ca88yzc 3

【ca88yzc】ipv4尾部分析

Posted by

通信术语 最大传输单元(Maximum Transmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口有关(网络接口卡、串口等)。

详细解释

因特网协议允许IP分片,这样就可以将数据包分成足够小的片段以通过那些最大传输单元小于该数据包原始大小的链路了。这一分片过程发生在网络层(OSI
模型的第三层),第四层为传输层,传输层是
OSI
模型中最重要的一层,这里是根据窗口控制传输,而非MTU。传输协议同时进行流量控制或是基于接收方可接收数据的快慢程度规定适当的发送速率。除此之外,传输层按照网络能处理的最大尺寸将较长的数据包进行强制分割。例如,以太网无法接收大于1500字节的数据包。发送方节点的传输层将数据分割成较小的数据片,同时对每一数据片安排一序列号,以便数据到达接收方节点的传输层时,能以正确的顺序重组,该过程即被称为排序。它使用的是将分组发送到链路上的网络接口的最大传输单元的值。原始分组的分片都被加上了标记,这样目的主机的TCP层就能将分组重组成原始的数据包了。

在因特网协议中,一条因特网传输路径的“路径最大传输单元”被定义为从源地址到目的地址所经过“路径”上的所有IP跳的最大传输单元的最小值。或者从另外一个角度来看,就是无需进一步分片就能穿过这条“路径”的传输单元的最大值。

RFC
1191描述了“路径最大传输单元发现方法”,这是一种确定两个IP主机之间路径最大传输单元的技术,其目的是为了避免IP分片。在这项技术中,源地址将数据报的DF(Don’t
Fragment,不要分片)位置位,再逐渐增大发送的数据报的大小——路径上任何需要将分组进行分片的设备都会将这种数据报丢弃并返回一个“数据报过大”的ICMP响应到源地址——这样,源主机就“学习”到了不用进行分片就能通过这条路径的最大的最大传输单元了。

不幸的是,越来越多的网络封杀了ICMP的传输(譬如说为了防范DDOS攻击)——这使得路径最大传输单元发现方法不能正常工作,其常见表现就是一个连接在低数据流量的情况下可以正常工作,但一旦有大量数据同时发送,就会立即挂起(例如在使用IRC的时候,客户会发现在发送了一个禁止IP欺骗的ping之后就得不到任何响应了,这是因为该连接被大量的欢迎消息堵塞了)。而且,在一个使用因特网协议的网络中,从源地址到目的地址的“路径”常常会为了响应各种各样的事件(负载均衡、拥塞、断电等等)而被动态地修改——这可能导致路径最大传输单元在传输过程中发生改变——有时甚至是反复的改变。其结果是,在主机寻找新的可以安全工作的最大传输单元的同时,更多的分组被丢失掉了。

对于时下大多数使用以太网的局域网来说,最大传输单元的值是1500字节。但是像PPPoE这样的系统会减小这个数值,这就使得在使用最大传输单元发现方法时可能会产生这样的结果:一些处于配置不当的防火墙之后的站点变得不可达了。对于这种情况,还是可能找到变通的方法的,但这取决于你控制的是网络的哪一部分。这些方法包括改变用来在防火墙一端建立TCP连接的第一个分组的MSS(Maximum
Segment Size,最大分段大小)。

对于一些支持老版本以太网协议的IBM系统(例如XSeries),可能只有在把最大传输单元设为1492之后才能在当下常见的局域网上进行运作。

如何检测网关的MTU

在本机打开dos窗口,执行: ping -f -l 1472 192.168.0.1
其中192.168.0.1是网关IP地址,1472是数据包的长度。请注意,上面的参数是“-l”(小写的L),而不是“-1”。
如果能ping通,表示数据包不需要拆包,可以通过网关发送出去。 如果出现:
Packet needs to be fragmented but DF set.
表示数据包需要拆开来发送。此时,减少数据包长度,再执行上面的ping命令。从1400到1472之间多试几次,就能找到合适的数据包长度了。把数据包长度加上数据包头28字节,就得到MTU的值。
如果检测到网关的MTU值是1500,不需要修改。
如果网关有防火墙ping不通,可以试试直接把MTU设为1400。

 

如何修改本机的MTU

修改方法如下:

Windows平台下

1、运行regedit

2、打开:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces

3、Interfaces下有多个子项,每个子项对应一个网卡。请按如下方法选择网卡:

A、确定本机用来连接Internet的网卡或拨号连接的IP,如192.168.0.19;

B、用鼠标点击Interfaces上的子项,查看键值列表中的IPAddress项;

C、如果IPAddress的键值与A中的IP相同,即192.168.0.19,则该子项就是要找的网卡。

4、进入该子项,在右边的窗口里按鼠标右键,选择“新建”->“DWORD
值”,输入名称“MTU”,按回车。再用鼠标双击“MTU”,弹出修改窗口,填入MTU的值(一般为十进制的1480)。

填写前请先把基数设为十进制。 设置好后,需要重启机器才能生效。

Windows 7(XP、Vista未实测)

1、使用管理员权限运行cmd

2、使用netsh interface ipv4 show
subinterfaces命令看看MTU以及本地连接名称。

3、使用netsh interface ipv4 set subinterface “本地连接” mtu=1000
store=persistent

(注:这里的连接名是你使用上面命令看到的MTU值对应的这个连接名,他在右边显示。)

附:1、此方法不用重启;2、如是ipv6就将上面的ipv4改成ipv6

Linux下可使用如下命令修改 需要root权限

ifconfig网卡MTU值

如 ifconfig eth0 mtu 1460

MaxMTU是最大的TCP/IP传输单元,在TCP/IP协议中,将要传输的数据分成较小的组进行传输,每个组的大小为576字节。Windows默认的字节为1500,这是以太网的分组标准。ADSL使用的
PPPoE略小于这个数值,一般为1492。而某些网站采用的MaxMTU大于1492,所以,可能导致某些网页不能访问。修改Windows默认的MaxMTU可以解决这个问题。不论是
PC机上安装的PPPoE软件或者是内置在Modem的
PPPoE软件,在使用中都有可能遇到这个问题。
如果使用路由器出现此种情况,
请在防火墙配置 => 基本设定
里, 将MTU改为手工, 设置为 1492 即可. 那如何确定路由器从ISP获得的 MTU 为
1500, 请见附件圈出的位置.

网络中一些常见链路层协议MTU的缺省数值如下:

FDDI协议:4352字节

以太网(Ethernet)协议:1500字节

PPPoE(ADSL)协议:1492字节

X.25协议(Dial
Up/Modem):576字节

Point-to-Point:4470字节

如果在IP层要传输一个数据报比链路层的MTU还大,那么IP层就会对这个数据报进行分片。一个数据报会被分为若干片,每个分片的大小都小于或者等于链路层的MTU值。当同一网络上的主机互相进行通信时,该网络的MTU对通信双方非常重要。但当主机间要通过很多网络才能通信时,对通信双方最重要的是通信路径中最小的MTU,因为在通信路径上不同网络的链路层MTU不同。通信路径中最小的MTU被称为路径MTU。

 


The ipv6 mtu of interface 0 is 3100:
awang@awangdevpc:/tmp$ sudo tcpdump -ni eth0 -evvv icmp6

09:22:22.394905 f0:de:f1:fb:98:8b > 00:21:27:ac:f1:53, ethertype IPv6
(0x86dd), length 3110: (hlim 64, next-header Fragment (44) payload
length: 3056) 1234::60ef:4cde:b1a1:d87e > 1234::2: frag
(0xe5fc7cc4:0|3048) ICMP6, echo request, length 3048, seq 1
09:22:22.394934 f0:de:f1:fb:98:8b > 00:21:27:ac:f1:53, ethertype IPv6
(0x86dd), length 2022: (hlim 64, next-header Fragment (44) payload
length: 1968) 1234::60ef:4cde:b1a1:d87e > 1234::2: frag
(0xe5fc7cc4:3048|1960)

09:22:22.396538 00:21:27:ac:f1:53 > f0:de:f1:fb:98:8b, ethertype IPv6
(0x86dd), length 3110: (hlim 64, next-header Fragment (44) payload
length: 3056) 1234::2 > 1234::60ef:4cde:b1a1:d87e: frag
(0x249da4f6:0|3048) ICMP6, echo reply, length 3048, seq 1
09:22:22.396544 00:21:27:ac:f1:53 > f0:de:f1:fb:98:8b, ethertype IPv6
(0x86dd), length 2022: (hlim 64, next-header Fragment (44) payload
length: 1968) 1234::2 > 1234::60ef:4cde:b1a1:d87e: frag
(0x249da4f6:3048|1960)

1.  Algorithm:

1>  Is the biggest integer which is smaller than 3100.
2>  could be devided by 8.
Since “3096” match the rule, so use it in IP layer to fragment.  

2.  Then use the “3096” to caculate other length:
3>  Ethernet layer length : add the ethernet header length “14”, the
total length which is printed in ethernet layer is “3110”.
4>  IP layber payload: Since the IP layber of IPV4 is 40, so the
printed payload is 3056.  
5>  ICMP length : And the ICMP tyoe of IPV6 is 8, so the printed ICMP
payload is 3048.


ipv4 mtu:

If set the ipv4 mtu of interface 0 to “1500”, then ping an IP address
whihc is directlly connected, then use tcpdump:

awang@awangdevpc:/tmp$ sudo tcpdump -ni eth0 -evvv icmp

09:39:53.721760 00:21:9b:58:ca:8f > 00:90:7f:95:70:98, ethertype IPv4
(0x0800), length 1514: (tos 0x0, ttl 64, id 8113, offset 0, flags [+],
proto ICMP (1), length 1500)
    172.26.0.183 > 172.26.0.1: ICMP echo request, id 4321, seq 1,
length 1480
09:39:53.721778 00:21:9b:58:ca:8f > 00:90:7f:95:70:98, ethertype IPv4
(0x0800), length 1514: (tos 0x0, ttl 64, id 8113, offset 1480, flags
[+], proto ICMP (1), length 1500)
    172.26.0.183 > 172.26.0.1: icmp
09:39:53.721781 00:21:9b:58:ca:8f > 00:90:7f:95:70:98, ethertype IPv4
(0x0800), length 1514: (tos 0x0, ttl 64, id 8113, offset 2960, flags
[+], proto ICMP (1), length 1500)
    172.26.0.183 > 172.26.0.1: icmp
09:39:53.721784 00:21:9b:58:ca:8f > 00:90:7f:95:70:98, ethertype IPv4
(0x0800), length 602: (tos 0x0, ttl 64, id 8113, offset 4440, flags
[none], proto ICMP (1), length 588)
    172.26.0.183 > 172.26.0.1: icmp

09:39:53.722909 00:90:7f:95:70:98 > 00:21:9b:58:ca:8f, ethertype IPv4
(0x0800), length 1514: (tos 0x0, ttl 64, id 10621, offset 0, flags
[+], proto ICMP (1), length 1500)
    172.26.0.1 > 172.26.0.183: ICMP echo reply, id 4321, seq 1,
length 1480
09:39:53.723153 00:90:7f:95:70:98 > 00:21:9b:58:ca:8f, ethertype IPv4
(0x0800), length 1514: (tos 0x0, ttl 64, id 10621, offset 1480, flags
[+], proto ICMP (1), length 1500)
    172.26.0.1 > 172.26.0.183: icmp
09:39:53.723161 00:90:7f:95:70:98 > 00:21:9b:58:ca:8f, ethertype IPv4
(0x0800), length 1514: (tos 0x0, ttl 64, id 10621, offset 2960, flags
[+], proto ICMP (1), length 1500)
    172.26.0.1 > 172.26.0.183: icmp
09:39:53.723402 00:90:7f:95:70:98 > 00:21:9b:58:ca:8f, ethertype IPv4
(0x0800), length 602: (tos 0x0, ttl 64, id 10621, offset 4440, flags
[none], proto ICMP (1), length 588)
    172.26.0.1 > 172.26.0.183: icmp

1.  Algorithm:
1>  Is the biggest integer which is smaller than 1500.
2>  could be devided by 4.
Since “1500” match the rule, so use it in IP layer to fragment.

2.  Then use the “3096” to caculate other length:
Ethernet layer length : Add the ethernet header length “14”, the total
length which is printed in ethernet layer is “1514”.

 

ca88yzc 1

ip头部最长是60字节,前面的20字节是固定的,选项可加上40字节

4位版本号— 对于ipv4来说呢,就是4

4位头部长度 —  表示
有多小个32bit(4字节),4位最大表示数是15啦,也就是最大就是15啦,所以头部最长就是60啦

8位服务类型 — 已经不用了

16总长度—ip数据报长度 所以最大长度为 65535啦

16位标识– 分片的时候用的

3位标志 — 第一位保留 第二位 禁止分片 第三位 表示更多分片

13位偏移 — 相对ip数据报的开始处

8位生存时间 —ttl 当变为0的时候抛弃

8 位协议 —- 指应用层协议,区分上层协议

16位校验和 —- 数据的hash值啦

32 位 原端 和目的端ip地址

选项 包括有

1 记录路由

2 时间戳

3 松散路由

4 严谨 路由

下面来分析一下

tcpdump -i eth0:1 -ent ‘(dst 192.168.5.190 and src 192.168.5.109)or( dst
192.168.5.109 and src 192.168.5.190)’ –X

bc:ee:7b:9d:ee:02 > 40:16:7e:79:c7:36, ethertype IPv4 (0x0800),
length 74: 192.168.5.109 > 192.168.5.190: ICMP echo request, id 1,
seq 72, length 40

0x0000:  4500 003c 7da4 0000 4001 70a1 c0a8 056d  E..<}…@.p….m
0x0010:  c0a8 05be 0800 4d13 0001 0048 6162 6364  ……M….Habcd
0x0020:  6566 6768 696a 6b6c 6d6e 6f70 7172 7374  efghijklmnopqrst
0x0030:  7576 7761 6263 6465 6667 6869            uvwabcdefghi

