转:http://blog.csdn.net/nerdx/article/details/12450055
-
-
-
-
-
-
1.1 void dev_add_pack(struct packet_type *pt)
-
{
-
int hash;
-
-
spin_lock_bh(&ptype_lock);
-
-
if (pt->type == htons(ETH_P_ALL)) {
-
netdev_nit++;
-
list_add_rcu(&pt->list, &ptype_all);
-
} else {
-
hash = ntohs(pt->type) & 15;
-
list_add_rcu(&pt->list, &ptype_base[hash]);
-
}
-
spin_unlock_bh(&ptype_lock);
-
}
-
-
-
-
-
1.2 static struct packet_type ip_packet_type = {
-
.type = __constant_htons(ETH_P_IP),
-
.func = ip_rcv,
-
};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1.3 int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
-
{
-
struct iphdr *iph;
-
-
-
-
if (skb->pkt_type == PACKET_OTHERHOST)
-
goto drop;
-
-
-
IP_INC_STATS_BH(IPSTATS_MIB_INRECEIVES);
-
-
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
-
IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
-
goto out;
-
}
-
-
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
-
goto inhdr_error;
-
-
iph = skb->nh.iph;
-
-
-
-
-
-
-
if (iph->ihl < 5 || iph->version != 4)
-
goto inhdr_error;
-
-
-
if (!pskb_may_pull(skb, iph->ihl*4))
-
goto inhdr_error;
-
-
-
if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
-
goto inhdr_error;
-
-
{
-
__u32 len = ntohs(iph->tot_len);
-
if (skb->len < len || len < (iph->ihl<<2))
-
goto inhdr_error;
-
-
-
-
-
if (skb->len > len) {
-
__pskb_trim(skb, len);
-
if (skb->ip_summed == CHECKSUM_HW)
-
skb->ip_summed = CHECKSUM_NONE;
-
}
-
}
-
-
return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
-
ip_rcv_finish);
-
-
-
inhdr_error:
-
IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
-
drop:
-
kfree_skb(skb);
-
out:
-
return NET_RX_DROP;
-
}
-
-
-
-
-
-
-
-
-
-
-
1.4 static inline int ip_rcv_finish(struct sk_buff *skb)
-
{
-
struct net_device *dev = skb->dev;
-
struct iphdr *iph = skb->nh.iph;
-
-
-
if (skb->dst == NULL) {
-
if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))
-
goto drop;
-
}
-
...
-
-
-
if (iph->ihl > 5) {
-
struct ip_options *opt;
-
-
if (skb_cow(skb, skb_headroom(skb))) {
-
IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
-
goto drop;
-
}
-
iph = skb->nh.iph;
-
-
if (ip_options_compile(NULL, skb))
-
goto inhdr_error;
-
-
opt = &(IPCB(skb)->opt);
-
if (opt->srr) {
-
struct in_device *in_dev = in_dev_get(dev);
-
if (in_dev) {
-
if (!IN_DEV_SOURCE_ROUTE(in_dev)) {
-
-
in_dev_put(in_dev);
-
goto drop;
-
}
-
in_dev_put(in_dev);
-
}
-
if (ip_options_rcv_srr(skb))
-
goto drop;
-
}
-
}
-
-
return dst_input(skb);
-
-
-
inhdr_error:
-
IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
-
drop:
-
kfree_skb(skb);
-
return NET_RX_DROP;
-
}
-
阅读(439) | 评论(0) | 转发(0) |