以太网/ IPV4/IPV6包头,TCP包头格式回顾
阅读原文时间:2023年07月10日阅读:1

问题:以太网数据包,承载的数据内容大小46~1500字节,是如何来的?

以太网协议规定最小链路层数据包(帧)为64字节,其中以太网首部+尾部共计18字节(源/目的MAC12字节;上层协议号2字节;CRC尾部4字节)

1-1 版本4位:表示版本号,目前最广泛的是IPv4=B0100,相信IPv6=B0110

1-2 头长4位:数据包头部长度。它表示数据包头部包括多少个32位长整型,也就是多少个4字节的数据。无选项则为5(红色部分)。

1-3 服务类型:包括8个二进制位,每个位的意义如下:

过程字段:3位,设置了数据包的重要性,取值越大数据越重要,取值范围为:0(正常)~ 7(网络控制)

延迟字段:1位,取值:0(正常)、1(期特低的延迟)

流量字段:1位,取值:0(正常)、1(期特高的流量)

可靠性字段:1位,取值:0(正常)、1(期特高的可靠性)

成本字段:1位,取值:0(正常)、1(期特最小成本)

保留字段:1位 ,未使用

1-4 总长度16位:当前IP数据包的总长度,单位是字节。当然最大只能是65535,即63KB。

2-1 重组标识16位:发送者发送的包的顺序,依序递增1,如果客户端收到的包乱序了。依据这个排序,例如下图

2-2 标志3位:

第一位:保留字段

  第二位:取值:0(允许数据报分段)、1(数据报不能分段)

  第三位:后面是否有更多分片,取值:0(数据包后面没有包,该包为最后的包)、1(数据包后面有更多的包)

2-3 段偏移量13位:与更多段位组合,帮助接收方组合分段的报文,以字节为单位。

【示例wireshark抓包 标准位+偏移量共计 16位】

3-1 生存时间8位:经常ping命令看到的TTL(Time To Live)就是这个,每经过一个路由器,该值就减一,到零丢弃。

3-2 协议代码8位:表明使用该包裹的上层协议,如TCP=6,ICMP=1,UDP=17等。

【示例TCP】

3-3 IP头检验和16位:是IPv4数据包头部的校验和。

IP首部检验和字段(16位,2字节),只计算IP头部的的所有字段的校验和,它不对首部后面的数据进行计算。

发送方:计算一份数据报的IP头部检验和,则需要首先把此检验和字段置为0。然后对首部中每个16 bit(2字节)进行二进制反码求和(整个首部看成是由一串16 bit的字组成),然后结果存在此检验和字段中。

接受方:当收到一份IP数据报后,对首部中每个16 bit(2字节)进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该为全1。如果结果不是全1(即检验和错误),那么IP就丢弃收到的数据报。但是不生成差错报文,由上层去发现丢失的数据报并进行重传。

4-1 源始地址:32位=4字节,我们常看到的IP是将每个字节用点(.)分开,如此而已。

5-1 目的地址:32位,同上。

6-1 可选选项:主要是给一些特殊的情况使用,往往安全路由会当作攻击而过滤掉,普联(TP_LINK)的TL-ER5110路由就能这么做。

7-1.用户数据。

1-1 版本(Version):版本字段用来表示IP协议的版本,该字段长度为4比特位,对应值为6(0110)。

1-2 流量分类(Traffic Class):流量分类字段用来标识对应IPv6的流量类别,该字段长度为8比特位,类似于IPv4中的ToS(服务类型)字段。

1-3 流标签(Flow Label):流标签字段时IPv6数据报中新增的一个字段,该字段长度为20比特位,可用来标记报文的数据流类型,以便在网络层区分不同的报文。

2-1 有效载荷长度(PayLoad Length):有效载荷长度字段是以字节为单位的标识IPv6数据报中有效载荷部分(包括所有扩展报头部分)的总长度,也就是除了IPv6的基本报头以外的其他部分的总长度,该字段长度为16比特位。

