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µØÖ·¡£
                  	
				
