频道栏目
首页 > 网络 > 网络协议 > 正文

关于IP选项的知识总结

2017-09-12 10:35:57         来源:SnailCpp的博客  
收藏   我要投稿

一、带IP选项的数据包的产生

首先要说明的是,并非任何IP包都带有IP选项的,事实上,正好相反,正常的IP包都不带IP选项

也就是说,正常IP包的包头长度标志位(第0x000E字节)的值都是0x45,其中高位“4”表示该IP包的版本号为4(IP v4),低位“5”表示包头长5个32位组(即20字节)。下图是一个正常的IP包:

这20个字节的IP包头通常称为“IP包固定头”,任何一个IP包都有符合这个格式的20字节包头

带有IP选项的IP包的包头除了20字节的固定头之外,还带有若干不定长度的选项字节,所以包头长一定大于5个32位组,也就是:包头长是否大于5是IP包是否带有IP选项的一个标志。

下图是一个带有路由记录选项的IP包:

图上可以看到:包头长度标志位(第0x000E字节)的值为0x4F,低位“F”表示包头长0x0F个32位组,即15x4=60字节,60字节是IP包头的最大长度了!

由于并非任何IP包都带有IP选项,按照steven的办法,我们采用带有参数的Ping命令来产生带有IP选项的IP包(谁还有其它的办法?别忘了告诉我一下!)

由于Ping命令是利用了ICMP来检查网路的连通情况,并且默认是连续检查四次,因此,发出一个Ping命令可以用《科来》捕捉到四个请求包。同时,如果能连通的话,宿端也会回发四个应答包(不能连通?那当然没有应答包了!连通不好也会丢失应答包的!)

有关Ping命令的参数介绍如下(可以放心在Windows命令方式下使用的!):

Ping -r 9 网址 //参数-r表示产生路由记录选项包,9表示最多记录9个路由IP,网址是宿端的IP地址

Ping -s 4 网址 //参数-s表示产生时间戳选项包,4表示最多记录4个路由IP及时间戳,网址是宿端的IP地址

Ping -j 网址组 //参数-j表示产生松散源路由选项包,网址组是到达宿端的所经过的路由器IP地址,要按顺序经过,但允许其中经过其它路由器

Ping -k 网址组 //参数-k表示产生严格源路由记录选项包,网址组是到达宿端的所经过的路由器IP地址,要按顺序经过,且不允许其中经过其它路由器

二、选项码

选项码位于数据包的第0x0022字节,值为0x07表示路由记录选项,值为0x44表示时间戳选项,值为0x83表示松散源路由选项,值为0x89表示严格源路由选项

[特别声明]本文版权归作者个人所有,对本文全部或部分进行转载、摘要等,请取得本人书面认可。QQ:8534669

三、带有路由记录选项的IP包分析

1、请求包

请求包是源端发出的,所以它的源IP地址(位于数据包的第0x001A、0x001B、0x001C、0x001D四个字节)应该就是本机的IP地址。IP记录表的长度是Ping -r Count命令设定的,9表示IP记录表的长度为9个32位组(即36个字节),最多可记录9个路由IP。IP记录表长度加上一个选项码字节(第0x0022字节)、一个选项长度字节(第0x0023字节)、一个选项指针字节(第0x0024字节),所以选项长度字节的值应为39(即0x27)。由于发出请求包的时候,尚未经过任何路由器,所以IP记录表的值应该全部为0,而选项指针(位于数据包的第0x0024字节)的值应为0x04,表示遇到第一个路由器时,路由器IP地址应存入选项的第0x04个字节(数据包的第0x0024字节)开始的四个字节中。

下图是发出带有路由记录选项的IP包Ping -r命令:

下图是对这个Ping -r命令捕捉到的请求包(利用《科来》的“按协议浏览”-“Ethernet II”-“IP”-“ICMP”-“Echo Req”来查看):

以上记录中,IP数据包的:

第0x000E字节第3位到第0位值为0x0F,表示这个IP数据包的包头长为60字节,超过了IP数据包固定包头的20字节长度,说明这个IP数据包带有IP选项;

第0x001A字节到第0x001D字节值为0xC0A801D4是源IP地址,与本机的IP地址192.168.1.212比较,可知这是本机发出的请求包;

第0x0022字节称为选项码,值为0x07(0 00 00111),说明这个IP数据包带有记录路由选项,其中第7位为复制标志位,值为0表示该IP包需要分片时只需将该选项复制到第一个分片中,第6位到第5位为选项类,值为00表示该IP选项是数据包和网络控制选项,第4位到第0位为选项号,值为00111表示该IP选项是路由记录选项;

第0x0023字节为长度,值为0x27,说明这个记录路由选项需要记录的路由器(IP地址)个数为9个,这个值是由包的源端设定的;

第0x0024字节为指针,值为0x04,说明这个记录路由选项尚未记录路由器IP地址;

记录路由选项中已经记录的IP地址均为0.0.0.0,进一步印证了这个IP数据包是请求包,理由是发出请求包的时候,尚未经过任何路由器;

2、应答包

