TCP/IP 学习笔记(一)-网络层和传输层协议的报文格式

287 阅读23分钟

MAC地址

image.png

  • 1 :单播地址(0)/多播地址(1)
  • 2 : 全局地址(0)/本地地址(1)
  • 3~24(22) : 厂商识别码,由ieee管理,保证不重复
  • 25~28(24) : 厂商内识别码,由厂商管理,标识不同的产品

以太网帧

以太帧的结构

image.png

  • 前同步码:用来使接收端的适配器在接收 MAC 帧时能够迅速调整时钟频率,使它和发送端的频率相同。前同步码为 7 个字节,1 和 0 交替。
  • 帧开始定界符:帧的起始符,为 1 个字节。前 6 位 1 和 0 交替,最后的两个连续的 1 表示告诉接收端适配器:“帧信息要来了,准备接收”。
  • 目的地址:接收帧的网络适配器的物理地址(MAC 地址),为 6 个字节(48 比特)。作用是当网卡接收到一个数据帧时,首先会检查该帧的目的地址,是否与当前适配器的物理地址相同,如果相同,就会进一步处理;如果不同,则直接丢弃。
  • 源地址:发送帧的网络适配器的物理地址(MAC 地址),为 6 个字节(48 比特)。
  • 类型:上层协议的类型。由于上层协议众多,所以在处理数据的时候必须设置该字段,标识数据交付哪个协议处理。例如,字段为 0x0800 时,表示将数据交付给 IP 协议。
  • 数据:也称为效载荷,表示交付给上层的数据。以太网帧数据长度最小为 46 字节,最大为 1500 字节。如果不足 46 字节时,会填充到最小长度。最大值也叫最大传输单元(MTU)。在 Linux 中,使用 ifconfig 命令可以查看该值,通常为 1500。
  • 帧检验序列FCS:检测该帧是否出现差错,占 4 个字节(32 比特)。发送方计算帧的循环冗余码校验(CRC)值,把这个值写到帧里。接收方计算机重新计算 CRC,与 FCS 字段的值进行比较。如果两个值不相同,则表示传输过程中发生了数据丢失或改变。这时,就需要重新传输这一帧。

以太帧的工作机制

当以太网软件从网络层接收到数据报之后,需要完成如下操作:

  1. 根据需要把网际层的数据分解为较小的块,以符合以太网帧数据段的要求。
以太网帧的整体大小必须在 64~1518 字节之间(不包含前导码)。有些系统支持更大的帧,
最大可以支持 9000 字节。有些系统支持更大的帧,最大可以支持 9000 字节。
  1. 把数据块打包成帧。每一帧都包含数据及其他信息,这些信息是以太网网络适配器处理帧所需要的。
  2. 把数据帧传递给对应于 OSI 模型物理层的底层组件,后者把帧转换为比特流,并且通过传输介质发送出去。
  3. 以太网上的其他网络适配器接收到这个帧,检查其中的目的地址。如果目的地址与网络适配器的地址相匹配,适配器软件就会处理接收到的帧,把数据传递给协议栈中较高的层。

image.png

ipv4首部

image.png

注意: 上图表示的数据,最高位在左边,记为0位;最低位在右边,记为31位。在网络中传输数据时,先传输0~7位,其次是8~15位,
然后传输16~23位,最后传输24~31位。由于TCP/IP协议头部中所有的二进制数在网络中传输时都要求以这种顺序进行,因此把它称为
网络字节顺序。在实际编程中,以其他形式存储的二进制数必须在传输数据前使用网络编程API相应的函数把头部转换成网络字节顺序。

1)版本号: 占用4位(二进制位),表示该IP数据报使用的IP协议版本。目前Internet中使用的主要是TCP/IP协议族中版本号为4(二进制表示0100)的IP协议, IPV6为0110。

2)头长度: 占用4位,此域指出整个报头的长度(包括选项),该长度是以32位二进制数为一个计数单位的(*4 才为实际头部长度),接收端通过此域可以计算出报头在何处结束及从何处开始读数据。普通IP数据报(没有任何选项)该字段的值是5(二进制表示0101)(即20个字节的长度)。

3)服务类型TOS(Type Of Service): 占用8位,用于规定本数据报的处理方式。 服务类型字段的8位分成以下5个子域:

