Linux Neighbor Protocol Learning notes seven ARP packet processing process __linux

Source: Internet
Author: User
Tags goto rfc htons

The preceding section analyzes the initialization process of the ARP protocol. This section is primarily an ARP packet processing process that, when ARP is initialized, adds the receive handler function of the ARP protocol to the hash list associated with the three-layer protocol packet processing function by calling Dev_add_pack Ptype_ In base (for a hash list related to the three-layer protocol packet handler function, refer to the documentation http://blog.csdn.net/lickylin/article/details/22900401). When the underlying ARP packet is received at the bottom, the ARP_RCV is invoked for subsequent processing.

Here we analyze the ARP_RCV and the functions associated with it.

ARP_RCV's definition is as follows, this function is mainly arp_process encapsulation, compared with arp_process is mainly to increase the ARP packet rationality check, and increase the firewall hook function. Arp_process is invoked for packets that meet the requirements.

Function: Docking the processing function of the received ARP packet

1, first of all ARP packet to conduct a reasonable check

2, call Nf_hook, to determine whether the need for further treatment of ARP, for the need

Further processing of the packet, the call arp_process for subsequent processing.

Static INTARP_RCV (struct Sk_buff *skb, struct net_device, *dev,

struct Packet_type *pt, struct net_device *orig_dev)

{

struct ARPHDR *arp;

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

if (!pskb_may_pull (SKB, Arp_hdr_len (Dev))

Goto FREESKB;

ARP = ARP_HDR (SKB);

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;

memset (NEIGH_CB (SKB), 0, sizeof (STRUCTNEIGHBOUR_CB));

Return Nf_hook (Nfproto_arp, nf_arp_in, Skb,dev, NULL, arp_process);

FREESKB:

KFREE_SKB (SKB);

Out_of_mem:

return 0;

}

Below we analyze arp_process

Function: Process an ARP Request

For Arp_process, the main considerations are as follows:

1, the ARP packet is the correct format, is a system-supported neighbor protocol

2, whether you need to discard the received ARP packets

3. Handle the ARP packets that meet the conditions.

Here are some of the conditions for handling ARP packets:

Criteria for discarding packets:

1, arp_process only processing request, reply ARP packet, discard other types of packets

A for packets of type request, the discarded destination address is either multicast or loopback ARP data.

For data packets that need to be processed, they can be divided into several areas:

1. Processing of reply packets for ARP requests sent by the machine

2. ARP Request packet

A the ARP Request packet with the destination address is a local address and the source address is not 0

b the ARP Request packet whose destination address is a local address and a duplicate address detection with a source address of 0

3. Reply packets for ARP requests not sent locally

Static intarp_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;

__be32 sip, Tip;

U16 Dev_type = dev->type;

int addr_type;

struct neighbour *n;

struct NET *net = dev_net (dev);

/* ARP_RCV below verifies the ARP header andverifies the device

* isarp ' able.

*/

if (In_dev = NULL)

Goto out;

/* Call ARP_HDR to get the start pointer of the ARP header in the SKB data.

ARP = ARP_HDR (SKB);

/* Determine if the type of the device matches the type of hardware in the packet * *

Switch (dev_type) {

Default

if (Arp->ar_pro!= htons (eth_p_ip) | |

Htons (Dev_type)!= arp->ar_hrd)

Goto out;

Break

Case Arphrd_ether:

Case ARPHRD_IEEE802_TR:

Case ARPHRD_FDDI:

Case arphrd_ieee802:

/*

*ethernet, Token ring and Fibre Channel (which are IEEE 802

*devices, according to RFC 2625) devices'll 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

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

*however, to being 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

Case ARPHRD_AX25:

if (Arp->ar_pro!= htons (ax25_p_ip) | |

ARP->AR_HRD!= htons (arphrd_ax25))

Goto out;

Break

Case Arphrd_netrom:

if (Arp->ar_pro!= htons (ax25_p_ip) | |

ARP->AR_HRD!= htons (arphrd_netrom))

Goto out;

Break

}

/* Understand only this message types * *

if (Arp->ar_op!= htons (arpop_reply) &&

Arp->ar_op!= htons (arpop_request))

Goto out;

/*

* Extractfields

*/

/*

Gets the source MAC address, source IP address, destination MAC address, destination IP address in the ARP packet

*/

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

Sha =arp_ptr;

Arp_ptr + + dev->addr_len;

memcpy (&sip, Arp_ptr, 4);

Arp_ptr + 4;

Arp_ptr + + dev->addr_len;

memcpy (&tip, Arp_ptr, 4);

/*

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

* Addresses. If It is one such, delete it.

*/

/* Discard Destination address is multicast or loopback ARP data (for multicast address and loopback address is not required ARP) * *

if (Ipv4_is_loopback (tip) | | Ipv4_is_multicast (TIP))

Goto out;

/*

* Special Case:we must set Frame Relay source q.922 Address

*/

if (Dev_type = = Arphrd_dlci)

SHA = dev->broadcast;

/*

* Process entry. The idea here Iswe want to send a reply if it is a

* Request for us or if it's a request for someone else that we hold

* Aproxy for. We want to add a entry Toour cache if it is a reply

* To Usor if it's a request for our address.

* (Theassumption for this?

* address, they are probably intending to talk to us, so it saves time

* If wecache their address. Their address isalso probably

* Ourcache, since ours is isn't in their cache.)

*

* Putting this another way, we are care about replies if they are to

* Us,in which case we add them to the cache. For requests, we care

* Aboutthose for us and those for our proxies. We reply to both,

* Andin the case of requests for us we add the requester to the ARP

* Cache.

*/

/* Special Case:ipv4 duplicate addressdetection packet (RFC2131) * *

/* for ARP requests with a source IP address of 0, this is commonly used for duplicate address detection.

At this point, if the ARP type is request and the destination IP address is a local address and can be answered by ARP,

The call Arp_send sends the ARP reply packet. */

/*

For packets with a source address of 0, why not find the routing table first when sending an ARP reply message?

When we set up the routing table, we will set up a total zero default route, so for the destination IP 0

Packet, whose route is always there. So you don't have to look up the routing table in the process to generate

Arpreply packets, and send them out.

*/

if (sip = = 0) {

if (Arp->ar_op = = htons (arpop_request) &&

Inet_addr_type (NET, tip) = = Rtn_local &&

!arp_ignore (In_dev, sip, Tip)

Arp_send (arpop_reply, Eth_p_arp, Sip,dev, Tip, Sha,

Dev->dev_addr, SHA);

Goto out;

}

/*

For a packet with an ARP type request, and a route to the destination address tip is found, the following code is executed

*/

if (Arp->ar_op = = htons (arpop_request) &&

Ip_route_input (SKB, Tip, sip, 0, dev) = = 0) {

/* Get tip corresponding Routing cache/

RT = Skb_rtable (SKB);

Addr_type = rt->rt_type;

/*1, if the IP address type of the route cache corresponds to local, call Neigh_event_ns to find the neighbor item that meets the criteria

A If a neighbor item is found that meets the criteria, call Arp_send to send the reply package to the ARP request package and return

b) Direct return.

2, if the route cache corresponding IP address type is not local, then the ARP proxy processing, completed

return directly

*/

if (Addr_type = = rtn_local) {

int dont_send = 0;

if (!dont_send)

Dont_send |=arp_ignore (In_dev,sip,tip);

if (!dont_send &&in_dev_arpfilter (In_dev))

Dont_send |=arp_filter (Sip,tip,dev);

if (!dont_send) {

n = Neigh_event_ns (&arp_tbl,sha, &sip, Dev);

if (n) {

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 (Addr_type = Rtn_unicast &&

(Arp_fwd_proxy (In_dev, Dev, rt) | |

Arp_fwd_pvlan (In_dev, Dev, rt, sip, tip) | |

Pneigh_lookup (&ARP_TBL, net, &tip, Dev, 0))

{

n = Neigh_event_ns (&arp_tbl,sha, &sip, Dev);

if (n)

Neigh_release (n);

if (NEIGH_CB (SKB)->flags &locally_enqueued | |

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;

}

}

}

* Update Our ARP tables * *

/*

1, for ARP reply packet, enter the following processing flow

2, for the ARP request packet, and did not find a tip IP corresponding to the routing cache

*/

/* Call __neigh_lookup to find the neighbour hash bucket of the arp_tbl, and find the corresponding neighbor for the SIP.

n = __neigh_lookup (&arp_tbl, &sip,dev, 0);

/* for ARP reply that the system allows non-ARP requests, do the following * *

if (Ipv4_devconf_all (dev_net (Dev), arp_accept)) {

/* Unsolicited ARP is not accepted bydefault.

It is possible, which this option should being enabled for some

Devices (The strip is candidate)

*/

/*1, for ARP reply that are not ARP requests, and without corresponding neighbour, forces the creation of a new neighbour

2, for SIP and tip equal ARP request, also forces the creation of new neighbour??

*/

if (n = = NULL &&

(Arp->ar_op = = htons (arpop_reply) | |

(Arp->ar_op = = htons (arpop_request) && tip = = sip)) &&

Inet_addr_type (NET, sip) = = rtn_unicast)

n = __neigh_lookup (&arp_tbl,&sip, Dev, 1);

}

/* If you find a qualifying neighbour, execute the following code

1. For the ARP reply message sent to this machine, the neighbor item is set to reach state

2. For the ARP request message sent to this machine, the neighbor item state is set to stale state

Last Call neigh_update, update neighbour status

*/

if (n) {

int state = nud_reachable;

int override;

/* If several different ARP repliesfollows 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.

*/

Override = Time_after (jiffies,n->updated + n->parms->locktime);

/* Broadcast replies and request packets

Do not assert neighbour reachability.

*/

if (Arp->ar_op!= htons (arpop_reply) | |

Skb->pkt_type!= Packet_host)

state = Nud_stale;

Neigh_update (N, Sha, state, override?) neigh_update_f_override:0);

Neigh_release (n);

}

Out

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.