2-2 下一个头部(Next Header) :下一个头部字段用来标识当前报头的下一个头部类型,该字段长度为8比特位。每种扩展报头都有其对应的值。下一个头部字段内定义的扩展报头类型与IPv4中的协议字段值类似,但在IPv6数据报中,紧接着IPv6报头的可能是上层协议头部(当没有扩展报头或者为最后一个扩展报头时才是上层协议头),也可能是IPv6扩展报头。

2-3 跳数限制(Hop Limit):跳数限制于IPv4报文中的TTL字段类似,指定了报文可以有效转发的次数,该字段长度为8比特位。报文每经过一个路由器结点,跳数值就减1,当此字段值减到0时,则直接丢弃该报文。

3+4+5 源地址(Source IP Address):源IP地址字段标识了发送该IPv6报文发送者的IPv6地址,占128位。
6+7+8 目的IP地址(Destination IP Address):目的IP地址字段标识了IPv6报文的接收者的IPv6地址,占128位。

9-N IPv6扩展报头:Pv6扩展报头是跟在IPv6基本报头后面的可选报头。可以有0个,或者多个扩展报头。数据包仅仅需要传送各自数据包所需要的信息,不需要传送用不到的字段。所以可以通过定义新的扩展报头添加到IPv6数据包中来增加新的可选功能。

主要的IPv6扩展报头有一下几类:

逐跳选项头(Hop-by-hop Options Header):传送必须被转发路径中的每一个节点都检验处理的信息。例如,路由器告警和超大包有效载荷选项等。
目的选项头(Destination Options Header):承载特别针对数据包目的地地址的可选信息
路由头(Routing Header):本扩展报头类型值为43,通过列出在到达目的地的路径中数据包所要经过的节点列表来提供源路由选择的功能。
分段头(Fragment Header):本扩展报头类型值为44,用于标识数据报的分段,在IPv4中就有对应的字段。当源节点发送的报文超过传输链路MTU(源节点和目的节点之间传输路径的MTU)时,需要对报文进行分段时使用。
认证头(Authentication Header,AH):本扩展报头类型值为51,该包头由 IPSec 使用用,以提供认证、数据完整性和防重放保护。它还确保基本IPv6 包头中一些字段的保护。该包头在 IPv4 和 IPv6 中是相同的. 通常称之为 IPSec认证包头 (AH)用于IPSec,提供报文验证,完整性检查。
封装安全有效载荷头(Encapsulating Security Payload,ESP):本扩展头类型值为50,用于IPSec,提供报文验证、完整性检查差和加密。

========================================================

1-1 源始端口16位:现在知道为啥TCP端口范围是 0-65535了吧

1-2 目的端口:同上。

2-1 数据序号32位:TCP为发送的每个字节都编一个号码,这里存储当前数据包数据第一个字节的序号。

3-1 确认序号32位:为了安全,TCP告诉接受者希望他下次接到数据包的第一个字节的序号也同时代表自己确认接收到了这个序号-1字节的数据了。

4-1 首部长度4位:类似IP--->表明数据距包头有多少个32位(有几个四个字节)。20个字节,则为5

4-2 保留6位:未使用,应置零。

4-3 紧急比特URG:当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。

4-4 确认比特ACK:只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。参考TCP三次握手

4-5 PSH:表示要求对方在接到数据后立即请求递交给应用程序,而不是缓冲起来直到缓冲区收满为止。一般为1.

4-6 复位比特RST(Reset) :当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。参考TCP三次握手

4-7 同步比特SYN:同步比特SYN置为1,就表示这是一个连接请求或连接接受报文。参考TCP三次握手

4-8 终止比特FIN(FINal):用来释放一个连接。当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。

4-9 窗口字段16位:窗口字段用来控制对方发送的数据量,单位为字节。TCP连接的一端根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方以确定对方的发送窗口的上限。

