接收IP分块单元要比发送它们要麻烦一些,因为这些IP单元可能以任何顺序到达,必须所有的单元都接收 到了以后才能重新将它们组装起来 。每接收一个IP包都要检查其是否是IP分割单元 。在第一个IP分割单元到达 时,IP会建立一个新的 ipq 结构,这一结构与用于IP单元重组的 ipqueue 列表相连 。当接收到更多的IP单元时,先找到正确的 ipq 结构,并为每个单元新建立一个 ipfrag 结构 。每个 ipq 结构唯一地描述一个接收IP分割单元的,包括它的源和目的IP地址,上层协议标识和本IP帧的标识 。当接收到所有的IP分割单元后,将它们重新组成一个 sk_buff,然后交给上层协议处理 。每个 ipq 中包含一个定时器,它在每接收到一个合法的单元后重新时 。如果定时器到时,ipq 结构和它的一些 ipfrag 结构将被丢弃,传送的信息则被假定为丢失 。然后提交给层协议来重传该信息 。
10.6地址解析协议 (ARP)
地址解析协议担当了一个把IP地址翻译成物理硬件地址如以太网地址的角色 。IP在将数据(以 sk_buff 的形式)通过设备驱动传送时需要这一转换 。
它执行各种检查,来看是否这一设备需要硬件头,是否需要重建包的硬件头 。Linux缓存了硬件头,这样可以避频繁重建 。如果需要重建硬件头,则调用设备指定的硬件头重建例程 。所有的以太网设备使用相同的头重例程,这些例程将目的IP地址转换成物理地址 。
ARP协议本身是很简单的,它包括两个消息类型,ARP请求与ARP应答 。ARP请求包含了需要解析的IP地址,ARP应答(希望它)包含被解析的IP地址,硬件地址 。ARP请求向连接在网络上的所有主机广播,因此,对于以网,所有连在网上的机器都能看到ARP请求 。拥有ARP请求中的IP地址的机器将发出包含了它自己的物理地址ARP应答 。
ARP协议在Linux中是围绕 arp_table 结构表来建立的,每个结构描述一个IP到物理地址的转换 。这些表项 在需要进行IP地址解析时生成,在随时间变旧时被删除 。每个 arp_table 结构有如下字段:
last used本ARP项最近一次使用的时间
last updated本ARP项最近一次更新的时间
flags描述本项的状态,如是否完成等
IP address本项描述的IP地址
hardware address要解析的硬件地址
hardware header指向缓存硬件头的指针
timer是个 timer_list 项,用于ARP请求没有响应时的超时
retriesARP请求重试的次数
sk_buff queue等待IP地址解析的sk_buff项列表
ARP表包括了指向 arp_table 链的指针( arp_table 向量) 。缓存这些表项可以加速对它们的访问,每个表项用IP地址的最后两个字节来生成索引,然后就可以查找表链以找到正确的表项 。Linux也以 hh_cache 结构的形式来缓存 arp_table 项的预建的硬件头 。
请求一个IP地址解析并且没有相应的 arp_table 项时,ARP必须发送一个ARP请求 。它在表和sk_buff队列中 生成一个新的 arp_table 项,sk_buff 包含了需要进行地址解析的网络包 。发送ARP请求时运行ARP定时器 。如果没有响应,ARP将重试几次,如果仍然没有响应,ARP将删除该 arp_table 项 。同时会通知队列中等待IP地址解析的 sk_buff 结构,传送它们的上层协议将处理这一失败 。UDP不关心丢包,而TCP则会建立TCP连接进行重传 。如果IP地址的所有者返回了它的硬件地址,则 arp_table 项被标记为完成,队列中的sk_buff将被删除,传输动作继续 。硬件地址被写到每个sk_buff的硬件头中 。
ARP协议层必须响应ARP请求 。它注册它的协议类型(ETH_P_ARP),生成一个 packet_type 结构 。这表示它将检查网络设备收到的所有ARP包 。与ARP应答一样,这包括ARP请求 。用保存在接收设备的 device 结构中的硬件地址来生成ARP应答 。
推荐阅读
- Linux 核心--10.文件系统
- 诺基亚将在更多产品上采用Linux操作系统
- 蛤蟆皮的功效与作用 蛤蟆皮的功效
- Linux 核心--7.PCI设备
- Linux 核心--8.中断与中断处理
- 椰子汤的功效与作用 椰子汤有什么功效
- Linux操作系统如何限制SSH密码尝试次数
- 微软公司对Linux操作系统使出的各种杀招
- Linux 核心--4.内存管理
- 以Linux做路由器的问题