3 bit1 bit1 bit1 bit2 bit
优先权短延迟D高吞吐量位T高可靠位R保留位
  • 优先权: 占用3位,数值(十进制0~7)越大,表示该数据报优先权越高。网络中路由器可以使用优先权进行拥塞控制,如当网络发生拥塞时可以根据数据报的优先权来决定数据报的取舍。
  • 短延迟位D(Delay): 占用1位,该位置为1时,数据报请求以短延迟信道传输,0表示正常延时。
  • 高吞吐量位T(Throughput): 占用1位,该位置1时,数据报请求以高吞吐量信道传输,0表示普通。
  • 高可靠位R(Reliability): 占用1位,该位置1时,数据报请求以高可靠性信道传输,0表示普通。
  • 保留位: 占用2位。

4)总长度: 占用16位,总长度字段是指整个IP数据报的长度(报头区+数据区),以字节为单位。利用头部长度字段和总长度字段就可以计算出IP数据报中数据内容的起始位置和长度。由于该字段长度为16位二进制数,因此理论上IP数据报最长可达65536个(2的16次方-1)字节(事实上受物理网络的限制,要比这个数值小很多)。

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

6)标志(flag): 占用3位,R、DF(Don’t Fragment)、MF(More Fragment)三位。目前只有后两位有效。

  • DF位:为1表示不分片,为0表示分片。
  • MF:为1表示“更多的片”,为0表示这是最后一片。

7)片位移: 占用13位,分片重组时会用到该字段。表示较长的分组在分片后,某片在原分组中的相对位置。以8个字节为偏移单位。因此,实际偏移位置/8 = 该值。

8)生存时间(TTL,time to live): 占用8位,它指定了数据报可以在网络中传输的最长时间。实际应用中把生存时间字段设置成了数据报可以经过的最大路由器数。TTL的初始值由源主机设置(通常为32、64、128或256),一旦经过一个处理它的路由器,它的值就减1。当该字段为0时,数据报就丢弃,并发送ICMP报文通知源主机,因此可以防止进入一个循环回路时,数据报无休止地传输下去。

9)上层协议标识: 占用8位,IP协议可以承载各种上层协议,目标端根据协议标识就可以把收到的IP数据报送到TCP或UDP等处理此报文的上层协议了。常用网际协议编号:

image.png

10)头部校验和: 占用16位,用于协议头数据有效性的校验,可以保证IP报头区在传输时的正确性和完整性。头部检验和字段是根据IP协议头计算出的检验和,它不对头部后面的数据进行计算。

原理:发送端首先将检验和字段置0,然后对头部中每16位二进制数进行反码求和的运算,并将结果存在校验和字段中。 由于接收方在
计算过程中包含了发送方放在头部的校验和,因此,如果头部在传输过程中没有发生任何差错,那么接收方计算的结果应该是全1。

11)源地址: 占用32位,表示发送端IP地址。

12)目的地址: 占用32位,表述目的端IP地址。

ARP

报文格式

ARP 协议包(ARP 报文)主要分为 ARP 请求包和 ARP 响应包,ARP 协议是通过报文进行工作的,ARP 报文格式如图所示:
image.png

RP 报文总长度为 28 字节,MAC 地址长度为 6 字节,IP 地址长度为 4 字节。其中,每个字段的含义如下。

  • 硬件类型:指明了发送方想知道的硬件接口类型,以太网的值为 1。
  • 协议类型:表示要映射的协议地址类型。它的值为 0x0800,表示 IP 地址。
  • 硬件地址长度和协议长度:分别指出硬件地址和协议的长度,以字节为单位。对于以太网上 IP 地址的ARP请求或应答来说,它们的值分别为 6 和 4。
  • 操作类型:用来表示这个报文的类型,ARP 请求为 1,ARP 响应为 2,RARP 请求为 3,RARP 响应为 4。
  • 发送方 MAC 地址:发送方设备的硬件地址。
  • 发送方 IP 地址:发送方设备的 IP 地址。
  • 目标 MAC 地址:接收方设备的硬件地址。
  • 目标 IP 地址:接收方设备的IP地址。

ARP 数据包分为请求包和响应包,对应报文中的某些字段值也有所不同。

  • ARP 请求包报文的操作类型(op)字段的值为 request(1),目标 MAC 地址字段的值为 Target 00:00:00_00:00:00(00:00:00:00:00:00)(广播地址)。
  • ARP 响应包报文中操作类型(op)字段的值为 reply(2),目标 MAC 地址字段的值为目标主机的硬件地址。

ARP工作机制

ARP 工作流程分为两个阶段,一个是 ARP 请求过程,另一个是 ARP 响应过程。工作流程如下所示。 image.png image.png

在上面图片中,主机 A 的 IP 地址为 192.168.1.1,主机 B 的 IP 地址为 192.168.1.2。

