您的位置:首页 > 理论基础 > 计算机网络

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

2014-05-12 20:24 134 查看
接口层包括在本地网上发送和接收分组的硬件与软件。

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

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

设备提供以下支持。

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

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

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

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

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

ifnet结构

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

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



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

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

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

和一个OSI地址。

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



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



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



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

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



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

(*if->if_start)(ifp)

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

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



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

ifaddr结构

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

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

多个地址。



ifnet和ifaddr的关系如下:



sockaddr结构

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

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



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

ifnet和ifaddr的专用化

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

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

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

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



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

数据。

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

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

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



内核通过分配一个iifaddr结构和两个sockaddr_dl结构(一个是链路层地址本身,一个是地址掩码)来构造一个链路层地址。

结构sockaddr_dl可被OSI、ARP和路由算法访问。

下图是一个初始化后的以太网sockaddr_dl.



第一个sockaddr_dl初始化各中值。第二个是一个比特掩码,用来选择出现在第一个结构中的文本内容,上图为le0.

网络初始化概述

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

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



下面概要地说明下以太网的初始化过程:

作为cpu_startup的一部分,内核查找任何连接的网络设备。这个过程的细节超出了本书的范围,一旦一个设备被识别,一个

设备专用的初始化函数就被调用(LANCE以太网设备为leattach函数),下面的操作被执行:

1.创建le_softc结构





2.从设备复制硬件地址到结构中。

3.初始化ifnet结构,设置ifnet的如下成员:if_unit,if_name,if_mtu,if_init,if_reset,if_ioctl,if_output,if_start,if_flags。

if_attach函数

对接口进行初始化后,都需要调用if_attach函数来完成接口ifnet结构的初始化。并把这个结构插入到先前配置的接口列表

中。在if_attach中,内核也为每个接口初始化并分配一个链路层地址。下图说明了由if_attach构造的数据结构。



在上图中,if_attach被调用了三次,每次调用时,它向ifnet列表中添加一个新的ifnet结构。为这个接口创建一个链路层ifaddr
结构,并且初始化ifnet_addrs数组中的一项。
if_attach更新两个全局变量,第一个是if_index,它存放系统中最后一个接口的索引。第二个是ifnet_addrs,它指向一个
ifaddr指针的数组。这个数组的每项都指向一个接口的链路层地址。这个数组提供对系统中每个接口的链路层地址的快速
访问。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: