《TCP/IP详解卷二:实现》笔记-接口层

《TCP/IP详解卷2:实现》笔记--接口层

接口层包括在本地网上发送和接收分组的硬件与软件。

我们用设备驱动程序来表示与硬件及网络接口通信的软件,网络接口是指在一个特定网络上硬件与设备驱动器之间的接口。

Net/3接口层试图在网络协议和连接到一个系统的网络设备的驱动器间提供一个与硬件无关的编程接口。这个接口层为所有的

设备提供以下支持。

1.一套精心定义的接口函数。

2.一套标准的统计与控制标志。

3.一个与设备无关的存储协议地址的方法。

4.一个标准的输出分组的排队方法。

这个不要求接口层提供可靠地分组传输,仅需要提供最大努力的服务。更高协议层必须弥补这种可靠性缺陷。


ifnet结构

结构ifnet结构中包含所有接口的通用信息,在系统初始化期间,分配为每个网络设备分配一个独立的ifnet结构,每个ifnet结构

有一个列表,它包含这个设备一个或多个协议地址。下图说明了一个接口和它地址之前的关系。

《TCP/IP详解卷二:实现》笔记-接口层

上图的接口显示了3个存放在ifaddr结构中的协议地址。虽然一些网络接口,例如slip,仅支持一个协议,而其他接口,如

以太网,支持多个协议并需要多个地址。例如,一个系统可能使用一个以太网接口同时同于Internet和OSI两个协议。一个

类型字段标识每个以太网帧的内容,并且因为Internet和OSI协议使用不同的编址方式,以太网接口必须有一个Internet地址

和一个OSI地址。

下图是包含在结构ifnet中的实现信息。

《TCP/IP详解卷二:实现》笔记-接口层


ifnet结构中的下一部分显示在下图,它用来描述接口的硬件特征。

《TCP/IP详解卷二:实现》笔记-接口层


接口统计信息由下图中下一组ifnet接口成员来收集。它们被加入来支持接口的标准SNMP MIB-II变量

《TCP/IP详解卷二:实现》笔记-接口层


结构ifnet的下一部分,显示在下图,它包含指向标准接口层函数的指针,他们把设备专用的细节从网络层分离出来。每个接口

实现这些适用于特定设备的函数。

《TCP/IP详解卷二:实现》笔记-接口层

以后会分析以太网、环回接口的设备专用函数,内核通过ifnet接口中的这些指针直接调用它们,例如,ifp指向一个ifnet结构。

(*if->if_start)(ifp)

调用这个接口的设备驱动程序的if_start函数。


结构ifnet的最后一个成员是接口的输出队列。

《TCP/IP详解卷二:实现》笔记-接口层

队列作为一个mbuf链的链表来实现。


ifaddr结构

每个接口维护一个ifaddr结构的链表,因为一些数据链路,如以太网,支持多于一个的协议。一个单独的ifaddr结构描述每个

分配给接口的地址,通常每个协议一个地址。支持多地址的另一个原因是很多协议,包括TCP/IP,支持为每个物理接口指派

多个地址。

《TCP/IP详解卷二:实现》笔记-接口层

ifnet和ifaddr的关系如下:

《TCP/IP详解卷二:实现》笔记-接口层


sockaddr结构

一个接口的编址信息不仅仅包含一个主机地址,在通用的sockeaddr结构中维护主机地址、广播地址和网络掩码。通过使用

一个通用的结构,将硬件与协议专用的地址细节相对于接口层隐藏起来。下图说明了这些结构的组织。

《TCP/IP详解卷二:实现》笔记-接口层

sa_len指示地址的长度,sa_family指示地址的类型,sa_data,包含一个协议相关格式的地址。


ifnet和ifaddr的专用化

结构ifnet和ifaddr包含适用于所有网络接口和协议地址的通用信息,为了容纳其他设备和协议专用信息,每个设备定义了并且

每个协议分配了一个专用化版本的ifnet和ifaddr结构。这些专用化的结构总是包含一个ifnet或ifaddr结构作为它们的第一个成员,

这样无需考虑其他专用信息就能访问这些公共信息。

下图是专用化ifnet结构的组织。

《TCP/IP详解卷二:实现》笔记-接口层

每个设备的结构以一个ifnet开始,接下来诠释设备相关的数据。环回接口只声明了一个ifnet,因为它不要求任何设备相关的

数据。

每个协议把每个接口的地址信息存储在一个专用化的ifaddr结构列表中。以太网协议使用一个in_ifaddr结构,而OSI协议使用

一个iso_ifaddr结构,另外,当接口被初始化时,内核为每个接口分配一个链路层地址,它在内核中标识这个接口。下图是一个

包含链路层地址、internet地址和OSI地址的接口地址列表。

《TCP/IP详解卷二:实现》笔记-接口层


网络初始化概述

所有我们说明的结构在内核初始化时分配和互相链接起来的。有些设备,例如slip和环回接口,完全用软件来实现。这些伪设

备用存储在全局pdevinit数组中的一个pdevinit结构来表示,在内核配置期间构造了这个数组。

《TCP/IP详解卷二:实现》笔记-接口层


if_attach函数

对接口的ifnet结构赋值后,都需要调用if_attach函数来完成接口ifnet结构的初始化。并把这个结构插入到先前配置的接口列表
中。在if_attach中,内核也为每个接口初始化并分配一个链路层地址。下图说明了由if_attach构造的数据结构。
《TCP/IP详解卷二:实现》笔记-接口层
在上图中,if_attach被调用了三次,每次调用时,它向ifnet列表中添加一个新的ifnet结构。为这个接口创建一个链路层ifaddr
结构,并且初始化ifnet_addrs数组中的一项。