主机 A 与主机 B 进行通信,需要获取其 MAC 地址,基本流程如下:

  • 主机 A 以广播形式向网络中所有主机发送 ARP 请求,请求包中包含了目标 IP 地址 192.168.1.2。
  • 主机 B 接收到请求,发现自己就是主机 A 要找的主机,返回响应,响应包中包含自己的 MAC 地址。

ARP 缓存

在请求目标主机的 MAC 地址时,每次获取目标主机 MAC 地址都需要发送一次 ARP 请求,然后根据响应获取到 MAC 地址。为了避免重复发送 ARP 请求,每台主机都有一个 ARP 高速缓存。当主机得到 ARP 响应后,将目标主机的 IP 地址和物理地址存入本机 ARP 缓存中,并保留一定时间。只要在这个时间范围内,下次请求 MAC 地址时,直接查询 ARP 缓存,而无须再发送 ARP 请求,从而节约了网络资源。

当有了 ARP 缓存以后,ARP 的工作流程如下:

  1. 主机 A 在本机 ARP 缓存中检查主机 B 的匹配 MAC 地址。

  2. 如果在 ARP 缓存中没有找到主机 B 的 IP 地址及对应的 MAC 地址,它将询问主机 B 的 MAC 地址,从而将 ARP 请求帧广播到本地网络上的所有主机。源主机 A 的 IP 地址和 MAC 地址都包括在 ARP 请求中。

  3. 本地网络上的每台主机都接收到 ARP 请求,并且检查是否与自己的 IP 地址匹配。如果主机发现请求的 IP 地址与自己的 IP 地址不匹配,它将丢弃 ARP 请求。主机 B 确定 ARP 请求中的 IP 地址与自己的 IP 地址匹配,则将主机 A 的 IP 地址和 MAC 地址映射添加到本地 ARP 缓存中。

  4. 主机 B 将包含自身 MAC 地址的 ARP 回复消息直接发送给主机 A。

  5. 当主机 A 收到从主机 B 发来的 ARP 回复消息时,会用主机 B 的 IP 地址和 MAC 地址更新 ARP 缓存。

  6. 主机 B 的 MAC 地址一旦确定,主机 A 就能向主机 B 发送 IP 数据包。本机缓存是有生存期的,生存期结束后,将再次重复上面的过程。

ICMP

1.   ICMP允许主机或路由报告差错情况和提供有关异常情况。ICMP是因特网的标准协议,但ICMP不是高层协议,而是IP层的协议。
通常ICMP报文被IP层或更高层协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。
2.   ICMP报文作为IP层数据报的数据,加上数据报的首部,组成数据报发送出去。
3.   ICMP报文的种类有两种,即ICMP差错报告报文和ICMP询问报文。

报文格式

image.png

ICMP报文的前4个字节是统一的格式,共有三个字段:即类型,代码和检验和。

  • 类型:占8位
  • 代码:占8位
  • 检验和:占16位
8位类型和8位代码字段一起决定了ICMP报文的类型:
类型8,代码0:表示回显请求(ping请求)。
类型0,代码0:表示回显应答(ping应答)
类型11,代码0:超时

检验和字段:包括数据在内的整个ICMP数据包的检验和;其计算方法和IP头部检验和的计算方法一样的。

其它字段根据ICMP报文类型不同而不同。 ICMP报文具体分为查询报文和差错报文(对ICMP差错报文有时需要做特殊处理,因此要对其进行区分。如:对ICMP差错报文进行响应时,永远不会生成另一份ICMP差错报文,否则会出现死循环)

详细请查阅:icmp 报文详解

TCP首部格式

