Windows XP Windows 7 Windows 2003 Windows Vista Windows教程綜合 Linux 系統教程
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟件教程
 Windows教程網 >> Linux系統教程 >> Linux教程 >> linux協議棧之鄰居子系統(相關流程五)

linux協議棧之鄰居子系統(相關流程五)

日期:2017/2/7 14:39:41      編輯:Linux教程
 

int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)

{

struct arphdr *arp;



/* ARP header, plus 2 device addresses, plus 2 IP addresses. */

//判斷skb是否含有足夠的數據

if (!pskb_may_pull(skb, (sizeof(struct arphdr) +

(2 * dev->addr_len) +

(2 * sizeof(u32)))))

goto freeskb;



arp = skb->nh.arph;

if (arp->ar_hln != dev->addr_len ||

dev->flags & IFF_NOARP ||

skb->pkt_type == PACKET_OTHERHOST ||

skb->pkt_type == PACKET_LOOPBACK ||

arp->ar_pln != 4)

goto freeskb;



if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)

goto out_of_mem;

//netfiter處理後,轉至arp_process中處理

return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);



freeskb:

kfree_skb(skb);

out_of_mem:

return 0;

}

int arp_process(struct sk_buff *skb)

{

struct net_device *dev = skb->dev;

struct in_device *in_dev = in_dev_get(dev);

struct arphdr *arp;

unsigned char *arp_ptr;

struct rtable *rt;

unsigned char *sha, *tha;

u32 sip, tip;

u16 dev_type = dev->type;

int addr_type;

struct neighbour *n;



/* arp_rcv below verifies the ARP header and verifies the device

* is ARP'able.

*/



//接口上沒有IP

if (in_dev == NULL)

goto out;

//取得arp 頭部

arp = skb->nh.arph;



switch (dev_type) {

default:

//arp 不為IP類型,或者且不與接口相同

if (arp->ar_pro != htons(ETH_P_IP) ||

htons(dev_type) != arp->ar_hrd)

goto out;

break;

#ifdef CONFIG_NET_ETHERNET

case ARPHRD_ETHER:

#endif

#ifdef CONFIG_TR

case ARPHRD_IEEE802_TR:

#endif

#ifdef CONFIG_FDDI

case ARPHRD_FDDI:

#endif

#ifdef CONFIG_NET_FC

case ARPHRD_IEEE802:

#endif

#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_TR) || \

defined(CONFIG_FDDI) || defined(CONFIG_NET_FC)

/*

* ETHERNET, Token Ring and Fibre Channel (which are IEEE 802

* devices, according to RFC 2625) devices will accept ARP

* hardware types of either 1 (Ethernet) or 6 (IEEE 802.2).

* This is the case also of FDDI, where the RFC 1390 says that

* FDDI devices should accept ARP hardware of (1) Ethernet,

* however, to be more robust, we'll accept both 1 (Ethernet)

* or 6 (IEEE 802.2)

*/

if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&

arp->ar_hrd != htons(ARPHRD_IEEE802)) ||

arp->ar_pro != htons(ETH_P_IP))

goto out;

break;

#endif

#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)

case ARPHRD_AX25:

if (arp->ar_pro != htons(AX25_P_IP) ||

arp->ar_hrd != htons(ARPHRD_AX25))

goto out;

break;

#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)

case ARPHRD_NETROM:

if (arp->ar_pro != htons(AX25_P_IP) ||

arp->ar_hrd != htons(ARPHRD_NETROM))

goto out;

break;

#endif

#endif

}



/* Understand only these message types */

//不為請求或者應答



if (arp->ar_op != htons(ARPOP_REPLY) &&

arp->ar_op != htons(ARPOP_REQUEST))

goto out;



/*

* Extract fields

*/

arp_ptr= (unsigned char *)(arp+1);

//發送端以太網地址首地址

sha = arp_ptr;

arp_ptr += dev->addr_len;

//sip 發送端IP地址

memcpy(&sip, arp_ptr, 4);

arp_ptr += 4;

tha = arp_ptr;

arp_ptr += dev->addr_len;

//tip 目的IP地址

memcpy(&tip, arp_ptr, 4);

/*

* Check for bad requests for 127.x.x.x and requests for multicast

* addresses. If this is one such, delete it.

*/

//回環或者多播地址

if (LOOPBACK(tip) || MULTICAST(tip))

Copyright © Windows教程網 All Rights Reserved