0x4 代表ip版本号

0x5  头部长度为 5个32位(20个字节)

0x00 说明tos没有开启

0x003c  说明 数据报总长度 60字节

0x7da4 数据报标示

0x0 没有设置标志位

0x000 分片偏移

0x40 ttl设置为64

0x01 表示上层协议 为 icmp    1    ICMP        # internet control
message protocol (可以查找linux的/etc/protocols )

0x70a1 校验值

0xc0a8 056d 源ip

0xc0a8 05be 目标ip

 

IP分片

什么时候会分片呢,就是数据包大的时候啦

ca88yzc 2

参照下图就最清楚啦

ca88yzc 3

下面来做个试验

ping 192.168.5.190 -l 1473

bc:ee:7b:9d:ee:02 > 40:16:7e:79:c7:36, ethertype IPv4 (0x0800),
length 1514: (tos 0x0, ttl 64, id 20425, offset 0, flags [+], proto
ICMP (1), length 1500)

192.168.5.109 > 192.168.5.190: ICMP echo request, id 1, seq 92,
length 1480

bc:ee:7b:9d:ee:02 > 40:16:7e:79:c7:36, ethertype IPv4 (0x0800),
length 60: (tos 0x0, ttl 64, id 20425, offset 1480, flags [none],
proto ICMP (1), length 21)

192.168.5.109 > 192.168.5.190: icmp

从id可以看出

他们两个包都是同一个包的

第一个包偏移为0 ,flag[+] 表示MF标志啦

第二个包偏移为1480 flag[none]表示已经无下一个

从上个我们可以知道,第二个包是没有包含icmp头部,因为规范说第一次发了下次就不发啦

相关文章

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注