image.png image.png

  1. 源端口和目的端口
  • TCP源端口(Source Port):源计算机上的应用程序的端口号,占 16 位。
  • TCP目的端口(Destination Port):目标计算机的应用程序端口号,占 16 位。
  1. 序列号:CP序列号(Sequence Number):占 32 位。它表示本报文段所发送数据的第一个字节的编号。在 TCP 连接中,所传送的字节流的每一个字节都会按顺序编号。当SYN标记不为1时,这是当前数据分段第一个字母的序列号;如果SYN的值是1时,这个字段的值就是初始序列值(ISN),用于对序列号进行同步。这时,第一个字节的序列号比这个字段的值大1,也就是ISN加1。
  2. 确认号:TCP 确认号(Acknowledgment Number,ACK Number):占 32 位。它表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。其值是接收计算机即将接收到的下一个序列号,也就是下一个接收到的字节的序列号加1。
  3. T首部长度/数据偏移(Header Length):数据偏移是指数据段中的“数据”部分起始处距离 TCP 数据段起始处的字节偏移量,占 4 位。其实这里的“数据偏移”也是在确定 TCP 数据段头部分的长度,告诉接收端的应用程序,数据从何处开始。
  4. 保留位(Reserved):占 4 位。为 TCP 将来的发展预留空间,目前必须全部为 0。
  5. 控制位
  • CWR(Congestion Window Reduce):拥塞窗口减少标志,用来表明它接收到了设置 ECE 标志的 TCP 包。并且,发送方收到消息之后,通过减小发送窗口的大小来降低发送速率。
  • ECE(ECN Echo):用来在 TCP 三次握手时表明一个 TCP 端是具备 ECN 功能的。在数据传输过程中,它也用来表明接收到的 TCP 包的 IP 头部的 ECN 被设置为 11,即网络线路拥堵。
  • URG(Urgent):表示本报文段中发送的数据是否包含紧急数据。URG=1 时表示有紧急数据。当 URG=1 时,后面的紧急指针字段才有效。
  • ACK:表示前面的确认号字段是否有效。ACK=1 时表示有效。只有当 ACK=1 时,前面的确认号字段才有效。TCP 规定,连接建立后,ACK 必须为 1。
  • PSH(Push):告诉对方收到该报文段后是否立即把数据推送给上层。如果值为 1,表示应当立即把数据提交给上层,而不是缓存起来。
  • RST:表示是否重置连接。如果 RST=1,说明 TCP 连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。
  • SYN:在建立连接时使用,用来同步序号。当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1,ACK=1 时,表示对方同意建立连接。SYN=1 时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才为 1。
  • FIN:标记数据是否发送完毕。如果 FIN=1,表示数据已经发送完成,可以释放连接。
  1. 窗口大小(Window Size):占 16 位。它表示从 Ack Number 开始还可以接收多少字节的数据量,也表示当前接收端的接收窗口还有多少剩余空间。该字段可以用于 TCP 的流量控制。
  2. 校验和(TCP Checksum):占 16 位。它用于确认传输的数据是否有损坏。发送端基于数据内容校验生成一个数值,接收端根据接收的数据校验生成一个值。两个值必须相同,才能证明数据是有效的。如果两个值不同,则丢掉这个数据包。Checksum 是根据伪头 + TCP 头 + TCP 数据三部分进行计算的。
  3. 紧急指针(Urgent Pointer):仅当前面的 URG 控制位为 1 时才有意义。它指出本数据段中为紧急数据的字节数,占 16 位。当所有紧急数据处理完后,TCP 就会告诉应用程序恢复到正常操作。即使当前窗口大小为 0,也是可以发送紧急数据的,因为紧急数据无须缓存。
  4. 可选项(Option):长度不定,但长度必须是 32bits 的整数倍。

Tcp中option字段的使用

TCP Options字段的一般数据结构如图所示: image.png

  TCP报文头部选项字段(TCP Options字段)的一般结构选项的第一个字段kind说明选项的类型。有的TCP选项没有后面两个字段,仅包含1字节的kind字段。第二个字段length(如果有的话)指定该选项的总长度,该长度包括kind字段和length字段占据的2字节。第三个字段info(如果有的话)是选项的具体信息。常见的TCP options详见 TCP协议。

常见的TCP options介绍:

  • 第一个kind= 2,表示最大报文段长度(Max Segment Size,MSS),TCP模块通常将MSS设置为(MTU-40)字节(减掉的这40字节包括20字节的TCP头部和20字节的IP头部)。这样携带TCP报文段的IP数据报的长度就不会超过MTU(假设TCP头部和IP头部都不包含选项字段,并且这也是一般情况),从而避免本机发生IP分片。对以太网而言,MSS值是1460(1500-40)字节。而图五中最大报文长度为1320字节,这当然也是可以的。

  • kind= 4,表示支持SACK,详情见链接

  • kind = 8,代表Timestamps,即时间戳,启用Timestamp Option后,每个TCP Segment中都会带有Timestamp Option,其中包含了两个32bit的Timestamp也就是各四个字节的Timestamp Value(TSval)和Timestamp Echo Reply(TSecr)。发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段值复制到时间戳回送回答字段。因此,发送方在收到确认报文后,可以准确计算出RTT。

  • 全部option字段请查阅: 常用的TCP Option

UDP首部格式

