1 / 29

Arp.c—— 源代码注释 小组成员: 李婷 1071000114 罗雪 1071000118 史雅萌 1071000119

Arp.c—— 源代码注释 小组成员: 李婷 1071000114 罗雪 1071000118 史雅萌 1071000119 古丽布斯 1071000301. ARP ARP ,即 地址解析协议 ,实现通过 IP 地址 得知其物理地址。. 地址解析协议 ARP 是在主机 ARP 高速缓存( ARP cache )中存放一个从 IP 地址到硬件地址的映射表,并且这个映射表还经常动态更新。. 基本原理:

zavad
Download Presentation

Arp.c—— 源代码注释 小组成员: 李婷 1071000114 罗雪 1071000118 史雅萌 1071000119

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Arp.c——源代码注释 小组成员: 李婷 1071000114 罗雪 1071000118 史雅萌 1071000119 古丽布斯 1071000301

  2. ARP ARP,即地址解析协议,实现通过IP地址得知其物理地址。

  3. 地址解析协议ARP是在主机ARP高速缓存(ARP cache)中存放一个从IP地址到硬件地址的映射表,并且这个映射表还经常动态更新。

  4. 基本原理: 当主机A要向本局域网上的某个主机C发送IP数据报时,就先在其ARP高速缓存中查看有无主机C的IP地址。 如有,就在ARP高速缓存中查出其对应的硬件地址,再把这个硬件地址写入MAC帧,然后通过局域网把该MAC帧发往此硬件地址。

  5. 如果在ARP缓存表中没有找到目标IP地址,可能是主机C才入网,也可能是主机A刚加电,其高速缓存还是空的。这种情况下,主机A就自动运行ARP,然后按以下步骤找出主机C的地址。

  6. 1.ARP进程在本局域网上广播发送ARP请求分组。 分组内容表明:我的IP地址是209.0.0.5,硬件地址是00-00-C0-15-AD-18请问IP地址为209.0.0.6的硬件地址是什么?”

  7. 2.在本局域网上的所有主机上运行的ARP进程都收到此ARP请求分组。2.在本局域网上的所有主机上运行的ARP进程都收到此ARP请求分组。

  8. 3.主机C在ARP请求分组中见到自己的IP地址,就向主机A发送ARP响应分组,并写入自己的硬件地址。其余的所有主机都不理睬这个ARP请求分组。3.主机C在ARP请求分组中见到自己的IP地址,就向主机A发送ARP响应分组,并写入自己的硬件地址。其余的所有主机都不理睬这个ARP请求分组。 响应分组表明:我的IP地址是209.0.0.6,我的硬件地址是08-00-2B-00-EE-0A。

  9. 4.主机A接受到主机C的ARP响应分组后,就在其ARP高速缓存中写入主机C的IP地址到物理地址的映射。4.主机A接受到主机C的ARP响应分组后,就在其ARP高速缓存中写入主机C的IP地址到物理地址的映射。

  10. 在完成以上步骤的同时A和C还同时都更新了自己的ARP缓存表,下次A再向主机C或者C向A发送信息时,直接从各自的ARP缓存表里查找就可以了。在完成以上步骤的同时A和C还同时都更新了自己的ARP缓存表,下次A再向主机C或者C向A发送信息时,直接从各自的ARP缓存表里查找就可以了。 大大增加了网络上的通信量。

  11. ARP缓存表采用了老化机制(即设置了生存时间),在一段时间内(一般15到20分钟)如果表中的某一行没有使用,就会被删除,这样可以大大减少ARP缓存表的长度,加快查询速度。ARP缓存表采用了老化机制(即设置了生存时间),在一段时间内(一般15到20分钟)如果表中的某一行没有使用,就会被删除,这样可以大大减少ARP缓存表的长度,加快查询速度。

  12. 设想有一种情况,主机A和C通信,A的ARP高速缓存里有C的硬件地址,但C的网络适配器突然坏了,C立即更换了一块,因此C的硬件地址就改变了,A在其ARP缓存中查找原先的硬件地址,因为C原先的硬件地址已经失效,所以无法找到C,但是如果过了定时器设定的时间,A的缓存表中已经删除了C的硬件地址,于是A重新广播发送ARP请求分组,又可以找到C.

  13. 使用ARP的四种典型情况 1.发送方是主机,要把IP数据报发送到本网络上的另一个主机。这时用ARP找到目的主机的物理地址。 2.发送方是主机,要把IP数据报发送到另一个网络上的一个主机。这时用ARP找到本网络上的一个路由器的物理地址。剩下的工作由这个路由器来完成。

  14. 3.发送方是路由器,要把IP数据报转发到本网络上的一个主机。这时用ARP找到目的主机的物理地址。3.发送方是路由器,要把IP数据报转发到本网络上的一个主机。这时用ARP找到目的主机的物理地址。 4.发送方是路由器,要把IP数据报转发到另一个网络上的一个主机。这时用ARP找到本网络上的一个路由器的物理地址。剩下的工作由这个路由器来完成。

  15. 1、Arp_table • arp_tbl是一个类型为struct neigh_table的全局变量,它是一个ARP的缓存表,也称为邻居表。协议栈通过ARP协议获取到的网络上邻居主机的IP地址与MAC地址的对应关系都会保存在这个表中,以备下次与邻居通讯时使用,同时,ARP模块自身也会提供一套相应的机制来更新和维护这个邻居表。 • 下面逐个分析arp_tbl中的 重要成员数据与函数:

  16. 1)entry_size,key_len,kmem_cachep • entry_size是一个入口的大小,也就是arp_tbl中一个邻居的大小,邻居用struct neighbour结构体表示,该结构体的最后一个成员是u8 primary_key[0],用于存放IP地址,作为这个邻居的哈希主键。 • entry_size的大小就是sizeof(struct neighbour) + 4,由于用IP地址作主键,所以key_len就是4。 • kmem_cachep是一个后备高速缓存,创建一个邻居需要的内存从这个后备高速缓存中去取。

  17. 2)hash_buckets,hash_mask,entries,hash • hash_buckets是一个哈希数组,里面存放了arp_tbl当前维护的所有的邻居,hash_mask是哈希数组大小的掩码,其初始值为1,所以hash_buckets的初始大小为2(0到hash_mask的空间范围)。entries是整个arp_tbl中邻居的数量,当entries大于hash_mask+1的时候,hash_buckets增长为原来的两部。成员hash是一个哈希函数指针,用于计算哈希值。

  18. 3)phash_buckets,PNEIGH_HASHMASK • 这是用于代理ARP的邻居哈希表,PNEIGH_HASHMASK固定为0xF,所以phash_buckets固定有16项,其它与hash_buckets相同。 4)id • id作为这个邻居表的一个名称,是一个字符串信息,内核协议栈的arp_tbl的id是arp_cache。

  19. 5)gc_interval,gc_thresh1/2/3 • gc_interval应该是常规的垃圾回收间隔时间,被缺省置为30秒,但目前在源代码中似乎没有看到它的应用。 • gc_thresh1的用途暂时还没有发现,它缺省被置为128。 • gc_thresh2是第二个阀值,如果表中的邻居数量超过这个阀值,并且在需要创建新的邻居时,发现已经超过5秒时间表没有被刷新过,则必须立即刷新arp_tbl表,进行强制垃圾回收,这个值缺省被置为512。 • gc_thresh3是arp_tbl中允许拥有的邻居数量的上限,一旦超过这个上限,并且表中没有可以清理掉的垃圾邻居,那么就无法创建新的邻居,这个值缺省被置为1024 。

  20. 2、arp_print——转储ARP数据包 • arp_print(struct arphdr *arp) • { • int len, idx; • unsigned char *ptr; • if (inet_debug != DBG_ARP) return; • printk("ARP: "); • if (arp == NULL) { • printk("(null)\n"); • return; • }

  21. 3、arp_send_q()——发送ARP数据包 • arp_send_q(void) //arp数据报的发送 • { • struct sk_buff *skb; • struct sk_buff *volatile work_q; //定义sk_buff结构体指针 • cli(); • work_q = arp_q; • skb_new_list_head(&work_q); //skbuff为双向循环链表,该函数是为了在链表头部加入新的skb • arp_q = NULL; • sti(); • while((skb=skb_dequeue(&work_q))!=NULL) • { // 检查所有以&work_q为对首的队列中的包,若未超过重传限制的就发送,否则销毁。//如果包未准备好,就把包放入&arp_q为队首的队列中去。下次arp_send_q调用时再处理。处理过程同上。

  22. 4、arp_timer • timer是邻居的定时器,用于解析ARP,其超时函数是neigh_timer_handler。 • 定时器处理函数neigh_timer_handler首先确定下次的超时时间(如果这次解析没有成功)为当前时间加上parms的成员retrans_time的值(缺省设置为1秒)。所以,ARP解析的发包超时时间是1秒,连续尝试3次。ARP解析是通过ops的成员函数solicit去做的,该成员函数指针指向的arp_solicit函数,arp_solicit会实际发送ARP请求包。

  23. 5、arp_response——arp回复 • 在[arp]中,网关设备把自己的mac地址填充在arp response中,发送给原请求者。当然收到arp response之后也会把这个arp信息缓存下来,这样一个arp的过程就完成了。 • 以arp response的形式发送广播,它通常只是为了把自己的arp信息通告/更新给局域网全体,这种response不需要别人请求,是自己主动发送的通告。

  24. 6、arp_lookup • arp_lookup函数从ARP缓存表中以目的IP地址(网关IP或者同一子网内的对端IP地址)为哈希主键,寻找相应的邻居,如果找到的邻居的成员dev等于当前的网络设备接口,且primary_key等于当前的目的IP地址,则即为需要的邻居,返回即可。如果找不到,则创建。

  25. 7、arp_destructor——删除缓存表中的arp映射项 • 每个neighbour结构通过都neigh_ops定义了一组操作函数集,neigh_ops结构都由其父亲neigh_table定义的构造函数填充(include/net/neighbour.h). • struct neigh_ops • { • int family; • void (*destructor)(struct neighbour *); • void (*solicit)(struct neighbour *, struct sk_buff*); • void (*error_report)(struct neighbour *, struct sk_buff*); • int (*output)(struct sk_buff*); • int (*connected_output)(struct sk_buff*); • int (*hh_output)(struct sk_buff*); • int (*queue_xmit)(struct sk_buff*); • };

  26. 8、 arp_destroy——删除无效的映射项 • void arp_destroy(unsigned long paddr) • { • arp_destructor(paddr,1); • } • /* • 删除可能是无效的条目 • */

  27. 9、arp_create • arp_lookup函数从ARP缓存表中找不到相应的邻居,如果找不到,则需要通过调用arp_create函数创建一个新的邻居。 • 邻居被直接置成NUD_STALE(过期)状态。如果未被 使用,则在60秒(parms->gc_staletime)后被定期回收的定时器处理函数回收掉。

  28. 10、arp_rvc —— 函数用于网络层收到一个arp请求时,测试请求包的内容 int arp_rcv(struct sk_buff *skb, /*接收到的包缓冲区指针*/ struct net_device *dev, /*接收到ARP包的网卡设备结构*/ struct packet_type *pt /*捕获的协议包类型, { struct arphdr *arp = skb->nh.arph; /*获取以太网帧中的数据部分   unsigned char *arp_ptr= (unsigned char *)(arp+1);  struct rtable *rt; /*路由结构指针*/ unsigned char *sha, *tha; /*源、目的硬件地址指针*/ u32 sip, tip; /*源、目的IP地址*/ u16 dev_type = dev->type; /*网络设备硬件类型*/ int addr_type; /**/ struct in_device *in_dev = in_dev_get(dev); /*IP层设备结构指针*/ struct neighbour *n; /*邻居结构指针*/ • 包的硬件长度应该和网络设备的硬件长度匹配硬件类型也需要匹配,设备应该是支持ARP的.同时如果pln!=4,则ARP查找并非来自IP协议。这些情况都将包丢弃.

More Related