阅读 137

TCP协议长什么样


  • 1位表示1bit,除去任选字段(选项和数据)共160bit也就是20字节
  • 源端口号和目的端口号用于寻找发端和接收端【源端口+源IP地址+目的端口+目的IP地址唯一确定一个TCP连接】
  • 序号用来标识从TCP发送端向接收端发送的数据字节流,他是32bit的无符号数,到达2的32次方-1后又从0开始
  • 确认序号是上次已成功收到数据字节序号加1【只有ack标识是1时,他才有效】
  • 首部长度标识TCP包首部实际长度,它的单位是32bit【假如数字是6,那么表示头部实际长度是 4字节*6=24字节,由于首部长度只有4bit,最大数为15,因而最多有15*32bit=480bit=60字节】
  • URG置为1表示紧急指针有效
  • ACK置为1表示确认序号有效
  • PSH置为1表示接收方应该尽快将这个报文段交给应用层
  • RST置1表示重建连接
  • SYN置1用来发起连接
  • FIN置1表示发端完成发送任务
  • 窗口大小是TCP用来做流量控制
  • 校验和覆盖TCP的首部和TCP数据,它一定由发端计算存储,收端验证
  • 紧急指针是一个正偏移量,和序号字段中的值相加表示紧急数据最后一个字段的序号
  • 常见可选字段如MSS(Maximim Segment Size 最长报文大小),用来标识本端能接收的最大长度的报文段

真实tcp报文怎么看?

以下报文为TCP建立和终止的报文示例


完整格式如下:

报文序号 报文产生时间(与上次报文的时间间隔) 源地址.端口号 > 目的地址 : 标识 分组序号:确认序号(报文段中字节数) 窗口大小 接收的最大报文长度复制代码

  • svr4.1037 > bsdi.discard 表示源地址的某个端口到目的地址
  • S是SYN标志,表示发起连接 ;F是FIN标志,表示发送端发送完数据;. 表示(SIN,FIN,RST,PSH)这四个标识都是0
  • 1415531521:1415531521(0) 表示分组的序号是1415531521,报文段中的数据字节数为0
  • ack后跟着的数字串是确认序号,它只有首部标识置为1才有用
  • win 4096表示窗口大小
  • <mss 1024>表示发送端能接收的最大报文长度

默认情况下tcpdump输出只显示SYN报文段的完整序号,其它位置显示偏移量


tcpdump怎么用?

常用参数解析

-X :用16进制显示具体内容
-n:显示IP,不转换域名
-s 0:尽可能多的展示内容
-vvv: 展示详细内容
-i eth1:监听eth1网络
tcp :监听协议类型
dst port 8500:8500端口接收的数据
-A:acsii显示内容复制代码

抓取当前机器上的post请求 sudo tcpdump -i eth1 -X -vvv -n -s 0 'tcp dst port 8500 and tcp[(tcp[12]>>2):4] = 0x504f5354'

比如我想获取post请求的原始IP可以用 sudo tcpdump -i eth1 -A -vvv -n -s 0 'tcp dst port 8500 and tcp[(tcp[12]>>2):4] = 0x504f5354' | grep 'X-Forwarded-For'

抓取当前机器上的get请求 sudo tcpdump -i eth1 -X -vvv -n -s 0 'tcp dst port 8500 and tcp[(tcp[12]>>2):4] = 0x47455420'

上面用到的tcp中括号相关内容是指tcp过滤,字节范围表达: proto [ expr : size ] photo表示协议 expr 表示与指定协议开头相关的字节偏移量;如只查看fin包 tcpdump -i <interface> “tcp[tcpflags] & (tcp-fin) !=0”

TCP协议从那些方面保证可靠性的?

  • 应用数据被分割成TCP认为最适合发送的数据块
  • 发送一个报文段(TCP传递给IP信息的单位)后启动定时器,如果无法及时收到确认,重发报文
  • 收到报文后,推迟几分之一秒发送确认
  • 提供首部和校验和,校验和出错不确认收到此报文,引发重发
  • 必要情况TCP会对收到的数据重排序,将正确的顺序交给应用层
  • 接收端会丢弃重复的数据
  • 本身能做流量控制


附录

把书读薄(TCP/IP详解 卷一 第十七章)