Linux 网络协议栈开发基础篇(十三)——TCP/IP协议各报文头格式

Posted zqixiao_09

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 网络协议栈开发基础篇(十三)——TCP/IP协议各报文头格式相关的知识,希望对你有一定的参考价值。

一、TCP报文

       TCPTCP/IP体系中面向连接的运输层协议,提供全双工的和可靠交付的服务。TCP报文段的格式如下图所示



源端口和目的端口:各占2个字节,是运输层与应用层的服务接口。

序号:4个字节。TCP连接传送的数据流中的每一个字节都被编上一个序号。首部中序号字段的值指的是本报文段所发送的数据的第一个字节的序号

确认号:占4个字节,是期望收到对方下一个报文段的数据的第一个字节的序号

数据偏移:占4 bit,它指出报文段的数据起始处距离TCP报文段的起始处有多远。实际上就是TCP报文段首部的长度

保留:占6 bit,保留为今后使用。

紧急比特URG:当URG=1时,表明紧急指针有效。它告诉系统报文段中有紧急数据,应尽快传送。

确认比特ACKACK=1时确认号字段才有效,ACK=0时确认号字段无效

推送比特PUSH:接收方接收到PUSH=1的报文段时会尽快的将其交付给接收应用进程,而不再等到整个接收缓存都填满后再向上交付。

复位比特RST:当RST=1时,表明TCP连接中出现严重差错,必须释放连接。复位比特还用来拒绝一个非法的报文段或拒绝打开一个连接。

同步比特SYN:在连接建立时用来同步序号。SYN=1ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,应在响应的报文段中使SYN=1ACK=1。因此,SYN=1就表示这是一个连接请求或连接接收报文

终止比特FIN:当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。

窗口:占2个字节,用来控制对方发送的数据量,单位是字节,指明对方发送窗口的上限。

校验和:占2个字节,校验的范围包括首部和数据两个部分,计算校验和时需要在报文段前加上12字节的伪首部。

紧急指针:占2个字节,指出本报文段中紧急数据最后一个字节的序号。只有当紧急比特URG=1时才有效。

选项:长度可变。TCP只规定了一种选项,即最大报文段长度MSS (Maximum Segment Size)

TCP连接建立的过程:

三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:


第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。


二、UDP报文

     UDP是一种不可靠的、无连接的数据报服务。源主机在传送数据前不需要和目标主机建立连接。数据被冠以源、目标端口号等UDP报头字段后直接发往目的主机。这时,每个数据段的可靠性依靠上层协议来保证。在传送数据较少、较小的情况下,UDP比TCP更加高效。


●源、目标端口号字段:占16比特。作用与TCP数据段中的端口号字段相同,用来标识源端和目标端的应用进程。

●长度字段:占16比特。标明UDP头部和UDP数据的总长度字节。

●校验和字段:占16比特。用来对UDP头部和UDP数据进行校验。和TCP不同的是,对UDP来说,此字段是可选项,而TCP数据段中的校验和字段是必须有的。


三、IP报文

     IP报文是在网络层传输的数据单元,也叫IP数据报。IP报文格式如下图

版本:IP协议的版本,目前的IP协议版本号为4,下一代IP协议版本号为6。

首部长度:IP报头的长度。固定部分的长度(20字节)和可变部分的长度之和。共占4位。最大为1111,即10进制的15,代表IP报头的最大长度可以为15个32bits(4字节),也就是最长可为15*4=60字节,除去固定部分的长度20字节,可变部分的长度最大为40字节。

服务类型:Type Of Service。

总长度:IP报文的总长度。报头的长度和数据部分的长度之和。

标识:唯一的标识主机发送的每一分数据报。通常每发送一个报文,它的值加一。当IP报文长度超过传输网络的MTU(最大传输单元)时必须分片,这个标识字段的值被复制到所有数据分片的标识字段中,使得这些分片在达到最终目的地时可以依照标识字段的内容重新组成原先的数据

标志:共3位。R、DF、MF三位。目前只有后两位有效,DF位:为1表示不分片,为0表示分片。MF:为1表示“更多的片”,为0表示这是最后一片。

片位移:本分片在原先数据报文中相对首位的偏移位。(需要再乘以8)

生存时间:IP报文所允许通过的路由器的最大数量。每经过一个路由器,TTL减1,当为0时,路由器将该数据报丢弃。TTL 字段是由发送端初始设置一个 8 bit字段.推荐的初始值由分配数字 RFC 指定,当前值为 64。发送 ICMP 回显应答时经常把 TTL 设为最大值 255

协议:指出IP报文携带的数据使用的是那种协议,以便目的主机的IP层能知道要将数据报上交到哪个进程(不同的协议有专门不同的进程处理)。和端口号类似,此处采用协议号,TCP的协议号为6,UDP的协议号为17。ICMP的协议号为1,IGMP的协议号为2.

首部校验和:计算IP头部的校验和,检查IP报头的完整性。

源IP地址:标识IP数据报的源端设备。

