ºìÁªLinuxÃÅ»§
Linux°ïÖú

LinuxÄÚºËARPµÄÉè¼ÆʵÏÖ¸ÅÊö ZT

·¢²¼Ê±¼ä:2006-07-25 18:36:02À´Ô´:ºìÁª×÷Õß:bear10214
LinuxÄÚºËARPµÄÉè¼ÆʵÏÖ¸ÅÊö ZT

×÷Õߣº ¹è¹ÈÅ©Ãñ

ARP (Address Resolution Protocol) ÊÇÓÃÀ´½«IPµØַת»¯³É»úÆ÷µÄÍø¿¨ÎïÀíµØÖ·£¨Ó²¼þµØÖ·£©¡£
µ±Ò»Ì¨»úÆ÷ÒªÏòÁíÍâһ̨ÎïÀíÉÏÏàÁ¬µÄ»úÆ÷·¢ËÍIP°üµÄʱºò£¬ËüÒªÏȼì²éÒ»ÏÂ×Ô¼ºµÄARP»º´æ£¬ÊÔͼÕÒµ½
¶Ô·½µÄÓ²¼þµØÖ·£¬Èç¹ûÕÒ²»µ½µÄ»°£¬½«Òª·¢Ë͵ÄIP°ü·ÅÈëµÈ´ý¶ÓÁÐÖУ¬½Ó×Å·¢³öÒ»¸öARPÇëÇ󡣵ȵ½ÊÕµ½
ARPÓ¦´ðµÄʱºò£¬¹¹ÔìºÃÔ­À´ÕýÔڵȴýµÄIP°üµÄethernetÍ·²¿£¨Ä¿µÄÓ²¼þµØÖ·£¬Ô´Ó²¼þµØÖ·£©£¬ÔÙ½«Õâ¸ö
IP°ü·¢ËͳöÈ¥¡£
LinuxµÄARPʵÏÖÏ൱¸´ÔÓ£¬²¿·ÖÔ­ÒòÊÇLinux²»Ö¹ÒªÖ§³Öethernet£¬»¹ÒªÖ§³ÖÆäËüÀàÐ͵ÄÍøÂ磬
ÁíÍâÒ»²¿·ÖÔ­ÒòÊÇARPµÄʵÏÖʵ¼ÊÉÏÊǺÍ·ÓÉ´¦Àí£¨routing£©Ïà¹Ø£¬ËùÒÔÀí½âÆðÀ´²»Ì«ÈÝÒס£

Ê×ÏÈÎÒÒª½²Ò»ÏÂARPº¯ÊýµÄµ÷Óùý³Ì£º
(1) µ±ÏµÍ³³õʼ»¯Ê±£¬µ÷ÓÃarp_initÀ´³õʼ»¯ARP»º´æ£¨arp_tbl£©£¬²¢ÇÒ×¢²áARPЭÒéµÄ½ÓÊÕ
º¯Êý¡£
(2) µ±Íø¿¨Çý¶¯³ÌÐòÊÕµ½Ò»¸öÍøÂç°ü£¨packet£©µÄʱºò£¬»á·ÖÅäÒ»¸ösk_buff(skb)£¬½«Êý¾Ý¿½±´½ø
Õâ¸ö»º³åÇø£¬È»ºóµ÷ÓÃnetif_rx°Ñskb·ÅÈëµÈ´ý¶ÓÁУ¨input_pkt_queue£©ÖУ¬²¢ÇÒ²úÉúÒ»¸ö
ÈíÖжϡ£µ±ÏµÍ³´¦ÀíÕâ¸öÈíÖжϵÄʱºò£¬»áµ÷ÓÃnet_rx_action£¬Ëü¸ù¾ÝÍøÂç°üµÄÀàÐÍ£¬
µ÷ÓÃÏàÓ¦µÄ½ÓÊÕº¯ÊýÀ´´¦Àí¡£Èç¹ûÊÇARP°ü£¬Ôòµ÷ÓÃarp_rcv¡£
(3) arp_rcvÅжÏÕâ¸öarpÇëÇóÊDz»ÊÇѯÎʱ¾»ú»òÕß±¾»ú´úÀíµÄÓ²¼þµØÖ·£¬Èç¹ûÊǵĻ°£¬µ÷ÓÃarp_send
·¢»ØarpÓ¦´ð¡£ÁíÍâarp_rcv»¹¾¡Á¿±£Áô¶Ô·½»úÆ÷µÄmac addres¡£
(4) arp_send·ÖÅäÒ»¸ösk_buff(skb)£¬ÌîºÃarp°üµÄÀàÐÍ£¬Ô´Ó²¼þµØÖ·£¬Ô´IPµØÖ·£¬Ä¿µÄÓ²¼þµØÖ·£¬
Ä¿µÄIPµØÖ·£¬È»ºóµ÷ÓÃdev_queue_xmitÕâ¸öarp°ü·¢ËͳöÈ¥¡£

Æä´Î£¬ÃèÊöÒ»ÏÂARPÖ÷ÒªµÄÊý¾Ý½á¹¹£º

