IP首部中有4bit用于表示首部长度,其单位是4个字节,所以,IP首部的最大长度是15*4=60字节,而IP固定首部的长度是20字节,所以一个IP首部最大允许有40字节长度的选项。
IP选项的一般格式是1个字节的代码(code),一个字节的长度(len),一个字节的指针(ptr),指针的值从1开始计数,指向IP选项的内容,一
般其值为4(跳过前面3字节的code, len, ptr),长度包括前面3字节在内的整个IP选项,最大值为40。
代码表示不同类型的IP选项,其可能的取值有: IPOPT_END,值为0,表示IP首部的选项到此结束。该选项就一个code,总长度为1。 IPOPT_NOOP,值为1,表示无操作。用作占位符,因为IP选项的总长度需要为4的整数倍。 IPOPT_SEC,值为0x82,意义暂不明,从代码来看,并未对其作任何实际操作。 IPOPT_SID,值为0x88,意义暂不明,从代码来看,未对其作任何实际操作。 IPOPT_LSRR,值为0x83,表示宽松的源站路由选项,该选项ptr指向的位置开始是一组表示IP地址的32位无符号数,指明本机上该 socket发送的数据报必须经过这一组IP地址中的每一个,但是任意两个地址之间还可以通过其他路由器(这就是宽松的含义)。 IPOPT_SSRR,值为0x89,表示严格的源站路由选项,即IP地址列表指明数据报必须采用的精确路由。 IPOPT_TIMESTAMP,值为0x44,表示IP时间戳选项,该选项除了前三个字节为code,len,ptr,第四字节前4bit表示溢出字段 (OF),后4bit表示标志字段(FL),FL有三个可能的取值IPOPT_TS_TSONLY(0),表示只记录时间 戳;IPOPT_TS_TSANDADDR(1),表示每个路由器都记录它的IP地址和时间戳,这样,在列表中就只能存放4对地址和时间 戳;IPOPT_TS_PRESPEC(2),表示发送端对选项列表进行初始化,存放了4个IP地址和4个取值为0的时间戳值。只有当列表中的下一个IP 地址与当前路由器地址相匹配时,才记录它的时间戳。由于IP选项的长度有限,当路由器由于没有空间而不能增加时间戳选项时,它将增加溢出字段(OF)的 值。 IPOPT_RR,值为0x07,表示IP记录路由选项,其格式跟IPOPT_LSRR相同,每一个路由器都把自己的出口IP地址记录到该选项的IP清单中,以达到记录路由的目的。ping程序的-R选项支持记录路由的功能。 IPOPT_RA,值为0x94,具体用途暂不明,跟路由和转发相关。 Linux内核用结构体struct ip_options表示IP选项,其定义如下: struct ip_options { __u32 faddr; unsigned char optlen; unsigned char srr; unsigned char rr; unsigned char ts; unsigned char is_setbyuser:1, is_data:1, is_strictroute:1, srr_is_hit:1, is_changed:1, rr_needaddr:1, ts_needtime:1, ts_needaddr:1; unsigned char router_alert; unsigned char __pad1; unsigned char __pad2; unsigned char __data[0]; }; faddr用于在IPOPT_LSRR和IPOPT_SSRR选项时,记录下一站的IP地址,optlen是IP首部中选项所占据的长度,srr记录 IPOPT_LSRR或IPOPT_SSRR选项在IP首部中的偏移量(选项的第一个字节的地址减去IP首部的第一个字节的地址),rr用于记录 IPOPT_RR选项在IP首部中的偏移量,ts用于记录IPOPT_TIMESTAMP选项在IP首部中的偏移量。 接下来是一些标志位,is_setbyuser表示该IP选项是应用层通过setsockopt设置的,is_data表示该IP选项拥 有 数据,选项数据存放在__data中。is_strictroute表示该选项是IPOPT_SSRR,而不是IPOPT_LSRR。 srr_is_hit跟源站路由选项相关,对IP选项作过任何的修改,需要把is_changed置1,rr_needaddr表示有IPOPT_RR选 项,需要记录IP地址,ts_needtime表示IPOPT_TIMESTAMP选项需要记录时间戳,ts_needaddr表示 IPOPT_TIMESTAMP选项需要记录IP地址。router_alert用于IPOPT_RA选项。 |
|