【源码】arp设计实现

至少在2.6的里面,arp是归于邻居系统的,跟路由相关。在1.2.13 好像是独立的<只看过这两个版本的kernel>

一.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请求是不是询问本机或者本机代理的硬件地址,如果是的话,调用arp_send发回arp应答。另外arp_rcv还尽量保留对方机器的mac addres。
(4) arp_send分配一个sk_buff(skb),填好arp包的类型,源硬件地址,源IP地址,目的硬件地址,目的IP地址,然后调用dev_queue_xmit这个arp包发送出去。

 

二.ARP结构体

http://www.oschina.net/code/explore/linux-2.6.36/include/net/neighbour.h  line142

/**neigh_table是一个用来描述物理上互相连接的机器的信息的哈希表,ARP缓存arp_tbl 就是这样的一个neigh_table。*/

struct neigh_table {
    struct neigh_table    *next;/**Used to link into a list of neighbour tables*/
    int            family;
    int            entry_size;/**Size of the struct neighbour + 4*/
    int            key_len;/**Length of key used by hash function.长度为4*/
    __u32            (*hash)(const void *pkey, const struct net_device *);
    int            (*constructor)(struct neighbour *);/**Initalizes new instances of struct neighbour*/
    int            (*pconstructor)(struct pneigh_entry *);
    void            (*pdestructor)(struct pneigh_entry *);
    void            (*proxy_redo)(struct sk_buff *skb);
    char            *id;
    struct neigh_parms    parms;
    /** HACK. gc_* should follow parms without a gap! */
    int            gc_interval;
    int            gc_thresh1;
    int            gc_thresh2;
    int            gc_thresh3;
    unsigned long        last_flush;
    struct delayed_work    gc_work;
    struct timer_list     proxy_timer;
    struct sk_buff_head    proxy_queue;
    atomic_t        entries;
    rwlock_t        lock;
    unsigned long        last_rand;
    struct kmem_cache        *kmem_cachep;
    struct neigh_statistics    __percpu *stats;
    struct neighbour    **hash_buckets;/**存放着所有物理邻居的信息,共32个,每一个bucket存放着一条neighbor链表*/
    unsigned int        hash_mask;
    __u32            hash_rnd;

/**存放着所有proxy arp的entry,每一个entry由网卡设备和ip地址组成,指明由哪个网卡设备代理哪个ip的mac地址*/
    struct pneigh_entry    **phash_buckets;/*共16个*/
};

 

三.ARP初始化

http://www.oschina.net/code/explore/linux-2.6.36/net/ipv4/arp.c    line1287

void __init arp_init(void)
{
    neigh_table_init(&arp_tbl);/**net/core/neighbour.c*/
    dev_add_pack(&arp_packet_type);/**register the ARP packet type with the link layer*/
    arp_proc_init();
#ifdef CONFIG_SYSCTL
    neigh_sysctl_register(NULL, &arp_tbl.parms, "ipv4", NULL);
#endif
    register_netdevice_notifier(&arp_netdev_notifier);
}

 

四.传输和接收ARP封包

 

 

PS:很大程度上自己对这一部分也不是很熟悉,以前零星看过,现在只是整理,如果有问题轻拍,欢迎交流

 

网上临时找到的【周末花整段时间整理下,目前只整理自己原有的】:

http://www.cnitblog.com/flutist1225/articles/19996.html

你可能感兴趣的:(【源码】arp设计实现)