以太网报文

  • DMAC:6字节,目的MAC地址,IPV4为6字节,该字段确定帧的接收者。可以是一个单播MAC地址,或组播MAC地址或者广播MAC地址。
  • SMAC:6字节,源MAC地址,IPV4为6字节,该字段标识发送帧的工作站。只能是一个单播MAC地址。
  • Type:2字节,用来表示荷载数据的类型。例如:该字段值如果是0x0800,则表示荷载数据是一个IPv4 Packet ,0x86dd是IPv6 Packet,0x0806是ARP Packet,0x8848是MPLS报文等。
  • Data:变长,数据字段的最小长度必须为46字节以保证帧长至少为64字节,这意味着传输一字节信息也必须使用46字节的数据字段。如果填入该字段的信息少于46字节,该字段的其余部分也必须进行填充。数据字段的最大长度为1500字节。
  • CRC:4字节,用于帧内后续字节差错的循环冗余检验(也称为FCS或帧检验序列)

注意:CRC在wireshark中无显示,若CRC错误,可能在网卡层或传入内核时被丢弃


ARP报文

  • 目的MAC地址:请求报文为ff-ff-ff-ff-ff-ff,应答报文为请求端的MAC地址。
  • 源MAC地址:请求报文为请求端的MAC地址,应答报文为被请求的MAC地址。
  • 帧类型:长度为2个字节,取值为0x0806,代表ARP报文。
  • 硬件类型:长度为2个字节。表示网络类型;以太网取值为1。
  • 协议类型:长度为2个字节。表示硬件地址要映射的协议地址类型,映射IP地址时的值为0x0800
  • 硬件地址长度(hln):长度为1个字节。表示硬件地址的长度;以太网中取值为6,表示MAC地址长度为6个字节。
  • 协议地址长度(pln):长度为1个字节。表示协议地址长度;取值为4表示IP地址长度为4个字节。
  • 操作类型(op):长度为2个字节,表示ARP报文的种类;取值为1表示是ARP请求报文。为2表示是ARP应答报文。
  • 发送端的MAC地址:请求报文为请求端的MAC地址;应答报文为被请求端的MAC地址。
  • 发送端的IP地址:请求报文为请求端的IP地址;应答报文为被请求端的IP地址。
  • 目的端MAC地址:请求端发出该请求时,还不知道该MAC地址。接收方忽略该字段。应答报文为请求端的MAC地址。
  • 目的端IP地址:请求端希望映射的IP地址,也就是被请求端的IP地址。应答报文为请求端的IP地址。

IP报文

  • 版本:长度为4bit,表示IP报文版本信息。该字段值为0x4,表示是IPv4报文,该字段值为0x6,表示是IPv6报文。

  • 首部长度:长度为4bit,用来表示IP包的头部长度(单位4字节)。如果不带可选字段,则为20字节,最长为60字节。

  • 服务类型(DS域):长度为8bit,只有在有QoS差分服务要求时这个字段才起作用,用来区分报文的转发优先级。

  • 总长度:长度为16bit,整个IP数据报的长度,包括首部和数据之和,单位为字节,最长65535,总长度必须不超过最大传输单元MTU。在进行分片时,总长度为分片后的每一片的IP首部和数据长度的总和。

  • 标识:长度为16bit,用于IP报文的分片和重组。主机每发一个报文该标识加1,因为IP是无连接服务,不存在按序接收问题,所以该序号仅用于IP分片时,在数据报长度超过MTU必须分片时,将该序号复制到所有的数据分片的标识字段中,相同的标识字段代表这些分片属于同一数据报

  • 标志:长度为3bit,用于IP报文的分片和重组

    • Bit 0: 保留位,必须为0
    • Bit 1: DF(Don’t Fragment),能否分片位,0表示可以分片,1表示不能分片
    • Bit 2: MF(More Fragment),表示是否该报文为最后一片,0表示最后一片,1代表后面还有
  • 片偏移:长度为13bit,用于IP报文的分片和重组。表示较长的分组在分片后,某片在原分组中的相对位置。以8个字节为偏移单位。

  • 生存时间(TTL):长度为8bit,可经过的最多路由数,即数据包在网络中可通过的路由器数的最大值。数据报每过一个路由器前将TTL值减1,若TTL减小到0,则丢弃这个数据报,不再转发,防止无法交付的数据报无限制的浪费网络资源(若将其设置为1,则代表该数据报只能在本局域网中传输)。

  • 协议类型:长度8bit,指出此数据包携带的数据使用何种协议,以便目的主机的IP层将数据部分上交给哪个进程处理。

    注意:这里的IP标识特殊的IP数据报-IP数据报再封装到IP数据报中

  • 头部校验和:长度为16bit,用来对IP报文的头部进行差错校验。只检验数据包的首部,不检验数据部分。这是因为数据报每经过一个路由器均需要重新计算头部校验和(一些字段如TTL,标识、片偏移都有可能发生变化),不校验数据可减少工作量,且这里不采用CRC检验码,而采用简单的计算方法:将IP数据报首部划分为许多16位字的序列,并将校验和字段置0.用反码算数运算把所有16位字相加后,得到的和的反码即为校验和。如下图所示

    反码算数运算:由低位到高位逐列计算,0和0相加是0,0和1相加是1,1和1相加是0,但产生一个进位1,加到下一列,若最高位相加后产生进位,则最后得到的结果要加1

  • 源IP地址:长度为32bit,表示产生并发送该IP报文的设备接口的IP地址。
  • 目的IP地址:长度为32bit,表示该IP报文的目的接口的IP地址。
  • 选项/长度填充:选项字段长度可变,从1字节到40字节不等,取决于所选项的功能。填充字段全为0。

