Linux内核版本
4.16.8
相关文件
include/uapi/linux/Ip.h
1. IP选项类型字节及其组成
IP选项位于IP头部的最后,可以有0到多个。有些IP选项是定长的,而有些是变长的,但所有IP选项的第一个字节都是选项类型。下图所示是IP选项在IP头部中的位置。
RFC 791. Figure 4. IP头部
类型字节的组成是这样的:最高位为复制标识(copied flag),接下来2位是选项类别(option class),最后的5位是选项编号(option number)。
图1 IP选项类型字节
1.1 复制标识(copiedflag)
如图1所示,复制标识0为不复制,即选项只需在第一个分片中保留一份即可,无需复制到所有分片中,而1则为复制,即选项需复制到所有分片中。常用的IP选项中,安全、商业IP安全选项、宽松路由、严格路由、路由器警告以及流标识符会设置该标识为1,而选项列表结束符、空操作、时间戳和记录路由为0。
Linux为该标识位定义了一个常量IPOPT_COPY:
43#define IPOPT_COPY0x80
在后面常用IP选项类型常量定义中会看到,用按位或操作来设置该标识。
1.2 选项类别(optionclass) 选项类别共2位,因此可以定义4种不同的类别,00为控制,01和11是预留,10是调试&测量,比如时间戳选项的类别就是10。为此Linux定义了4个常量:
51 #defineIPOPT_CONTROL0x00
52 #defineIPOPT_RESERVED10x20
53 #defineIPOPT_MEASUREMENT0x40
54 #defineIPOPT_RESERVED20x60
以IPOPT_MEASUREMENT为例,0x40即0100 0000,取第6、5位为10。常用的IP选项中除了时间戳为10外,其他的所有选项都为00。
为获取选项类别,Linux定义了一个常量IPOPT_CLASS_MASK,和一个宏IPOPT_CLASS:
44 #define IPOPT_CLASS_MASK0x60
……
48 #defineIPOPT_CLASS(o)((o)&IPOPT_CLASS_MASK)
IPOPT_CLASS_MASK定义为0x60,即0110 0000,宏IPOPT_CLASS(o)是用参数o和0110 0000做按位与操作,结果就是保留o的第6、5位,其他都为0。
1.3 选项编号(optionnumber)
因为处于类型字段的第4到最低位,对于选项编号Linux倒是没定义相关的常量,在定义选择类型常量时直接用数字,参见2.Linux中定义的IP选项类型常量中各个类型常量的定义。
2. Linux中定义的IP选项类型常量
定义了以上这些常量之后,就可以通过按位或操作,将复制标识值、选项类别值和选项编号值连接起来,定义具体IP选项的类型值。
2.1 IPOPT_END:选项列表结束符(End of Option List)
选项列表结束符,用于标识整个选项列表,即所有选项的结束。该选项只有一个选项类型字节:
RFC 791.选项列表结束符
再看Linux中定义的常量IPOPT_END
56#define IPOPT_END(0 |IPOPT_CONTROL)
0 |IPOPT_CONTROL即0000 0000 | 0000 0000,结果为0000 0000
图2 IPOPT_END
2.2 IPOPT_NOOP:空操作(NoOperation)
空操作,一般是在选项之间或选项末尾用作32位对齐填充的,同样也只有一个选项类型字节:
RFC 791.空操作
57#define IPOPT_NOOP(1 |IPOPT_CONTROL)1 |IPOPT_CONTROL即0000 0001 | 0000 0000,结果为0000 0001
图3 IPOPT_NOOP
2.3 IPOPT_SEC:安全(Security)
安全选项的长度为11个字节,除了第1个类型字节外,还有1字节的长度、2字节的安全级别(下图中的S部分),2字节的发送信息间隔(下图中的C部分),2字节的处理限制(下图中的H部分)和3字节的传输控制码(下图中的TCC)。在本文中我们只说类型字节,其他的留待后续展开说。
RFC 791.安全
58#define IPOPT_SEC(2 |IPOPT_CONTROL|IPOPT_COPY)
2 |IPOPT_CONTROL|IPOPT_COPY即0000 0010 | 0000 0000| 1000 0000,结果为1000 0010
图4 IPOPT_SEC
2.4 IPOPT_LSRR:宽松路由(LooseSource Routing)
在宽松路由的路由数据部分(下图的route data部分)会列出几个必经的路由器IP地址,这些路由器地址并不能构成一条完整的路径,而在这些路由器之间可以选择其他的路由器。因此与2.9小节的严格路由相对应地称为宽松路由,可参考该小节来理解。
宽松路由选项的长度是可变的,取决于路由数据部分包含几个IP地址,而指针字节在数据报传递过程中,始终指向下一个路由器地址。在此我们还是集中在类型字节。
RFC 791.宽松路由
59#define IPOPT_LSRR(3 |IPOPT_CONTROL|IPOPT_COPY)3 |IPOPT_CONTROL|IPOPT_COPY即0000 0011 | 0000 0000| 1000 0000,结果为1000 0011
图5 IPOPT_LSRR
2.5
IPOPT_TIMESTAMP:时间戳(InternetTimestamp)
时间戳选项,是为了记录IP数据报经过路由器时的时间。这也是个可变长选项,1字节的选项类型,1字节的选项长度,1字节的指针,指向下一个可存放时间戳的位置,4位的溢出字段(下图中的oflw),记录未能记录的时间戳个数,4位的标志字段(下图中的flg),用以指定时间戳的格式,接下来就是时间戳列表,一个个时间戳,或者是一对对路由器IP地址+时间戳,这取决于flg。
RFC 791.时间戳
60#define IPOPT_TIMESTAMP(4 |IPOPT_MEASUREMENT)
4|IPOPT_MEASUREMENT即0000 0100 | 0100 0000,结果为0100 0100
图6 IPOPT_TIMESTAMP
2.6 IPOPT_CIPSO:商业IP安全选项(CommercialIP Security Option)
为了满足现在越来越多的商业企业、组织对各种安全策略的需要,IETF(The Internet TaskForce,国际互联网工程任务组) 在草案draft-ietf-cipso-ipsecurity-01中定义了商业IP安全选项,以支持更多的安全策略,而之前在2.3小节中讲述的安全选项(Security)只支持16个安全级别。
该选项包含了1字节的选项类型,1字节的选项长度,4字节的解释域(DOI)标识符(下图中的D部分),这是一个32位整数,用以唯一标识一种安全策略,标签(下图中的T部分)是相关的安全信息,长度可变。
draft-ietf-cipso-ipsecurity-01.Figure 1. 商业IP安全选项
61#define IPOPT_CIPSO(6 |IPOPT_CONTROL|IPOPT_COPY)
6 |IPOPT_CONTROL|IPOPT_COPY即0000 0110 | 0000 0000| 1000 0000,结果为1000 0110
图7I POPT_CIPSO
2.7
IPOPT_RR:记录路由(RecordRoute)
记录路由,顾名思义就是记录IP数据报在传递过程中经过的路由器的IP地址。1字节的选项类型,1字节的选项长度,1字节的指针,指向下一个可以存放IP地址的位置,接着就是用以存放路由器IP地址列表的部分,长度由发送方指定并初始化为全0。
RFC 791.记录路由
62#define IPOPT_RR(7 |IPOPT_CONTROL)
7 |IPOPT_CONTROL即0000 0111 | 0000 0000,结果为0000 0111
图8 IPOPT_RR
2.8 IPOPT_SID:流标识符(StreamID)
所谓流标识符,指的是SATNET流标识符,在该选项中1字节的选项类型和1字节的选项长度之后,是一个2字节的SATNET流标识符。
RFC 791.流标识符
63#define IPOPT_SID(8 |IPOPT_CONTROL|IPOPT_COPY)
图9 IPOPT_SID
2.9 IPOPT_SSRR:严格路由(StrictSource Routing)
严格路由各部分的说明可参考宽松路由,而严格是指必须按选项中列出的IP列表依次从一个IP地址到下一个IP地址传递IP数据报。
RFC 791.严格路由
64#define IPOPT_SSRR(9 |IPOPT_CONTROL|IPOPT_COPY)9 |IPOPT_CONTROL|IPOPT_COPY即0000 1001 | 0000 0000| 1000 0000,结果为1000 10001
图10 IPOPT_SSRR
2.10 IPOPT_RA:路由器警告(RouterAlert option)
路由器警告选项是为了提示IP数据报经过的路由器需仔细检查该数据报的内容。1字节的选项类型和1字节的选项长度之后的2个字节设置为1,即为路由器需要检查数据报,其他的预留。
RFC 2113.路由器警告
65#define IPOPT_RA(20|IPOPT_CONTROL|IPOPT_COPY)
20|IPOPT_CONTROL|IPOPT_COPY即0001 0100 | 0000 0000| 1000 0000,结果为1001 0100
图11 IPOPT_RA
参考资料
[1]RFC 791 - Internet Protocol
[2]RFC 2113 - IP Router Alert Option
[3]draft-ietf-cipso-ipsecurity-01
[4]Linux内核源码剖析——TCP/IP实现樊东东,莫澜著 2011-01-01机械工业出版社