应答包是宿端接收到请求包之后,由宿端转发回源端的。这在一般教科书中都没讲清楚,因为steven本身就没讲清楚,抄书的人当然也就讲不清楚了,呵呵。由于宿端必须接收到请求包才会回发应答包,所以我们只能在Ping通宿端之后才可能捕捉到应答包。与请求包相比,应答包的包头总长(第0x000E字节低4位)、选项码(第0x0022字节)和选项长度(第0x0023字节)应该不变,而宿IP地址(位于数据包的第0x001E、0x001F、0x0020、0x0021四个字节)是本机的IP地址,且选项指针(第0x0024字节)应大于0x04。

下图是对上面的Ping -r命令接收到的应答包(利用《科来》的“按协议浏览”-“Ethernet II”-“IP”-“ICMP”-“Echo Reply”来查看):

以上记录中,IP数据包的:

第0x000E字节第3位到第0位值为0x0F,表示这个IP数据包的包头长为60字节,超过了IP数据包固定包头的20字节长度,说明这个IP数据包带有IP选项;

第0x001E字节到第0x0021字节值为0xC0A801D4是宿IP地址,与本机的IP地址192.168.1.212比较,可知这是本机收到的应答包;

第0x0022字节称为选项码,值为0x07(0 00 00111),说明这个IP数据包带有记录路由选项,其中第7位为复制标志位,值为0表示该IP包需要分片时只需将该选项复制到第一个分片中,第6位到第5位为选项类,值为00表示该IP选项是数据包和网络控制选项,第4位到第0位为选项号,值为00111表示该IP选项是路由记录选项;

第0x0023字节为长度,值为0x27,说明这个记录路由选项需要记录的路由器(IP地址)个数为9个,这个值是由包的宿端设定的;

第0x0024字节为指针,值为0x28,说明这个记录路由选项已经记录了9个路由器(IP地址),其中第一个IP地址为0xDA13C10B,第二个IP地址为0x3B2980FD,最后一个(第9个)IP地址为0x3D900641;

需要说明的一点是,为了使应答包的IP记录表不再象请求包那样全为0,必须Ping外网IP地址而不能Ping内网IP地址(如192.168.x.x),因为Ping内网地址发出的请求包在内网未经过任何路由器就到达宿端了,当然IP记录表依然会全为0。

四、带有时间戳选项的IP包分析

1、请求包

与路由记录选项相似,时间戳选项请求包也是预定一个IP记录表,发送出去之后,每经过一个路由器就记录一个IP地址,直到宿端后被转发回源端,这样源端就可以了解数据包传输的路径。与路由记录选项不同的是,时间戳选项不但可以记录经过的路由器IP地址,还可以记录经过路由器的时刻。通过分析经过各路由器的时间间隔,就可以了解数据包传输路径中,哪段路径比较拥挤、哪段路径比较畅顺、应以多大的包进行传输比较合适。这样就为源端构造最优化的数据包提供了可能。为了提高灵活性,时间戳选项还提供了一个4位的标志字段(位于数据包第0x0025字节低4位),可以让带有时间戳选项的IP包经过路由器时①仅记录路过时刻而不记录路由器的IP地址,这种情形下标志字段值为0x00,或者②既记录路过时刻又记录路由器的IP地址,这种情形下标志字段值为0x01,甚至可以③预先构建一个将要路经的路由器IP地址表,每经过表中指定的路由器就记录路过时刻,这种情形下标志字段值为0x03,且溢出字段和指针字段失效。

Ping -s命令是产生带有时间戳选项的IP包的途径,但它只能产生第②种情形即既记录路过时刻又记录路由器的IP地址的IP包

下图是发出带有路由记录选项的IP包Ping -s命令:

下图是对这个Ping -s命令捕捉到的请求包(利用《科来》的“按协议浏览”-“Ethernet II”-“IP”-“ICMP”-“Echo Req”来查看):

以上记录中,IP数据包的:

第0x000E字节第3位到第0位值为0x0E,表示这个IP数据包的包头长为56字节,超过了IP数据包固定包头的20字节长度,说明这个IP数据包带有IP选项;

第0x001A字节到第0x001D字节值为0xC0A801D4是源IP地址,与本机的IP地址192.168.1.212比较,可知这是本机发出的请求包;

第0x0022字节称为选项码,值为0x44(0 10 00100),说明这个IP数据包带有时间戳选项,其中第7位为复制标志位,值为0表示该IP包需要分片时只需将该选项复制到第一个分片中,第6位到第5位为选项类,值为10表示该IP选项是调试和测量选项,第4位到第0位为选项号,值为00100表示该IP选项是时间戳选项;

第0x0025字节第3位到第0位为标志,值为0x01,表示该IP选项既记录路过时刻又记录路由器;

第0x0025字节第7位到第4位为溢出,值为0x00,表示该IP选项未发生因IP记录表已满而不能记录的路由器IP;

第0x0023字节为长度,值为0x24,说明这个时间戳选项需要记录的路由器(IP地址)个数为4个,这个值是由发出请求包的源端设定的;

第0x0024字节为指针,值为0x05,说明这个记录路由选项尚未记录任何路由器IP地址和时间戳;

