ip协议为点对点协议,而非端对端的协议,提供无连接的数据服务,没有端口的概念, 发送数据使用sendto函数,接收数据使用recvfrom函数

报文格式

ip数据报文格式

  • 版本号: 4bit, ip协议的版本,通信双方的ip协议必须达成一致,ipv4的版本就是4

  • 首部长度: 4bit,可表示的最大十进制数值是15。 请注意,这个字段所表示数的单位是32位字长(1个32位字长是4字节),因此,当IP的首部长度为1111时(即十进制的15),首部长度就达到60字节当IP分组的首部长度不是4字节的整数倍时,必须利用最后的填充字段加以填充。因此数据部分永远在4字节的整数倍开始,这样在实现IP协议时较为方便。首部长度限制为60字节的缺点是有时可能不够用。但这样做是希望用户尽量减少开销。最常用的首部长度就是20字节(即首部长度为0101),这时不使用任何选项。

  • 区分服务: 占8位,用来获得更好的服务。这个字段在旧标准中叫做服务类型,但实际上一直没有被使用过。1998年IETF把这个字段改名为区分服务DS(Differentiated Services)。只有在使用区分服务时,这个字段才起作用。 给应用程序,主机和Internet上的路由器提供一个优先级服务。在这个字段设置合适的标志,应用程序可以要求这个数据包得到高优先级,而让其他数据包等待

  • 总长度: 总长度指首部和数据之和的长度,单位为字节。总长度字段为16位,因此数据报的最大长度为2^16-1=65535字节。
    在IP层下面的每一种数据链路层都有自己的帧格式,其中包括帧格式中的数据字段的最大长度,这称为最大传送单元MTU(Maximum Transfer Unit)。当一个数据报封装成链路层的帧时,此数据报的总长度(即首部加上数据部分)一定不能超过下面的数据链路层的MTU值。最常见的MTU值是1500字节。超过则需要进行分片处理。
    MTU

  • 标识: 占16位。IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。但这个“标识”并不是序号,因为IP是无连接服务,数据报不存在按序接收的问题。当数据报由于长度超过网络的MTU而必须分片时,这个标识字段的值就被复制到所有的数据报的标识字段中。相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报

  • 标志:占3位,但目前只有2位有意义。

    • 标志字段中的最低位记为MF(More Fragment)。MF=1即表示后面“还有分片”的数据报。MF=0表示这已是若干数据报片中的最后一个
    • 标志字段中间的一位记为DF(Don’t Fragment),意思是“不能分片”。只有当DF=0时才允许分片。
      标志
  • 片偏移: 占13位。片偏移指出:较长的分组在分片后,某片在原分组中的相对位置。也就是说,相对用户数据字段的起点,该片从何处开始。片偏移以8个字节为偏移单位。这就是说,每个分片的长度一定是8字节(64位)的整数倍

  • 生存时间:占8位,生存时间字段常用的的英文缩写是TTL(Time To Live),表明是数据报在网络中的寿命。由发出数据报的源点设置这个字段。其目的是防止无法交付的数据报无限制地在因特网中兜圈子,因而白白消耗网络资源。最初的设计是以秒作为TTL的单位。每经过一个路由器时,就把TTL减去数据报在路由器消耗掉的一段时间。若数据报在路由器消耗的时间小于1秒,就把TTL值减1。当TTL值为0时,就丢弃这个数据报

  • 协议: 占8位,协议字段指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个处理过程。

    • icmp : 1
    • IGMP:2
    • IP: 4,如果你对为什么在协议名中竟然还会出现IP协议感到困惑,建议有时间研究一下IPSec VPN的原理,这里简单提一下,IPSec VPN是一种通过用公网IP来封装私网IP以实现跨公网的私网之间进行局域网通信的一种隧道技术
    • TCP:6
    • UDP:17
      • IPV6:41
        协议字段说明
  • 首部检验和: 占16位。这个字段只检验数据报的首部,但不包括数据部分。这是因为数据报每经过一个路由器,路由器都要重新计算一下首部检验和(一些字段,如生存时间、标志、片偏移等都可能发生变化)。不检验数据部分可减少计算的工作量。采用反码算数运算。
    校验和计算

    首先在发送端的时候,将校验和全部置为0,然后把数据报首段数据全部进行反码相加,得到的值为校验和,放入首段校验和里面,然后接收端将数据报首段数据和校验和一起全部反码相加,最后若是得到零,则保留,若是不为零,则说明数据报在传输的过程中发生了改变,则丢弃该数据报

  • 源IP地址:占32位, 注意使用的是大端法,如果应用层将IP地址看作是32位数值则需要将网络字节顺序转化为主机字节顺序

  • 目的IP地址:占32位

实例分析

  • 正常的icmp包
    tcpdump -i lo icmp -X 抓取icmp报文,查看ip报文首部

tcpdump抓取的icmp包

数据 含义
4 版本号,表明为ipv4
5 首部长度,0101 表明首部长度为5*4=20字节
00 tos
0054 总长度,0x54 = 84字节 如图中 length 84 所示
8cba 标识 35840+186 = 36026, 如图中id所示
4000 4 表示0100, 表示不分片,后面的13位表示片偏移, 为0
40 表示ttl,4*16 = 64
01 表示协议为icmp协议
afec 表示首部校验和
7f00 0001 表示源ip地址, 127.0.0.1
7f00 0001 表示目的ip地址 127.0.0.1

ping www.baidu.com
分片记录
|数据 | 含义|
|:———:|:————-:|
| 4 | 版本号,表明为ipv4|
| 5 | 首部长度,0101 表明首部长度为5*4=20字节|
|00| tos |
|05dc| 总长度,0x05dc = 1500 字节 |
|2c5a| 标识|
|20b9| 前3位为001, 表示分片,后面的13位表示片偏移, b9为185 |
|0a| 表示ttl,ttl=10|
|01| 表示协议为icmp协议|
|1b2a| 表示首部校验和 |
|ac11 9387| 表示源ip地址, 172.17.147.135|
|dcb5 2696| 表示目的ip地址 220.181.38.150|

为什么icmp包数据的最大值只能是65507 计算:65535-ip首部20字节-icmp首部8字节 = 65507

文档更新时间: 2021-01-28 19:59   作者:周国强