Processing function Analysis of Linux kernel arp (ARP_RCV, arp_send)

Source: Internet
Author: User
Tags goto reserved htons

Processing function Analysis of Linux kernel arp (ARP_RCV, arp_send)

int ARP_RCV (struct sk_buff *skb, struct net_device, *dev,
struct Packet_type *pt)
When the system's network driver receives an ARP packet, call this function to process. In simple terms, Arp_rev
Send back to the machine or its agent of the other machine's network card hardware address (MAC addresses), and the sender's network card hardware address in their own cache (ARP cache).
Implementation process:
* Check that the hardware address length (typically 6 bytes) and the protocol address length (4 bytes) are correct.
* Call Skb_linearize to initialize the SKB so that we can use SKB->NH.IPH to access the IP header.
if (In_dev = NULL | |
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 out;

if ((SKB = Skb_share_check (SKB, gfp_atomic)) = = NULL)
Goto Out_of_mem;

if (Skb_is_nonlinear (SKB)) {
if (Skb_linearize (SKB, gfp_atomic)!= 0)
Goto FREESKB;
ARP = skb->nh.arph;
arp_ptr= (unsigned char *) (ARP+1);
}
* Determine the type of hardware address (ETHERNET:1) and protocol address (ip:0x800).
* To determine the type of ARP packet, ARP request for 1,arp answer is 2.
if (arp->ar_hrd!= __constant_htons (arphrd_ether) &&
ARP->AR_HRD!= __constant_htons (arphrd_ieee802))
Goto out;
if (Arp->ar_pro!= __constant_htons (ETH_P_IP))
Goto out;
... ...
if (Arp->ar_op!= __constant_htons (arpop_reply) &&
Arp->ar_op!= __constant_htons (arpop_request))
Goto out;
* Obtain ARP package values, including source Ethernet address (SHA), Source IP address (SIP), Destination Ethernet address (THA), and destination IP address (tip).
* If the destination address is loopback or muticast address, throw the ARP packet away.
Sha=arp_ptr;
Arp_ptr + + dev->addr_len;
memcpy (&sip, Arp_ptr, 4);
Arp_ptr + 4;
Tha=arp_ptr;
Arp_ptr + + dev->addr_len;
memcpy (&tip, Arp_ptr, 4);

if (loopback (tip) | | Multicast (TIP))
Goto out;
* If the source address is 0, this ARP packet used to detect the IP address conflict, then the local IP address for the source address and destination address sent back an ARP reply.
/* Special CASE:IPV4 Duplicate address detection packet (RFC2131) * *
if (sip = = 0) {
if (Arp->ar_op = = __constant_htons (arpop_request) &&
Inet_addr_type (tip) = = rtn_local)
Arp_send (ARPOP_REPLY,ETH_P_ARP,TIP,DEV,TIP,SHA,DEV->DEV_ADDR,DEV->DEV_ADDR);
Goto out;
}
* If it is an ARP request, call Ip_route_input to find the route of the destination address (tip).
(a) If the tip is a native address, call Neigh_event_ns to update the ARP cache (ARP_TBL) and note the other
IP and hardware addresses. Then call Arp_send to send back the answer.
Since the other side sent me ARP request, very likely he will communicate with me, save his address will shorten the next processing time,
This is why the IP and hardware addresses of the sender are reserved.
(b) If the tip is a native IP that requires forward, a similar operation is performed, but if Proxy_delay is not equal to 0
, do not immediately send back the answer, but the ARP packet first placed in the ARP_TBL in the Proxy_queue, set a timed
Device to send later. Also, call Pneigh_lookup to determine whether the hardware address of the tip is in the resident cache, and to send back the answer at this time.
if (Arp->ar_op = = __constant_htons (arpop_request) &&
Ip_route_input (SKB, Tip, sip, 0, dev) = = 0) {

RT = (struct rtable*) skb->dst;
Addr_type = rt->rt_type;

if (Addr_type = = rtn_local) {
n = Neigh_event_ns (&arp_tbl, Sha, &sip, Dev);
if (n) {
int dont_send = 0;
if (In_dev_arpfilter (In_dev))
Dont_send |= Arp_filter (Sip,tip,dev);
if (!dont_send)
Arp_send (Arpop_reply,eth_p_arp,sip,dev,tip,sha,dev->dev_addr,sha);

Neigh_release (n);
}
Goto out;
else if (In_dev_forward (In_dev)) {
if ((Rt->rt_flags&rtcf_dnat) | |
(Addr_type = = Rtn_unicast && rt->u.dst.dev!= Dev &&
(In_dev_proxy_arp (in_dev) | | | pneigh_lookup (&ARP_TBL, &tip, DEV, 0))) {
n = Neigh_event_ns (&arp_tbl, Sha, &sip, Dev);
if (n)
Neigh_release (n);

if (skb->stamp.tv_sec = 0 | |
Skb->pkt_type = = Packet_host | |
In_dev->arp_parms->proxy_delay = = 0) {
Arp_send (Arpop_reply,eth_p_arp,sip,dev,tip,sha,dev->dev_addr,sha);
} else {
Pneigh_enqueue (&arp_tbl, in_dev->arp_parms, SKB);
In_dev_put (In_dev);
return 0;
}
Goto out;
}
}
}
* After processing the ARP request, ARP_RCV whether the request or answer is received, according to the SIP call __neigh_lookup to check
Find Arp_tbl, can't find it, insert a new entry, deposit the IP and hardware address of each other, and finally call Neigh_update to update the status of this entry.
n = __neigh_lookup (&arp_tbl, &sip, Dev, 0);
if (n) {
int state = nud_reachable;
int override = 0;
/* If Several different ARP replies follows back-to-back,
Use the one. It is possible, if several proxy
Agents are active. Taking the reply prevents
ARP trashing and chooses the fastest router.
*/
if (jiffies-n->updated >= n->parms->locktime)
Override = 1;
/* Broadcast replies and request packets
Do not assert neighbour reachability.
*/
if (Arp->ar_op!= __constant_htons (arpop_reply) | |
Skb->pkt_type!= Packet_host)
state = Nud_stale;
Neigh_update (N, Sha, state, override, 1);
Neigh_release (n);
}
void arp_send (int type, int ptype, u32 dest_ip,
struct Net_device *dev, u32 src_ip,
unsigned char *dest_hw, unsigned char *SRC_HW,
unsigned char *target_hw)
When the system's network drivers receive an ARP packet, use this function to handle it. In simple words, arp_rev
The network card hardware address of the machine or other machine that it is acting on is returned (MAC address), and the URL of the sending person's card is placed in its cache.
The process is now:
(1) Allocate a sk_buff, use to construct the ARP package, in addition to the necessary space, also reserved 15 words for use.
Use the Skb_reserve to empty the front 15 words and the network packet head.
SKB = alloc_skb (sizeof (struct ARPHDR) + 2* (dev->addr_len+4)
+ Dev->hard_header_len + gfp_atomic);
if (SKB = NULL)
Return
Skb_reserve (SKB, (dev->hard_header_len+15) &~15);
Skb->nh.raw = skb->data;
ARP = (struct ARPHDR *) skb_put (skb,sizeof (struct ARPHDR) + 2* (dev->addr_len+4));
Skb->dev = Dev;
Skb->protocol = __constant_htons (Eth_p_arp);
+ If the source hardware address is empty, it is designed as the hardware address;
If the destination hardware address is empty, it is designed as a multicast address.
if (SRC_HW = NULL)
SRC_HW = dev->dev_addr;
if (DEST_HW = NULL)
DEST_HW = dev->broadcast;
+ Adjust the MAC head structure function of the network card, and fill in the Ethernet destination hardware address and source hardware address of this ARP packet.
Ethernet's default structure is Eth_header, please see the Ether_setup function in net_init.c.
if (Dev->hard_header &&
Dev->hard_header (skb,dev,ptype,dest_hw,src_hw,skb->len) ar_hrd = htons (Dev->type);
Arp->ar_pro = __constant_htons (ETH_P_IP);
+ Write hardware address length (generally 6 words) and protocol address length (4 words);
To fill in the ARP package type, ARP please 1,arp should be 2.
ARP->AR_HLN = dev->addr_len;
ARP->AR_PLN = 4;
Arp->ar_op = htons (type);
Write the data for the ARP packet, including the source Ethernet address (SHA), Source IP address (SIP), Destination Ethernet address (THA), and destination IP address (tip).
arp_ptr= (unsigned char *) (ARP+1);
memcpy (Arp_ptr, SRC_HW, Dev->addr_len);
arp_ptr+=dev->addr_len;
memcpy (Arp_ptr, &src_ip,4);
arp_ptr+=4;
if (TARGET_HW!= NULL)
memcpy (Arp_ptr, TARGET_HW, Dev->addr_len);
Else
memset (arp_ptr, 0, Dev->addr_len);
arp_ptr+=dev->addr_len;
memcpy (Arp_ptr, &DEST_IP, 4);
+ Finally, adjust the dev_queue_xmit to place this ARP packet on the sending team and prepare to send it.
Dev_queue_xmit (SKB);

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.