记录路由选项中已经记录的IP地址均为0.0.0.0、时间戳均为0,进一步印证了这个IP数据包是请求包,理由是请求包发出时IP记录表全置为0;

2、应答包

与路由记录应答包一样,时间戳选项应答包也必须在Ping得通宿端之后才会由宿端转发回来。由于请求包经过每个路由器都要作记录,因而时间戳选项的溢出字段(位于数据包第0x0025字节高4位)、指针字段(位于数据包第0x0024字节)和IP记录表(位于数据包第0x0026字节之后)都应有所变化。特别要指出的是溢出字段,它用于计算因IP记录表已满而无法记录的路由器IP个数,因为受到IP包头最大只能60字节的限制,时间戳选项的IP记录表最多只能记录4个路由器IP,所以一旦传输路径上要经过的路由器个数大于4个,那只能用溢出字段来计数了,这也是Ping -s命令的参数最大不可超过4的原因。

下图是对上面的Ping -s命令接收到的应答包(利用《科来》的“按协议浏览”-“Ethernet II”-“IP”-“ICMP”-“Echo Reply”来查看):

以上记录中,IP数据包的:

第0x000E字节第3位到第0位值为0x0E,表示这个IP数据包的包头长为56字节,超过了IP数据包固定包头的20字节长度,说明这个IP数据包带有IP选项;

第0x001E字节到第0x0021字节值为0xC0A801D4是宿IP地址,与本机的IP地址192.168.1.212比较,可知这是本机收到的应答包;

第0x0022字节称为选项码,值为0x44(0 10 00100),说明这个IP数据包带有时间戳选项,其中第7位为复制标志位,值为0表示该IP包需要分片时只需将该选项复制到第一个分片中,第6位到第5位为选项类,值为10表示该IP选项是调试和测量选项,第4位到第0位为选项号,值为00100表示该IP选项是时间戳选项;

第0x0025字节第3位到第0位为标志,值为0x01,表示该IP选项既记录路过时刻又记录路由器;

第0x0025字节第7位到第4位为溢出,值为0x07,表示该IP选项传输路径上经过的路由器中有7个因IP记录表已满而未作记录;

第0x0023字节为长度,值为0x24,说明这个时间戳选项需要记录的路由器(IP地址)个数为4个,这个值是由发出应答包的宿端设定的;

第0x0024字节为指针,值为0x25,说明这个记录路由选项已经记录了4个路由器IP地址和时间戳),其中第一个IP地址为0x00000000,经过这个IP地址的时间戳为0x04AC03B0,第二个IP地址为0x3B2980FD,经过这个IP地址的时间戳为0x04B5EE4F,最后一个(第4个)IP地址为0xD39B1C09,经过这个IP地址的时间戳为0x04AC062A;

需要说明的一点是,《科来》6.2对这个选项的解码是错误的,无论是请求包还是应答包。一方面,《科来》把数据包第0x0025字节当作了“溢出字段/标志字段”字节来解码(这是正确的),另一方面,它又把这个字节当作了IP地址表的第1个字节,并由此把整个IP地址表都向前挪了一个字节(这是错的),这就是《科来》的错误所在。对比上面时间戳应答包与Ping -s命令的两张图,可以明显看到《科来》的解码结果与Ping -s的结果不同。期待《科来》6.3会对这个Bug有所修正吧

再有,我怎样也还未能解释清楚为什么这个应答包记录的第一个路由器的IP地址居然会为0x00000000(位于数据包的第0x0026~0x0029字节)。因为这意味着经过第一个路由器的时候,这个路由器仅仅在数据包中记录了路过时刻,没有按规定同时记录IP地址,而对照前面Ping -r命令捕捉到的应答包,这个IP地址应该为0xDA13C10B。对照Ping -s命令的图还可以看到,这个路由器不但对第一个请求包没有按规定同时记录IP地址,而且对后面两个Ping通了的请求包都作了同样的处理(还有一个请求包中途丢失了,为什么会丢失我们无从知晓,但估计如果可以观察的话,相信第一个IP恐怕也是同样处理的),说明这不是孤立的现象,而是这个路由器的标准处理手法。兴许这个路由器有故障?天知道

此外,对4字节的时间戳字段如何解码为可读的“年月日 时分秒”格式,我到现在还查不到相关资料。而无论是微软的Ping(它是从Unix移植过来的)还是《科来》,也都未对它进行解码,所以我们才看到“时间戳为0x04AC03B0”这种羞涩难懂的表达。不过这个问题我觉得不能怪微软或科来。微软不过是把一个Unix的程序移植了过来,Unix上没有的,微软当然可以理直气壮地也没有。至于科来,则不便评论了罢(我是科来的铁杆Fans啊!)。我觉得,要怪就只能怪我和steven两个人。怪我是因为我太Out,太孤陋寡闻。而怪steven的原因,则是他在他的经典上没有对此做出解释,以致后来的抄书人想抄都没处可抄,至于那些连想都没想过的,不予评论也罢

上一篇:计算机网络笔记二
下一篇:RNN网络详解
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站