荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jjk (UNIX+C+XML+?? 傻了?), 信区: Linux
标  题: ARP的设计实现概述(转寄)
发信站: 荔园晨风BBS站 (Mon Apr 22 19:48:22 2002), 转信

【 以下文字转载自 jjk 的信箱 】
【 原文由 jjk.bbs@apue.dhs.org 所发表 】
发信人: tl (tl), 信区: UKP
标  题: ARP的设计实现概述
发信站: UNIX编程 (2002年04月16日20:56:41 星期二), 转信

作者:硅谷农民<mailto:ggnm@kerneldiary.net>

  ARP (Address Resolution Protocol) 是用来将IP地址转化成机器的网卡物理地址(
硬件地址)。
当一台机器要向另外一台物理上相连的机器发送IP包的时候,它要先检查一下自己的AR
P缓存,试图找到
对方的硬件地址,如果找不到的话,将要发送的IP包放入等待队列中,接着发出一个AR
P请求。等到收到
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请求是不是询问本机或者本机代理的硬件地址,如果是的
话,调用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个buc
ket,每一个bucket
           存放着一条neighbor链表。
        +  struct pneigh_entry     *phash_buckets[PNEIGH_HASHMASK+1];
           phash_buckets存放着所有proxy arp的entry,每一个entry由网卡设备和i
p地址组成,指明
           由哪个网卡设备代理哪个ip的mac地址。共有16个bucket.
        +  int                     family;      网络类型,为AF_INET
           int                     entry_size;  大小为sizeof(struct neighbou
r) + 4
           int                     key_len;     键的长度,为4
        +  __u32                   (*hash)(const void *pkey, const struct ne
t_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地址。
--------------------------------------------------
硅谷农民,日出而作,一分耕耘,一分收获。

--

    欲慰韶华携吴钩,剑雪刀霜遣风流。
    一蓑烟雨平生事,道无狂嚣亦无愁!

※ 来源:·UNIX编程 apue.dhs.org·[FROM: 166.111.160.6] --
※ 转寄:·UNIX编程 apue.dhs.org·[FROM: 210.39.3.50]
--
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.146]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店