(1) neigh_table
neigh_tableÊÇÒ»¸öÓÃÀ´ÃèÊöÎïÀíÉÏ»¥ÏàÁ¬½ÓµÄ»úÆ÷µÄÐÅÏ¢µÄ¹þÏ£±í£¬ARP»º´æarp_tbl ¾ÍÊÇ
ÕâÑùµÄÒ»¸öneigh_table¡£ÏµÍ³ÖÐËùÓеÄneigh_table¶¼Á¬ÔÚÒ»Æð¡£ÏÂÃæÊÇһЩÖ÷ÒªµÄÓò£º




+ struct neighbour *hash_buckets[NEIGH_HASHMASK+1];
hash_buckets´æ·Å×ÅËùÓÐÁÚ¾Ó£¨ÎïÀíÉÏÏàÁ¬µÄ»úÆ÷£©µÄÐÅÏ¢£¬¹²ÓÐ32¸öbucket£¬Ã¿Ò»¸öbucket
´æ·Å×ÅÒ»ÌõneighborÁ´±í¡£

+ struct pneigh_entry *phash_buckets[PNEIGH_HASHMASK+1];
phash_buckets´æ·Å×ÅËùÓÐproxy arpµÄentry£¬Ã¿Ò»¸öentryÓÉÍø¿¨É豸ºÍipµØÖ·×é³É£¬Ö¸Ã÷
ÓÉÄĸöÍø¿¨É豸´úÀíÄĸöipµÄmacµØÖ·¡£¹²ÓÐ16¸öbucket.

+ int family; ÍøÂçÀàÐÍ£¬ÎªAF_INET
int entry_size; ´óСΪsizeof(struct neighbour) + 4
int key_len; ¼üµÄ³¤¶È£¬Îª4

+ __u32 (*hash)(const void *pkey, const struct net_device *);
int (*constructor)(struct neighbour *);
int (*pconstructor)(struct pneigh_entry *);
Õ⼸¸ö·Ö±ðÊÇARPµÄ¹þÏ£º¯Êý£¬neighbourºÍpneigh_entryµÄ¹¹Ô캯Êý£¬

+ struct neigh_parms parms;
ARP»º´æµÄһЩ²ÎÊý£¬°üÀ¨ARP°ü´«Êäʱ¼ä£¬ÖØ·¢Ê±¼ä£¬¶ÓÁг¤¶ÈºÍ´úÀí¶ÓÁг¤¶ÈµÈµÈ¡£

+ int gc_interval;
int gc_thresh1;
int gc_thresh2;
int gc_thresh3;
unsigned long last_flush;
struct timer_list gc_timer;
ARP»º´æÓÐÒ»¸ö»ØÊÕ»úÖÆ£¨garbage collection£©£¬ÕâЩ²ÎÊýÓÃÀ´ÉèÖûØÊÕµÄƵÂÊ
ºÍ·§ÖµµÈµÈ¡£

+ struct sk_buff_head proxy_queue;
ÓÐʱproxy arp²¢²»ÂíÉÏ·¢»ØÓ¦´ð£¬ÄÇô¾Í½«arp°üÔÝʱ·ÅÔÚÕâ¸ö¶ÓÁÐÀï¡£

(2) neighbour
neighbour°üº¬ÁËÁÚ¾Ó£¨ÎïÀíÉÏ»¥ÏàÁ¬½ÓµÄ»úÆ÷£©µÄÐÅÏ¢£¬ÒÔÏÂÊÇËüÖ»ÒªµÄÓò£º

+ struct net_device *dev;
ÓëÁÚ¾ÓÏàÁ¬µÄÍøÂçÉ豸£¨Íø¿¨£©¡£

+ __u8 nud_state;
neighbourµÄ״̬£¬°üÀ¨NUD_INCOMPLETE£¨Î´Íê³É£©£¬NUD_REACHABLE£¨ÎÞ·¨·ÃÎÊ£©£¬
NUD_STALE£¨¹ýʱ£©ºÍNUD_FAILED£¨Ê§°Ü£©µÈµÈ¡£

+ unsigned char ha[(MAX_ADDR_LEN+sizeof(unsigned long)-1)&~(sizeof(unsigned long)-1)];
ÁÚ¾ÓµÄÓ²¼þµØÖ·¡£

+ struct hh_cache *hh;
ethernet°üµÄÍ·²¿»º´æ£¬ÓÃÀ´¼Ó¿ìÍùÁÚ¾Ó·¢Ë͵ÄËٶȡ£LinuxÌá¸ßЧÂʵÄŬÁ¦¿É¼ûÒ»°ß :-) ¡£

+ struct sk_buff_head arp_queue;
µÈ´ýÕâ¸öÁÚ¾ÓµÄÓ²¼þµØÖ·µÄIP°ü¶ÓÁС£

+ struct neigh_ops *ops;
¶Ôneighbour²Ù×÷µÄÒ»Ì׺¯ÊýÖ¸Õë¡£ÓеãÏñc++ÀàµÄ³ÉÔ±º¯Êý¡£

+ u8 primary_key[0];
¹þÏ£±íµÄÖ÷¼ü£¬Ò»°ãÊÇIPµØÖ·¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