ICMP

ICMP报文有两种:ICMP差错报告报文和ICMP询问报文
ICMP报文的前4字节是统一的格式,即类型、代码和校验和,接着4字节和ICMP的类型有关,最后是数据字段,其长度取决于ICMP的类型。下图给出常见报文类型

差错报告报文介绍

  1. 终点不可达:当路由器或主机不能交付数据报时就向源点发送该报文
  2. 源点抑制:当路由器或主机由于拥塞而丢弃数据报时,就向源点发送该报文,使其知道应当把报文发送速率变慢
  3. 时间超过:当路由器收到TTL为0的数据报时,除了丢弃报文外,还向源点发送该报文,若终点再预定规定的时间内不能收到一个数据报的全部分片报文时,就把已经收到的分片全部丢弃,并向源点发送该报文
  4. 参数问题:当路由器或目的主机收到的数据报的首部中有的字段的值不正确时就丢弃报文,并向源点发送参数问题报文
  5. 改变路由(重定向):路由器把改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器(可通过更好的路由)

改变路由的简短解释:我们知道,在因特网中的主机也要有一个路由表。当主机要发送数据报时,首先查找主机自己的路由表,看应从哪个接收把报文发出。在因特网中主机数量远大于路由器,出于效率的考虑,主机不和链接在网络上的路由器定期交换路由信息。在主机刚工作时,一般都在路由表中设置一个默认路由器的IP地址(这个就是网关),不管数据报要发送到哪个目的地址,都一律先将数据报传送给网络上的这个默认路由器,而这个默认路由器知道每一个目的网络的最佳路由(通过和其他路由器交换路由信息)。如果默认路由器发现主机发往某个目的地址的数据报的最佳路由不是自己而是另一个路由器R,那么就用ICMP的改变路由报文告诉主机,于是主机就在其路由表中增加一个项目:到某某目的地址应经过路由器R(而不是默认路由器)。

所有的ICMP差错报文格式:把收到的需要进行差错报告的IP数据报的首部和数据字段的前8个字节提取出来,作为ICMP报文的数据字段。如下图所示

提取前8字节是为了获取端口号(对于TCP和UDP)以及报文的发送序号(对于TCP),这些信息对源点通知高层协议是有用的

询问报文介绍

  1. 回送请求和应答
    回送请求报文是由主机或路由器向一个特定的目的主机发出的询问。收到此报文的主机必须源点发送ICMP回送应答报文。这种询问报文用来测试目的站是否可达以及了解其有关状态

    ping命令就是典型的ICMP会送请求和应答

  2. 时间戳请求和回答
    请求某个主机或路由器回答当前的日期和时间。再ICMP时间戳回答报文中有一个32位的字段,其中写入的整数代表从1900年1月1日起到当前时刻一共有多少秒。时间戳请求与回答可用来进行时钟同步和测量时间。


