ARP输入 之 arp_rcv

概述

arp_rcv是ARP包的入口函数,ARP模块在二层注册了类型为ETH_P_ARP的数据包回调函数arp_rcv,当收到ARP包时,二层进行分发,调用arp_rcv;

arp_rcv对ARP输入包的合法性进行检查,然后经过netfilter的ARP_IN钩子点,之后调用arp_process处理输出包;

源码分析
1 /*
2  *    Called once on startup.
3  */
4 
5 static struct packet_type arp_packet_type __read_mostly = {
6     .type =    cpu_to_be16(ETH_P_ARP),
7     .func =    arp_rcv,
8 };
 1 /*
 2  *    Receive an arp request from the device layer.
 3  */
 4 
 5 static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
 6            struct packet_type *pt, struct net_device *orig_dev)
 7 {
 8     const struct arphdr *arp;
 9 
10     /* do not tweak dropwatch on an ARP we will ignore */
11     /* 不支持ARP,非本机包,回环包,不处理 */
12     if (dev->flags & IFF_NOARP ||
13         skb->pkt_type == PACKET_OTHERHOST ||
14         skb->pkt_type == PACKET_LOOPBACK)
15         goto consumeskb;
16 
17     /* skb如果是共享的,则克隆一个 */
18     skb = skb_share_check(skb, GFP_ATOMIC);
19     if (!skb)
20         goto out_of_mem;
21 
22     /* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
23     /* 检查arp包完整性 */
24     if (!pskb_may_pull(skb, arp_hdr_len(dev)))
25         goto freeskb;
26 
27     /* 获取arp头 */
28     arp = arp_hdr(skb);
29 
30     /* 地址长度和协议长度检查 */
31     if (arp->ar_hln != dev->addr_len || arp->ar_pln != 4)
32         goto freeskb;
33 
34     /* 清空neighCB */
35     memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
36 
37     /* 经过NF的ARP_IN钩子点,然后调用arp_process */
38     return NF_HOOK(NFPROTO_ARP, NF_ARP_IN,
39                dev_net(dev), NULL, skb, dev, NULL,
40                arp_process);
41 
42 consumeskb:
43     consume_skb(skb);
44     return NET_RX_SUCCESS;
45 freeskb:
46     kfree_skb(skb);
47 out_of_mem:
48     return NET_RX_DROP;
49 }

猜你喜欢

转载自www.cnblogs.com/wanpengcoder/p/11755423.html
arp
今日推荐