深入理解iputils网络工具-第8篇 rdisk:路由表更新程序
2012-12-28 11:18
253 查看
8.1 引言
初始化路由表有很多种方法,其中使用ICMP路由器发现报文就是一种方法。rdisc程序正是使用ICMP路由器发现报文来完成路由表的初始化和更新。rdisc程序根据编译的不同可以程序可以编译成具有或没有服务器功能。如果设置了RDISC_SERVER宏,则会有服务器的功能,也就是会对ICMP报文路由器请求报文进行回复。否则,不会对ICMP报文路由器请求报文进行回复。
ICMP路由器发现报文格式可以参看RFC 1256。
8.2 rdisc程序的使用
ICMP路由发现报文目前使用的并不多,对rdisc的测试也并不方便。rdisc程序的选项的解释如下:
-a
将所有路由加入内核路由项,不管优先级是多大。
-b
与-a选项相反,在接受ICMP路由通告报文时,只将优先级最高的路由加入内核路由项,而删除那些低优先级的路由。
-d
设置为debug模式。
-f
即使没有发现任何路由也永远运行程序。一般情况下,如果程序在发送3个请求报文之后仍然没有接受到通告报文就退出运行,并返回非零值。
注意:-f参数能够覆盖-s参数的效果。
-p <preference>
在发送ICMP路由器通告报文是,需要在对应路由器地址字段后面设置4字节的优先级字段。这个字段就是本地接口地址的优先级。
在初始化的时候,会将所有存储的本机接口的优先级设置为<preference>。
-s
程序快速发送3个请求报文,以快速找出路由。如果此后没有接收到报文就退出运行,并返回非零值。
注意:-f参数能够覆盖-s参数的效果。
-t
测试模式。
设置这个选项使得程序不退居后台运行。
-T <interval>
将在网络接口发送ICMP路由器通告报文的最大的时间间隔设置为<interval>。单位是秒。
注意:RFC 1256协议里规定此时间间隔不得小于4秒,不得超过1800妙,默认值是MAX_ADV_INT(600)。
-v
冗余输出模式,也就是向log中输出很多debug信息。
-V
打印出版本信息,然后退出。
8.3 rdisc程序的流程图
这里画出的流程图是具有服务器功能的程序的流程图,如下所示:8.4 rdisc.c程序的全局变量的分析
static int num_interfaces;本地主机网络接口总数。
static struct interface *interfaces;
本地主机的所有接口数据。
在初始化的时候,需要通过ioctl()函数取得所有本机借口的信息,存储在interfaces数组中。
在进行ICMP路由通告时,需要对所有的接口对应地址进行广播、多播或者单播。
static int interfaces_size; /* Number of elements in interfaces */
interfaces数组的个数,也就是符合条件的网络接口的个数。
#define MAXPACKET 4096
ICMP报文的最大字节数。
在分配给ICMP报文存储空间的时候使用。
int debugfile;
?
程序中没有使用到这个变量。
char usage[];
存储了的程序的用法介绍。
int s;
ICMP报文的socket文件。
struct sockaddr_in whereto;
发送ICMP报文的目的地址信息。
如果本地主机支持多播则向224.0.0.2(all-routers IP multicast group)发送数据,否则向255.255.255.255发送ICMP路由报文。
目的地址还可以自行设置。
int verbose = 0;
标识是不是打印冗余信息。
如果设置为1,则会打印文件出很多信息。
可以通过-v设置。
int debug = 0;
标识是不是debug模式。
如果设置为1,则会打印文件打印很多debug信息。
可以通过-d设置。
int trace = 0;
标识是不是不在后台运行。
如果设置为1,则在程序运行之后,不会退到后台运行,也不会关闭标准输入输出,错误消息也打印在标准输出上,可以方便调试。
可以通过-t设置。
int solicit = 0;
可以通过-s设置。
int ntransmitted = 0;
发送的ICMP路由报文总数。
在发送一个ICMP路由报文之后加1,在退出程序的时候作为统计数据打印出来。
int nreceived = 0;
接收到的ICMO路由报文总数。
在接收一个ICMP路由报文之后加1,在退出程序的时候作为统计数据打印出来。
int forever = 0;
可以通过-f选项设置为1。
#ifdef RDISC_SERVER
由于编译选项的不同,程序可以编译成具有或没有服务器功能。如果设置了RDISC_SERVER宏,则会有服务器的功能,也就是会对ICMP报文路由器请求报文进行回复。
int responder;
标识是否对ICMP路由请求报文进行回复。
设置为0则不回复。
可以通过-r设置为1。
int max_adv_int = MAX_ADV_INT;
在网络接口发送ICMP路由器通告报文的最大的时间间隔。单位是秒。
RFC 1256协议里规定max_adv_int不得小于4秒,不得超过1800妙。默认值是MAX_ADV_INT(600)。
可以通过-T选项设置,设置后会相应改变min_adv_int、lifetime的值。
int min_adv_int;
在网络接口发送ICMP路由器通告报文的最小的时间间隔。单位是秒。
RFC 1256协议里规定min_adv_int不得小于3秒,不得超过max_adv_int。其默认值是0.75 * max_adv_int。
在实际中,在网络接口发送ICMP路由器通告报文的最大的时间间隔是一个随机数,但是保证了时间间隔不小于min_adv_int,不大于max_adv_int。计算式子如下:
min_adv_int+ ((max_adv_int - min_adv_int) *(random() % 1000)/1000);
int lifetime;
放置在ICMP路由器报告报文中的生存时间字段的值。单位是秒。
RFC 1256协议里规定不得小于max_adv_int,不得大于9000秒,默认值是3 *max_adv_int。
int initial_advert_interval =MAX_INITIAL_ADVERT_INTERVAL;
在网络接口刚刚开始传输ICMP路由器通告报文的时候,需要定期传输公告报文,间隔间隔为MAX_INITIAL_ADVERT_INTERVAL秒。
FC 1256协议里规定MAX_INITIAL_ADVERT_INTERVAL为16,传输次数MAX_INITIAL_ADVERTISEMENTS为3。
int initial_advertisements = MAX_INITIAL_ADVERTISEMENTS;
在网络接口刚刚开始传输ICMP路由器通告报文的时候,需要定期传输公告报文,间隔间隔为MAX_INITIAL_ADVERT_INTERVAL秒。
FC 1256协议里规定MAX_INITIAL_ADVERT_INTERVAL为16,传输次数MAX_INITIAL_ADVERTISEMENTS为3。
int preference = 0;
在发送ICMP路由器通告报文是,需要在对应路由器地址字段后面设置4字节的优先级字段。这个字段就是本地接口地址的优先级。
在初始化的时候,会将所有interfaces中存储的本机接口的优先级设置为preference。
可以通过-p选项设置。
#endif
int max_solicitations = MAX_SOLICITATIONS;
在程序接口初始的情况下,允许网络接口连续发送MAX_SOLICITATIONS个ICMP路由器请求报文,发送时间间隔为SOLICITATION_INTERVAL。
FC 1256协议里规定时间间隔SOLICITATION_INTERVAL为3秒, 传输次数MAX_SOLICITATIONS为3个。
unsigned int solicitation_interval =SOLICITATION_INTERVAL;
在程序接口初始的情况下,允许网络接口连续发送MAX_SOLICITATIONS个ICMP路由器请求报文,发送时间间隔为SOLICITATION_INTERVAL。
FC 1256协议里规定时间间隔SOLICITATION_INTERVAL为3秒, 传输次数MAX_SOLICITATIONS为3个。发送时间间隔没有随机性。
int best_preference = 1;
标识内核中使用的路由项是不是只使用优先级最高的路由。
如果设置为1,则在接受ICMP路由通告报文时,只将优先级最高的路由加入内核路由项,而删除那些低优先级的路由。
可以通过-a选项设置为0。
可以通过-b选项设置为1。
static int logging = 0;
标识是不是使用文件来记录log信息。
如果使用了-t选项,则程序不会退居后台运行,则logging维持0,仍然将输出打印在标准输出上。
如果没有使用-t选项,则程序退居后台运行,则logging变为1,将输出打印在in.rdiscd的文件里。
char *sendaddress;
发送ICMP报文的目的地址。
如果本地主机支持多播则向224.0.0.2(all-routers IP multicast group)发送数据,否则向255.255.255.255发送ICMP路由报文
目的地址还可以自行设置。
char *recvaddress;
接收ICMP报文的目的地址。
如果本地主机支持多播则向224.0.0.1(all-systems IP multicast group)发送数据,否则向255.255.255.255发送ICMP路由报文
目的地址还可以自行设置。
struct table {
structin_addr router;
int preference;
int remaining_time;
int in_kernel;
struct table *next;
} *table;
存储路由的列表项。
当接受到ICMP路由器通告报文时,将所有的路由器地址及其优先级存储在table列表中。并根据best_preference的设置,将table列表中部分路由项加入内核中使用。
8.5 ICMP路由发现报文格式
ICMP路由器请求报文格式如下所示:ICMP路由器通告报文格式如下所示:
8.6 ioctl系统调用
ioctl系统调用提供一个通用命令接口,程序可以用它来访问一个设备的标准系统调用所不支持的特性。rdisc.c使用了很多的ioctl系统调用函数,其中在iputils中使用过的ioctl选项的解释如下:
类别 | 请求 | 描述 |
套接口 | SIOCGIFNUM | 找到网络接口的个数 |
SIOCGSTAMP | 取得时间戳 | |
文件 | FIONBIO | 设置/清除非阻塞标志 |
套接口配置控制 | SIOCGIFCONF | 获取所有接口的列表 |
SIOCGIFFLAGS | 取得接口标识 | |
SIOCGIFINDEX | 由接口名字获得接口标号(index) | |
SIOCGIFDSTADDR | 获取点到点地址 | |
SIOCGIFNETMASK | 获取子网掩码 | |
SIOCGIFHWADDR | 取得网络设备的硬件地址 | |
SIOCGIFNAME | 获取接口的名字 | |
SIOCGIFBRDADDR | 获取广播地址 | |
ARP | SIOCSARP | 创建修改ARP项 |
路由表 | SIOCADDRT | 增加路径 |
SIOCDELRT | 删除路径 | |
终端I/O | TIOCGWINSZ | 取得窗口大小 |
套接口操作相关的ioctl参数可以参看/linux-2.6.27/include/linux/sockios.h。
相关文章推荐
- 深入理解iputils网络工具-第3篇 clockdiff:时间比对程序
- 深入理解iputils网络工具-第5篇 arping:地址解析程序
- 深入理解iputils网络工具-第5篇 arping:地址解析程序
- 深入理解iputils网络工具-第4篇 tracepath:路由追踪程序
- 深入理解iputils网络工具-第6篇 rarpd:逆地址解析程序
- 深入理解iputils网络工具-第2篇 ping:通路检测程序
- 深入理解iputils网络工具-第7篇 tftpd:简单文本传输
- 深入理解iputils网络工具-第1篇 简介
- 深入理解.NET程序的原理 谈一谈破解.NET软件的工具和方法
- 深入理解.NET程序的原理 谈一谈破解.NET软件的工具和方法
- 深入理解.NET程序的原理 谈一谈破解.NET软件的工具和方法
- 深入理解JVM—性能监控工具
- 深入理解Hadoop集群和网络
- 深入理解openstack网络架构(4)-----连接到public network
- 深入理解计算机系统——第05章——优化程序性能
- 深入理解Lustre文件系统-第10篇 LNET:Lustre网络
- [读书笔记]深入理解计算机系统 第6章 优化程序性能
- 程序中理解网络七层协议
- 深入理解程序从编译到运行
- 深入理解JVM虚拟机 性能监控与故障处理工具