目的IP地址:标识IP数据报的目的地址。


四、ICMP报文

     ICMP(Internet Control Message Protocol)因特网控制报文协议。它是IPv4协议族中的一个子协议,用于IP主机、路由器之间传递控制消息。控制消息是在网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然不传输用户数据,但是对于用户数据的传递起着重要的作用。 

   ICMP协议与ARP协议不同,ICMP靠IP协议来完成任务,所以ICMP报文中要封装IP头部。它与传输层协议(如TCP和UDP)的目的不同,一般不用来在端系统之间传送数据,不被用户网络程序直接使用,除了像Ping和Tracert这样的诊断程序。

下面报文是回显请求和回显应答报文


1、ICMP消息类型

ICMP报告无法传送的数据报的错误,并帮助对这些错误进行疑难解答。例如,如果IPv4不能讲数据报传送到目标主机,则路由器上的或目标主机上的ICMP会向主机发送一条“无法到达目标”消息。下表为最常见的ICMP消息。

ICMP消息类型 用途说明
回显请求 Ping工具通过发送ICMP回显消息检查特定节点的IPv4连接以排查网络问题。类型值为0
回显应答 节点发送回显答复消息响应ICMP回显消息。类型值为8
重定向 路由器发送“重定向”消息,告诉发送主机到目标IPv4地址更好的路由。类型值为5
源抑制 路由器发送“源结束”消息,告诉发送主机它们的IPv4数据报将被丢弃——因为路由器上发生了拥塞。于是,发送主机将以较低的频度发送数据报。类型值为4
超时 这个消息有两种用途。第一,当超过IP生存期时向发送系统发出错误信息。第二,如果分段的IP数据报没有在某种期限内重新组合,这个消息将通知发送系统。类型值为11
无法到达目标 路由器和目标主机发送“无法到达目标”消息,通知发送主机它们的数据无法传送。类型值为3

其中无法到达目标消息中可以细分为一下几项

无法到达目标消息 说明
不能访问主机 路由器找不到目标的IPv4地址的路由时发送“不能访问主机”消息
无法访问协议 目标IPv4节点无法将IPv4报头中的“协议”字段与当前使用的IPv4客户端协议相匹配时会发送“无法访问协议”消息
无法访问端口 IPv4节点在UDP报头中的“目标端口”字段与使用该UDP端口的应用程序相匹配时发送“无法访问端口”消息
需要分段但设置了DF 当必须分段但发送节点在IPv4报头中设置了“不分段(DF)”标志时,IPv4路由器会发送“需要分段但设置了DF”消息

ICMP协议只是试图报告错误,并对特定的情况提供反馈,但最终并没有使IPv4成为一个可靠的协议。ICMP消息是以未确认的IPv4数据报传送的,它们自己也不可靠。


五、ARP报文

     ARP:地址解析协议(address Resolution protocol,地址解析协议)是将IP地址解析为以太网MAC地址(或称物理地址)的协议。

     在局域网中,当主机或其它网络设备有数据要发送给另一个主机或设备时,它必须知道对方的网络层地址(即I地址IP)但是仅仅有IP地址是不够的,因为IP数据报文必须封装成帧才能通过物理网络发送,因为发送站还必须有接收站的物理地址,所以需要从IP地址到物理地址,所以需要从IP地址到物理地址的映射。ARP就是实现这个功能的协议。


以太网目的地址:接收方设备的硬件地址(48bit,目的地址全为1的特殊地址是广播地址)。

以太网源地址:发送方的硬件地址

帧类型:表示后面数据的类型(其中,0x0806表示后面的数据是属于ARP包的,其他还可能属于IP包)。

硬件类型:表示硬件地址的类型(其中,值为1表示以太网地址,其他还可能表示令牌环地址)。

协议类型:表示要映射的协议地址类型(其中,0x0800表示IP地址,其他还可能是ICMP/IGMP)。

硬件地址长度:指出该报文中硬件地址的长度(ARP报文中,它的值为6)。

协议地址长度:指出该报文中协议地址的长度(ARP报文中,它的值为4)。

op:操作字段,共有4种类型(1.ARP请求,2.ARP应答,3.RARP请求,4.RARP应答)

发送端以太网地址:发送方设备的硬件地址。

发送端IP地址:发送方设备的IP地址。

目的以太网地址:接收方设备的硬件地址。

目的IP地址:接收方设备的IP地址。

以上是关于Linux 网络协议栈开发基础篇(十三)——TCP/IP协议各报文头格式的主要内容,如果未能解决你的问题,请参考以下文章

Linux 网络协议栈开发基础篇—— 使用wireshark分析TCP/IP协议中TCP包头的格式

Linux 网络协议栈开发基础篇—— 使用wireshark分析TCP/IP协议中TCP包头的格式

Linux内核网络协议栈基础精讲

python全栈学习笔记网络基础之网络协议篇

Linux网络协议栈源码分析基础知识

linux基础-TCP/IP协议篇