image.png

  • 源端口号:表示发送端端口号,字段长16位。该字段是可选项,有时可能不会设置源端口号。没有源端口号的时候该字段的设置为0。可用于不需要返回的通信中。

  • 目标端口号:表示接收端端口,字段长度16位。

  • 包长度:该字段保存了UDP首部的长度跟数据的长度之和。单位为字节。

  • 校验和:校验和是为了提供可靠的UDP首部和数据而设计的。

DNS 报文格式

DNS 分为查询请求和查询响应,请求和响应的报文结构基本相同。DNS 报文格式如图所示: image.png

基础结构部分

DNS 报文的基础结构部分指的是报文首部,如图所示: image.png

该部分中每个字段含义如下。

  • 事务 ID:DNS 报文的 ID 标识。对于请求报文和其对应的应答报文,该字段的值是相同的。通过它可以区分 DNS 应答报文是对哪个请求进行响应的。
  • 标志:DNS 报文中的标志字段。
  • 问题计数:DNS 查询请求的数目。
  • 回答资源记录数:DNS 响应的数目。
  • 权威名称服务器计数:权威名称服务器的数目。
  • 附加资源记录数:额外的记录数目(权威名称服务器对应 IP 地址的数目)。

基础结构部分中的标志字段又分为若干个字段,如图所示。 image.png

标志字段中每个字段的含义如下:

  • QR(Response):查询请求/响应的标志信息。查询请求时,值为 0;响应时,值为 1。
  • Opcode:操作码。其中,0 表示标准查询;1 表示反向查询;2 表示服务器状态请求。
  • AA(Authoritative):授权应答,该字段在响应报文中有效。值为 1 时,表示名称服务器是权威服务器;值为 0 时,表示不是权威服务器。
  • TC(Truncated):表示是否被截断。值为 1 时,表示响应已超过 512 字节并已被截断,只返回前 512 个字节。
  • RD(Recursion Desired):期望递归。该字段能在一个查询中设置,并在响应中返回。该标志告诉名称服务器必须处理这个查询,这种方式被称为一个递归查询。如果该位为 0,且被请求的名称服务器没有一个授权回答,它将返回一个能解答该查询的其他名称服务器列表。这种方式被称为迭代查询。
  • RA(Recursion Available):可用递归。该字段只出现在响应报文中。当值为 1 时,表示服务器支持递归查询。
  • Z:保留字段,在所有的请求和应答报文中,它的值必须为 0。
  • rcode(Reply code):返回码字段,表示响应的差错状态。当值为 0 时,表示没有错误;当值为 1 时,表示报文格式错误(Format error),服务器不能理解请求的报文;当值为 2 时,表示域名服务器失败(Server failure),因为服务器的原因导致没办法处理这个请求;当值为 3 时,表示名字错误(Name Error),只有对授权域名解析服务器有意义,指出解析的域名不存在;当值为 4 时,表示查询类型不支持(Not Implemented),即域名服务器不支持查询类型;当值为 5 时,表示拒绝(Refused),一般是服务器由于设置的策略拒绝给出应答,如服务器不希望对某些请求者给出应答。

问题部分

问题部分指的是报文格式中查询问题区域(Queries)部分。该部分是用来显示 DNS 查询请求的问题,通常只有一个问题。该部分包含正在进行的查询信息,包含查询名(被查询主机名字)、查询类型、查询类。问题部分格式如图所示:

image.png

该部分中每个字段含义如下:

  • 查询名:一般为要查询的域名,有时也会是 IP 地址,用于反向查询。
  • 查询类型:DNS 查询请求的资源类型。通常查询类型为 A 类型,表示由域名获取对应的 IP 地址。
  • 查询类:地址类型,通常为互联网地址,值为 1。

资源记录部分

资源记录部分是指 DNS 报文格式中的最后三个字段,包括回答问题区域字段、权威名称服务器区域字段、附加信息区域字段。这三个字段均采用一种称为资源记录的格式,格式如图所示: image.png

资源记录格式中每个字段含义如下:

  • 域名:DNS 请求的域名。
  • 类型:资源记录的类型,与问题部分中的查询类型值是一样的。
  • :地址类型,与问题部分中的查询类值是一样的。
  • 生存时间:以秒为单位,表示资源记录的生命周期,一般用于当地址解析程序取出资源记录后决定保存及使用缓存数据的时间。它同时也可以表明该资源记录的稳定程度,稳定的信息会被分配一个很大的值。
  • 资源数据长度:资源数据的长度。
  • 资源数据:表示按查询段要求返回的相关资源记录的数据。 详细查阅: DNS报文格式解析(非常详细)