UDP报文

  • 源端口:源端口号。在需要对方回信时选用。不需要时可用全0。

  • 目的端口:目的端口号。这在终点交付报文时必须要使用到。

  • 长度:UDP用户数据报的长度,其最小值是8(仅有首部),发送一个带0字节数据的UDP数据报是允许的。

  • 伪首部
    在UDP伪首部中,包含32位源IP地址,32位目的IP地址,8位填充0,8位协议,16位UDP长度。伪首部并非TCP&UDP数据报中实际的有效成分。伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,既不向下传送也不向上递交,而仅仅是为计算校验和

    伪头部的目的是让UDP层验证数据是否已经到达正确的目的地(即该IP没有接受地址错误的数据报,也没有给UDP一个本该其他传输协议的数据报),计算UDP校验和时包含了伪头部以及UDP头部和负载。

  • 校验和:检测UDP用户数据报在传输中是否有错,有错就丢弃。方法如下:

    UDP计算校验和的方法和计算IP数据报首部校验和的方法相似。但不同的是:IP数据报的校验和只检验IP数据报的首部,但UDP的校验和是将首部和数据部分一起都检验。

    首先是将全零放入校验和字段。再将伪首部以及UDP用户数据报看是由许多16位的字串。若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零字节(此字节不发送)。 然后按二进制反码计算出这些16位字的和。该结果的反码即为校验和。

    如果校验和字段值为0x0000表示发送方没有计算校验和。

    下图给出一个例子,假定UDP长度未15字节,因此要添加一个全0字节


TCP

  • 源端口和目的端口:各占2个字节,分别写入源端口号和目的端口号。
  • 序列号(Sequence Number):占4字节,在TCP连接中传送的字节流中的每一个字节都按顺序编号,整个要传送的字节流的其实序号必须在连接建立时设置。该字段则指本报问段所发送的数据的第一个字节的序号。例如,一段报文的序列号字段值为301,携带数据100字节,那么下一个报文段的序列号字段应为401.

    通过序列号,TCP接收端可以识别出重复接收到的TCP包,从而丢弃重复包,同时对于乱序数据包也可以依靠系列号进行重排序,进而对高层提供有序的数据流。另外如果接收的包中包含SYN或FIN标志位,逻辑上也占用1个byte,应答号需加1。

  • 确认号(Acknowledgment Number):占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。例如,接收端接收到一个净荷为12byte的数据包,SN为5,则会回复一个确认收到的数据包,如果这个数据包之前的数据也都已经收到了,这个数据包中的确认号则设置为12+5=17,表示之前的数据都已经收到了,准备接受SN=17的数据包。
  • 头部长度:占4位,指示TCP头的长度,即数据从何处开始。单位为4字节,即TCP头部长度最大值为60字节
  • 保留:占6位,保留今后使用,目前应置为0.
  • 标志:6位标志位,下面介绍:
    1. 紧急 URG(Urgent):当URG=1时,表明紧急指针字段生效。它告诉系统此报文中由紧急数据,应尽快传送,而不要按原来的排队顺序来传送。当URG=1时,发送应用进程就告诉发送方的TCP由紧急数据要传送。于是发送方TCP就把紧急数据插入到本报问段数据的最前面,而在紧急数据后面的数据仍是普通数据,这时要与首部中的紧急指针字段配合使用。
    2. 确认 ACK(ACKnowlegment):仅当ACK=1时,确认号字段才生效。TCP规定,在连接建立后所有传送的报文段都必须将ACK置1。
    3. 推送 PSH(Push):该标志置位时,一般是表示发送端缓存中已经没有待发送的数据,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理 telnetrlogin 等交互模式的连接时,该标志总是置位的,目的是希望键入一个命令后立即就能收到对方的响应。
    4. 复位 RST(Reset):当RST=1时,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接。RST置1还用来拒绝一个非法的报文段或拒绝打开一个连接
    5. 同步 SYN(SYNchronization):再连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。若对方同意建立连接,则应再响应的报文段中使SYN=1和ACK=1。
    6. 终止 FIN(Finish):用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接
  • 窗口尺寸:占2字节,窗口尺寸是作为接收方让发送方设置其发送窗口的依据,用于TCP的流量控制。
  • 校验和:占2字节,校验和字段检查的范围包括首部和数据两部分。和UDP一样,再计算校验和时,要在TCP报文的前面加上12字节的伪首部,其格式与UDP一样,只不过需要将第4个字段的17改为6(TCP的协议号是6),把第5字段中的UDP长度改为TCP长度,计算方式也和UDP一致。
  • 紧急指针:占2字节,仅当URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。

    注意,即使窗口值为0也可发送紧急数据

  • 选项:长度不定,但长度必须以是32bits的整数倍。常见的选项包括MSS(最大报文段长度)、SACK(选择确认)、Timestamp(时间戳)等等。