5-1.包校验和16位,包括首部和数据这两部分。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。校验范围包括TCP头、数据报内容和概念性伪头部。

**概念性伪头部又包括源IP,目的IP,TCP协议号。
**

5-2.紧急指针16位,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号:指向数据报中紧急数据最后一个字节的下一个字节。

6-1.可选选项0~160位,类似IP,是可选选项。

6-2.填充N位,使选项凑足32位(TCP头长度必须是33位(4字节)的倍数,头固定长度为20字节,首部长度字段代表多少个4字节,当无可选项时首部长度字段置为5代表=5*4字节=20)。

7-1.用户数据……

原文链接:https://blog.csdn.net/xiaoting451292510/article/details/102756146

可选项字段的格式

每个选项的开始是1字节的kind字段,说明选项的类型。一个TCP包可以包含多个可选项。

TCP头部选项功能

TCP头部的选项部分是TCP为了适应复杂的网络环境和更好的服务应用层而进行设计 的。TCP选项部分最长可以达到40byte ,再加上TCP选项外的固定的20byte字节部分, TCP的最长头部可达60byteo TCP头部长度可以通过TCP头部中的"数据偏移"位来查看。(值得注意的是TCP偏移量的单位是32位,也就是4byteo而TCP偏移量共占4bit位, 取最大的1111计算也就是十进制的15。15*4byte=60byte #这个也是TCP的首部不超 过60byte的原因。)

大多数的TCP选项部分出现在TCP连接建立阶段,也就是TCP的三次握手数据包中。 当然有些选项也会出现在已经建立连接的session中,不过此种情况较少出现。

TCP选项部分占有的位数必须是8bit的倍数,这也就是说,即使出现我们应用的选项 部分为4bit M旦也必须使用4bit的垫片。这样才符合RFC的要求

  1. 最大报文传输段(Maximum Segment Size —MSS )
  2. 窗口扩大选项(window scaling )
  3. 选择确认选项(Selective Acknowledgements —SACK )
  4. 时间戳选项(timestamps )
  5. NOP

最大报文传输段(Maximum Segment Size —MSS )

MSS是TCP选项中最经常出现,也是最早岀现的选项。MSS选项占4byte。MSS是每一个TCP报文段中数据字段的最大长度,注意:只是数据部分的字段,不包括TCP的头 部。TCP在三次握手中,每一方都会通告其期望收到的MSS ( MSS只出现在SYN数据包中)如果一方不接受另一方的MSS值则定位默认值536byte

MSS值太小或太大都是不合适。太小例如MSS值只有lbyte那么为了传输这lbyte 数据,至少要消耗20字节IP头部+20字节TCP头部二40byte ,这还不包括其二层头部所 需要的开销,显然这种数据传输效率是很低的。MSS过大,导致数据包可以封装很大,那 么在IP传输中分片的可能性就会增大,接受方在处理分片包所消耗的资源和处理时间都会 增大,如果分片在传输中还发生了重传,那么其网络开销也会增大。因此合理的MSS是至 关重要的。MSS的合理值应为保证数据包不分片的最大值。对于以太网MSS可以达到 1460byte.

与MSS相似的在IP层也有f 类似的概念…MTU ( Maximum Transfer Unit )下 图可以清晰翻译MSS与MTU的关系:

MTU = IP头 + TCP头 + MSS

我们知道TCP最大的窗口大小为64Kb ,在早期网络这是够用的,但随着各种复杂 网络的产生,特别是类似卫星通信这种时延和带宽都也交大的通信而产生,需要更大窗口来满足性能和高吞吐率”于是窗口扩大选项便产生了。

我们用下图一些图来说明为什么需要这个选项,和其主要功能:

我们假设Host A—B是一条高速的WAN链路。通信距离较远,延时也由于距离的原因变大。A向B发送大量数据,由于有足够带宽,那么A在很短时间内就可以发送完64Kb 的数据,而由于窗口过小,A只能停止发送,直到B对A发送的数据进行ACK确认。上面我们可以推算,在time 2-3和后面的time 5-6之间A-B是没有实际数据发送的。而大量的时间被浪费在了等待对方回应上。

如果我们改进我们的窗口大小,使之变的更大,如下图:

现在我们把窗口扩大到256kb ,我们看到,由于窗口足够大,A可以发送大量的数据 报,在其还在忙着发送报文的时间内,对A数据的ACK就已经可以返回了。(黄色的部分可以想象成一个个数据包,大量的数据包排长队在网络中传输L这样,A-B的通信就避免 了消耗大量的等待时间。对TCP的性能改善是巨大的。

Windows scaling占3个byte ,其中的f 字节表示移位值So新的窗口值等于TCP 首部的窗口位数从16增大到(16+S L这相当于把窗口值向左移动S位后获得实际的窗口 大小。移位值准许使用的最大值是14相当于窗口最大值增大到65535*2^14也就是1GB。

窗口扩大选项在TCP建立之初进行协商,如果已经实现了窗口扩大,当不再需要其扩大窗口时,发送S=0选项就可以恢复到窗口大小16。

选择确认选项(Selective Acknowledgements —SACK )

我们假设TCP传输中有这种情况岀现:收到的报文无差错,只是未按序列号,中间还缺 少一些序列号,那么能能否只传输缺少的数据,而不重传已经正确到达的数据?这就是选择确认的技术。用下列例子来说明一下:

要传输的数据共5个,分别编号为1,234,5。A-B Host。B作为接受者,发现数据接 收是这样的1 3 5。而中间的2和4没有到达其他都是正确的数据报。那么如果选用SACK , A将只会重传2和4,而不是所有的报文都重传。

SACK选项在TCP建立连接时由SYN数据包中加上〃允许SACK"的置为1来实现。SACK 对原来TCP首部的确认号字段不会产生影响,只是在发生不连续传输中才会使用。

我们知道TCP的数据报文是有字块边界的”例如上面例子,怎么形容丢失的数据包2 呢,我们会以之间的数据包说明,也就是说丢失的数据是有左右边界的。而此边界在 传输中是用TCP序列号来表示的。由于TCP首部选项部分最多只有40字节,而指明一个 边界要用掉4字节(因为TCP序列号是32位,也就是4字节),因此在选项中最多只能指 明4个字节块的边界信息。这是因为4个字块要有8个边界(前后边界\另外还需要2 个功能字节,一个字节用来指明使用SACK选项,另一字节指明这个选项要占多少字节。4* ( 4*2 ) +2=34byte。所以最多只能指出4个字节块边界信息。

一般来说,计算机都是默认支持选择确认的。上面这张图是刚才通过wireshark工具抓取到的接收方给发送方发送的一个tcp确认包,在这个tcp选择确认(SACK)包中,在图1的tcp选项的SACK选项是选择确认(SACK)能保障可靠传输最为重要的依据。所以,这里我们重点关注tcp选项部分,在tcp首部中可以看到确认号为:2336611189,首部长度是32字节,Window size valaue字段是接收方的接收窗口,同于通知发送方将发送窗口大小设置为65520字节。

从该tcp数据包的tcp选项来看这是一个选择确认(SACK)包,也就是说这个确认包只有tcp首部,没有数据部分,Kind:SACK(5)用来表示这是选择确认(SACK),该字段占用一个字节。Length表示tcp选项长度,占用一个字节,左边界和右边界各占用4字节,也就是说这里总共用掉了10字节。

其中left edge表示接收方接收到的数据块中的左边界位置(起始字节),

right edge可以理解为接收方接收到的数据块中的结束位置(右边界),

那么我们可以根据捕获的数据报中的确认号丢失的数据块中的起始字节,也就是要重传的起始字节,再结合接收窗口,左边界和右边界。我们可以推出接收窗口中的已经接收到的数据块,和未接收到的数据块,如下图所示:

从上图中我们可以清晰的看到滑动窗口中的数据分布如上图所示,其中未接收到的字节数据块表示需要重传的数据,那么发送方在进行选择性重传时,会从2336611189字节的位置开始重传。注意:对于已经接收到的字节数据块(2336631881 - 2336693150)是不会被重传的。

如上图所示,现有10个分组数据,第1个分组为1-100,第2个分组为101-200,其他以此类推… 假设发送方发送了这10个分组,然后接收方接收到数据后给发送方发送了一个选择确认(SACK)数据报,其中tcp首部中给出确认号为201,同时tcp选项中携带了8个左/右边界。

  发送方接收到选择确认数据包后,会根据数据包中的tcp首部中的确认号201,从201字节位置开始重传,再根据tcp首部的tcp选项中的选择确认(SACK)选项指明的已经收到的数据块的8个边界,进行选择性重传(201-300),(401-500),(601-700),(801-900)分组(对于已经收到的数据块(301-400),(501-600),(701-800),(901-1000)是不会重传的,因为选择确认(SACK)选项中给出的边界是指明已经接收到的数据块和未接收到的数据块。换句话说,边界就是接收方用来告诉发送方:“哪些数据已经收到,哪些数据没收到”。然后发送方再选择对未收到的数据进行重传)。

时间戳选项(timestamps )

时间戳选项占10个字节,其中最主要的字段时间戳字段(4字节)和时间戳回送回答字段(4字节)

时间戳选项主要的功能有两个:

  • 1 .用来计算往返时间RTT(Round-Trip Time往返时延)。发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段值复制到时间戳回送回答字段。因此,发送方在 收到确认报文后,可以准确计算出RTT。时间戳是一个单调增长的值,接收方只需要回 显收到的内容,因此是不需要关注时间戳的单元是什么,也不需要连接双发的时钟同步。
  • 2 . PAWS:防止回绕的序号。我们知道序列号只有32位,而每增加2^32个序列号后就会重复使用原来用过的序列号。假设我们有F高速网络,通信的主机双方有足够大的带 宽用来快速的传输数据。例如lGb/s的速率发送报文段,则不到35秒钟数据字节的序 列号就会重复。这样对TCP传输带来混乱的情况。这种情况之出现在高速链路上。而采 用时间戳选项”可以很容易的分辨出相同序列号的数据报,哪个是最近发送,哪个是以前发送的。

NOP

NOP ( no operation ),从字面意思也看出来了,这个字段实际上是没有但可意义的字 段。设计该字段主要是用来提供填充垫片。TCP的头部必须是4byte的倍数,但是大多数 的TCP选项不是4byte的倍数。假如出现了整个TCP选项部分不是4byte的倍数,那么就 需要使用1或多个字节无意义的nop来填充,使之符合TCP的头部构造的规定。例如,选 项部分只有6byte , 2个字节的nop就会用来做垫片。

  • NOP也会做为分割不同的选项数据,例如我们的TCP会话中同时使用了窗口扩大选项和 SACK那么TCP头部中的SACK的表示部分与窗口扩大选项中的参数之间使用nop隔离。 明确不同的选项之间的分割点,因此在一个数据包中出现多个nop是不奇怪的。

总结
TCP协议是一个设计可靠的,优越的协议,通过TCP的选项部分也可以看到其设计之 精妙。TCP的选项部分做为TCP头部的补充满足了对复杂网络和苛刻传输条件的要求。TCP 选项在给网络带来性能提升和高可靠的同时”也会被黑客所利用。

例如,每个操作系统都有自己独特的处理TCP选项部分的特点和排序规则。利用这种 系统的特殊性结合其他手段可以很容易的识别出是明哪种操作系统对了解和分析主机漏洞提 供了更多的参数。

======================THE    END==================================