在本文中讨论的所有接口和地址结构的一个例子配置如下图所示:
上图中显示了我们三个接口例子:以太网接口,SLIP接口和环回接口。它们都有一个链路层地址作为地址列表中的第一个结点。
显示的以太网接口有两个IP地址,SLIP接口有一个IP地址,并且环回接口有一个IP地址和一个OSI地址。
所有的IP地址都被链接到in_ifaddr列表中,并且所有链路层地址能从ifnet_addrs数组访问。
后面的部分讨论上图的数据结构以及用来查看和修改这些结构的IP专用ioctl命令。
之前讨论了通用的sockaddr和ifaddr结构。现在我们说明IP专用的结构:sockaddr_in和in_ifaddr。在Internet域中的地址存放在
一个sockaddr_in结构:
由于历史原因,Net/3以网络字节序将Internet地址存储在一个in_addr结构中,这个结构只有一个成员s_addr,它包含这个地址。
下图显示了Internet协议定义的接口地址结构。
对于每个指派给一个接口的IP地址,分配一个in_ifaddr结构,并且添加到接口地址列表中和IP地址全局列表中。
下图为以太网、PPP和环回in_ifaddr结构。
当接口结构在系统初始化期间被识别时的初始化。在Internet协议能通过这个接口进行通信前,必须指派一个IP地址。一个Net/3
内核运行,程序ifconfg就配置这些接口,ifconfig通过在某个插口上的ioctl系统调用来发送配置命令。通常都是通过系统引导时
调用shell脚本执行的。
下图是本文涉及到的ioctl命令。命令相关的地址必须是此命令插口所支持的地址族类,对于IP地址,ioctl命令在一个UDP插口上
发送。
本文中说明的ioctl的函数。
SIOCG命令用于获取地址信息。SIOCS用于设置地址信息。SIOC代表socket ioctl。
上图中的命令修改一个接口的相关地址信息。由于地址时特定协议使用的,因此,命令处理是与协议相关的。
ifioctl协议将协议相关的ioctl命令传递给此插口关联的pr_usrreq函数。将控制权交给udp_usrreq,并且又立即传给in_control,
在in_control中进行大部分处理。
我们按照下面的顺序查看这个接口ioctl命令,以及这些命令在in_control中处理。
1.指派一个地址、网络掩码或目标地址
2.指派一个广播地址
3.取回一个地址,网络地址,目标地址或广播地址
4.给一个接口指派多播地址
5.删除一个地址
对于所有这命令,在in_control函数中有两个switch语句,第一个switch语句进行前提处理,然后在第二个switch语句中处理
命令。
对于这三个命令in_control函数中第一个switch做相同的处理:
1.仅用于超级用户
2.分配并初始化in_ifaddr结构
对于点对点接口,在链路另一端的系统的地址使用该命令指定。
代码设置新地址后,使用函数if_ioctl通知硬件。如果地址原来有一个关联的路由,首先调用rtinit删除这路由,并再次调用rtinit
为新地址安装一个路由。
获取接口信息的过程比较简单,将in_ifaddr对应的信息复制到ioctl参数ifreq中。
SIOCG和SIOCS命令只操作一个接口关联的第一个IP地址,为支持每个接口多个IP地址,必须使用SIOCAIFADDR命令指派和
配置其他的地址。实际上SIOCAIFADDR能完成SIOCG和SIOCS命令能完成的操作。程序ifconfig使用SIOCAIFADDR来配置一
个接口的所有地址信息。
命令SIOCDIFADDR从一个接口删除IP地址,从当前接口中查找与请求IP相同的地址结构,并且删除任何与此地址关联的路由。