美文网首页通信协议Network
使用TCPDUMP研究TCP头部结构

使用TCPDUMP研究TCP头部结构

作者: awker | 来源:发表于2019-06-11 16:17 被阅读0次

    《Linux高性能服务器编程》读书笔记

    为了理解TCP头部中每个字段的定义,从10.31.90.106执行telnet命令,并用tcpdump抓取这个过程中telnet客户端和telnet服务器程序之间交换的数据包。
    一、执行tcpdump抓包
    # tcpdump -ntx -i lo

    二、在另一个终端输入telnet命令查询

    # telnet 127.0.0.1
    Trying 127.0.0.1...
    telnet: connect to address 127.0.0.1: Connection refused
    

    三、查看tcpdump抓到的包(开启了-x选项,使之输出数据包的二进制码)

    # tcpdump -ntx -i lo
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
    IP 127.0.0.1.57777 > 127.0.0.1.telnet: Flags [S], seq 3611485706, win 32792, options [mss 16396,sackOK,TS val 1023622707 ecr 0,nop,wscale 7], length 0
     0x0000:  4510 003c d839 4000 4006 6470 7f00 0001
     0x0010:  7f00 0001  e1b1 0017 d742 e60a 0000 0000
     0x0020:  a002 8018 7540 0000 0204 400c 0402 080a
     0x0030:  3d03 3e33 0000 0000 0103 0307
    IP 127.0.0.1.telnet > 127.0.0.1.57777: Flags [R.], seq 0, ack 3611485707, win 0, length 0
     0x0000:  4510 0028 0000 4000 4006 3cbe 7f00 0001
     0x0010:  7f00 0001 0017 e1b1 0000 0000 d742 e60b
     0x0020:  5014 0000 12b7 0000
    

    四、分析TCP包头(数据包共包含60字节,其中前20字节是IP头部,后40字节是TCP头部,不包含应用程序数据(length值为0))

    1. Flags [S],表示该TCP报文段包含SYN标志,因此它是一个同步报文段。(SYN ACK FIN RST PSH URG)
    2. seq 3611485706,从127.0.0.1.57777 > 127.0.0.1.telnet这个方向上的第一个TCP报文段,所以这个序号值也就是此次通信过程中该传输方向的ISN值。
    3. win 32792,win是接收通告窗口的大小。因为这是一个同步报文段,所以win值反映的是实际的接收通告窗口大小。?
    4. options,options是TCP选项,其具体内容列在方括号中。
    5. mss 16396,是发送端(客户端)通告的最大报文段长度。(通过ifconfig命令查看lo接口的MTU为16436字节,所以TCP报文段的MSS为16396(16436字节的MTU-20字节的IP头-20字节TCP头部)字节)
    6. sackOK,表示发送端支持并同意使用SACK选项。
    7. TS val 1023622707,是发送端的时间戳
    8. ecr 0,是时间戳回显应答(因为这是一次TCP通信的第一个TCP报文段,所以它针对对方的时间戳的应答为0(尚未收到对方的时间戳)
    9. nop,空操作选项
    10. wscale 7,发送端使用的窗口扩大因子为7
    11. length 0,表示数据部分长度为0字节
    12. TCP头部,从 0xe1b10x0307(前20字节是IP头部,0x4510 到 0x0001)
     0x0010:  7f00 0001  e1b1 0017 d742 e60a 0000 0000
     0x0020:  a002 8018 7540 0000 0204 400c 0402 080a
     0x0030:  3d03 3e33 0000 0000 0103 0307
    
    十六进制数 二进制表示 十进制表示 TCP头部信息
    0xe1b1 01110000110110000 57777 源端口号
    0x0017 00010111 23 目的源口号
    0xd742e60a 3611485706 序号
    0x00000000 0 确认号
    0xa 00000100 10 TCP头部长度为10个32位(40字节)
    0x002 00000002 设置了SYN标志
    0x8018 32792 接收窗口大小
    0x7540 30016 头部校验和
    0x0000 没设置URG标志,所以紧急指针值无意义
    0x0204 0x02-->2,0x04-->4 最大报文段长度选项的kind值和length值(kind=2,length=4)
    0x400c 16396 最大报文段长度(Maximum segment size)
    0x0402 0x04-->4,0x02-->2 允许SACK选项(kind=4,length=2)
    0x080a 0x08-->8,0x0a-->10 时间戳选项的kind值和length值(kind=8,length=10)
    0x3d033e33 1023622707 时间戳
    0x00000000 0 回显应答时间戳
    0x01 0x01-->1 空操作选项(nop,kind=1)
    0x0303 0x03-->3,0x03-->3 窗口扩大因子选项的kind值和length值(kind=3,kind=3)
    0x07 7 窗口扩大因子为7

    对比下图,说明TCP头部结构


    • 16位端口号(port number):告知主机该报文段是来自哪里(源端口)以及传给哪个上层协议或应用程序(目的端口)的。进行TCP通信时,客户端通常使用系统自动选择的临时端口号,而服务器则使用知名服务端口号。所有知名服务使用的端口号都定义在/etc/services文件中。

    • 32位序号(sequence number):一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。假设主机A和主机B进行TCP通信,A发送给B的第一个TCP报文段中,序号值被系统初始化为某个随机值ISN(Initial Sequence Number,初始序号值)。那么在该传输方向上(从A到B),后续的TCP报文段中序号值将被系统设置成ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如,某个TCP报文段传送的数据是字节流中的第1025~2048字节,那么该报文段的序号值就是ISN+1025。另外一个传输方向(从B到A)的TCP报文段的序号值也具有相同的含义。

    • 32位确认号(acknowledgement number):用作对另一方发送来的TCP报文段的响应。其值是收到的TCP报文段的序号值加1。假设主机A和主机B进行TCP通信,那么A发送出的TCP报文段不仅携带自己的序号,而且包含对B发送来的TCP报文段的确认号。反之,B发送出的TCP报文段也同时携带自己的序号和对A发送来的报文段的确认号。

    • 4位头部长度(header length):标识该TCP头部有多少个32bit字(4字节)。因为4位最大能表示15,所以TCP头部最长是60字节。

    • 6位标志位包含如下几项:

      • URG标志,表示紧急指针(urgent pointer)是否有效。
      • ACK标志,表示确认号是否有效。我们称携带ACK标志的TCP报文段为确认报文段。
      • PSH标志,提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间(如果应用程序不将接收到的数据读走,它们就会一直停留在TCP接收缓冲区中)。
      • RST标志,表示要求对方重新建立连接。我们称携带RST标志的TCP报文段为复位报文段。
      • SYN标志,表示请求建立一个连接。我们称携带SYN标志的TCP报文段为同步报文段。
      • FIN标志,表示通知对方本端要关闭连接了。我们称携带FIN标志的TCP报文段为结束报文段。
    • 16位窗口大小(window size):是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。

    • 16位校验和(TCP checksum):由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。

    • 16位紧急指针(urgent pointer):是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。我们将在后面讨论TCP紧急数据。

    • TCP头部的最后一个选项字段(options)是可变长的可选信息。这部分最多包含40字节,因为TCP头部最长是60字节(其中还包含前面讨论的20字节的固定部分)。典型的TCP头部选项结构如图所示。



      选项的第一个字段kind说明选项的类型。有的TCP选项没有后面两个字段,仅包含1字节的kind字段。第二个字段length(如果有的话)指定该选项的总长度,该长度包括kind字段和length字段占据的2字节。第三个字段info(如果有的话)是选项的具体信息。常见的TCP选项有7种,如图所示。


    • kind=0是选项表结束选项。

    • kind=1是空操作(nop)选项,没有特殊含义,一般用于将TCP选项的总长度填充为4字节的整数倍。

    • kind=2是最大报文段长度选项。TCP连接初始化时,通信双方使用该选项来协商最大报文段长度(Max Segment Size,MSS)。TCP模块通常将MSS设置为(MTU-40)字节(减掉的这40字节包括20字节的TCP头部和20字节的IP头部)。这样携带TCP报文段的IP数据报的长度就不会超过MTU(假设TCP头部和IP头部都不包含选项字段,并且这也是一般情况),从而避免本机发生IP分片。对以太网而言,MSS值是1460(1500-40)字节。

    • kind=3是窗口扩大因子选项。TCP连接初始化时,通信双方使用该选项来协商接收通告窗口的扩大因子。在TCP的头部中,接收通告窗口大小是用16位表示的,故最大为65?535字节,但实际上TCP模块允许的接收通告窗口大小远不止这个数(为了提高TCP通信的吞吐量)。窗口扩大因子解决了这个问题。假设TCP头部中的接收通告窗口大小是N,窗口扩大因子(移位数)是M,那么TCP报文段的实际接收通告窗口大小是N乘2M,或者说N左移M位。注意,M的取值范围是0~14。我们可以通过修改/proc/sys/net/ipv4/tcp_window_scaling内核变量来启用或关闭窗口扩大因子选项。
      和MSS选项一样,窗口扩大因子选项只能出现在同步报文段中,否则将被忽略。但同步报文段本身不执行窗口扩大操作,即同步报文段头部的接收通告窗口大小就是该TCP报文段的实际接收通告窗口大小。当连接建立好之后,每个数据传输方向的窗口扩大因子就固定不变了。关于窗口扩大因子选项的细节,可参考标准文档RFC 1323。

    • kind=4是选择性确认(Selective Acknowledgment,SACK)选项。TCP通信时,如果某个TCP报文段丢失,则TCP模块会重传最后被确认的TCP报文段后续的所有报文段,这样原先已经正确传输的TCP报文段也可能重复发送,从而降低了TCP性能。SACK技术正是为改善这种情况而产生的,它使TCP模块只重新发送丢失的TCP报文段,不用发送所有未被确认的TCP报文段。选择性确认选项用在连接初始化时,表示是否支持SACK技术。我们可以通过修改/proc/sys/net/ipv4/tcp_sack内核变量来启用或关闭选择性确认选项。

    • kind=5是SACK实际工作的选项。该选项的参数告诉发送方本端已经收到并缓存的不连续的数据块,从而让发送端可以据此检查并重发丢失的数据块。每个块边沿(edge of block)参数包含一个4字节的序号。其中块左边沿表示不连续块的第一个数据的序号,而块右边沿则表示不连续块的最后一个数据的序号的下一个序号。这样一对参数(块左边沿和块右边沿)之间的数据是没有收到的。因为一个块信息占用8字节,所以TCP头部选项中实际上最多可以包含4个这样的不连续数据块(考虑选项类型和长度占用的2字节)。

    • kind=8是时间戳选项。该选项提供了较为准确的计算通信双方之间的回路时间(Round Trip Time,RTT)的方法,从而为TCP流量控制提供重要信息。我们可以通过修改/proc/sys/net/ipv4/tcp_timestamps内核变量来启用或关闭时间戳选项。

    相关文章

      网友评论

        本文标题:使用TCPDUMP研究TCP头部结构

        本文链接:https://www.haomeiwen.com/subject/dfuqfctx.html