Wireshark & Packetdrill | TCP 基础之三次握手续

admin 2023年11月13日11:48:56评论27 views字数 5670阅读18分54秒阅读模式

学习的乐趣,在于不断探索。




实验目的

再次通过 packetdrill 测试 TCP 基础之三次握手,此次构造模拟的是客户端场景,而之前《TCP 基础之三次握手》中构造模拟的是服务器端。


实验脚本

# cat tcp_3hs_007.pkt // TCP 基础之三次握手0  socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0+0 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
+0 > S 0:0(0) <...>+0.01 < S. 0:0(0) ack 1 win 10000 <mss 1000>+0 > . 1:1(0) ack 1


脚本说明

0  socket(..., SOCK_STREAM, IPPROTO_TCP) = 3// 0 是 创建 socket 的绝对时间。// 创建 socket ,socket(int domain, int type, int protocol)// domain,默认值... ,即 AF_INET 。// type,SOCK_STREAM ,指定这个套接字为面向连接的流式套接字(TCP)。// protocol,IPPROTO_TCP,指定TCP协议。// 3,因为 stdin(0),stdout(1),stderr(2) 默认被定义,内核将会给此 socket 指定文件描述符 FD 为 3。

+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0// +0 本行代码执行时间相对于上一行代码的偏移时间。// fcntl(),针对文件描述符提供控制。// 3,设置的套接字描述符。// F_SETFL,设置文件状态标记。// O_RDWR|O_NONBLOCK,可读可写|非阻塞方式。

+0 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0// +0 本行代码执行时间相对于上一行代码的偏移时间。// setsockopt() 设置套接字选项的系统调用。// 3,设置的套接字描述符。// SOL_TCP,表示要设置的选项位于TCP层面。// TCP_NODELAY,要设置的选项,表示禁用Nagle算法。// [1],表示选项值,1表示启用。// 4,表示选项值的长度,4字节。// 0,设置成功返回0。

+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)// +0 本行代码执行时间相对于上一行代码的偏移时间。// connect(),用来建立连接的系统调用。// 3,绑定的套接字描述符。// ... ,省略的connect()的参数,包括连接的IP地址和端口、以及地址长度。// -1,设置如果没有连接成功,则立即返回 -1。// EINPROGRESS (Operation now in progress),返回错误码是EINPROGRESS,表示正在连接。


+0 > S 0:0(0) <...>// +0 本行代码执行时间相对于上一行代码的偏移时间。// > ,表示预期协议栈会发送的数据包。// 0:0(0) ,表示开始序号:结束序号(数据包长度)。// <> 表示 TCP options,... 表示默认值。

+0.01 < S. 0:0(0) ack 1 win 10000 <mss 1000>// +0.01 本行代码执行时间相对于上一行代码的偏移时间,0.01s = 10ms。// < ,表示输入或注入的数据包。// S. ,表示是 SYN/ACK 数据包。// 0:0(0) ,表示开始序号0:结束序号0(数据包长度0)。// ack 1,表示确认号1,确认了客户端的SYN(seq + 1),因为SYN占1个字节。// win 10000,表示接收窗口10000字节。// <> 表示 TCP options,mss 1000,表示设置mss 1000字节大小。

+0 > . 1:1(0) ack 1// +0 本行代码执行时间相对于上一行代码的偏移时间。// > ,表示预期协议栈会发送的数据包。// . ,表示是 ACK 数据包。// 1:1(0) ,表示开始序号1:结束序号1(数据包长度0),因为SYN占1个字节。// ack 1 ,表示确认号1,确认了服务端的SYN(seq + 1),因为SYN占1个字节。


实验测试

1.执行脚本# packetdrill tcp_3hs_007.pkt # 执行完成后退出。

2.捕获数据包# tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes21:52:17.517087 tun0 Out IP 192.168.204.198.50960 > 192.0.2.1.8080: Flags [S], seq 2970850519, win 64240, options [mss 1460,sackOK,TS val 4210775127 ecr 0,nop,wscale 8], length 021:52:17.617197 ? In IP 192.0.2.1.8080 > 192.168.204.198.50960: Flags [S.], seq 0, ack 2970850520, win 10000, options [mss 1000], length 021:52:17.617210 ? Out IP 192.168.204.198.50960 > 192.0.2.1.8080: Flags [.], ack 1, win 64240, length 021:52:17.617278 ? Out IP 192.168.204.198.50960 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 64240, length 021:52:17.617286 ? In IP 192.0.2.1.8080 > 192.168.204.198.50960: Flags [R.], seq 1, ack 1, win 10000, length 0^C5 packets captured7 packets received by filter0 packets dropped by kernel#


数据包说明

1. TCP三次握手 - SYN21:52:17.517087 tun0  Out IP 192.168.204.198.50960 > 192.0.2.1.8080: Flags [S], seq 2970850519, win 64240, options [mss 1460,sackOK,TS val 4210775127 ecr 0,nop,wscale 8], length 0// 对应于脚本 +0 > S 0:0(0) <...> ,因为 > 表示预期内核协议栈会发送的数据包,所以如果内核协议栈发送的实际数据包与脚本所预期的数据包一致,则脚本正常执行,如果不一致,则脚本会报错停止运行,并指出相关错误。

2. TCP三次握手 - SYN/ACK21:52:17.617197 ? In IP 192.0.2.1.8080 > 192.168.204.198.50960: Flags [S.], seq 0, ack 2970850520, win 10000, options [mss 1000], length 0// 对应于脚本 +0.01 < S. 0:0(0) ack 1 win 10000 <mss 1000> ,与上一行间隔10ms后, < 表示输入数据包,所以 packetdrill 根据此行脚本各字段值构造的 SYN/ACK 数据包,注入到内核协议栈。

3. TCP三次握手 - ACK21:52:17.617210 ? Out IP 192.168.204.198.50960 > 192.0.2.1.8080: Flags [.], ack 1, win 64240, length 0// 对应于脚本 +0 > . 1:1(0) ack 1 ,> 表示预期内核协议栈会立即响应发送的 ACK 数据包。

4. FIN/ACK 和 RST/ACK21:52:17.617278 ? Out IP 192.168.204.198.50960 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 64240, length 021:52:17.617286 ? In IP 192.0.2.1.8080 > 192.168.204.198.50960: Flags [R.], seq 1, ack 1, win 10000, length 0// packetdrill 脚本之外产生的数据包,或者说预期之外的数据包。// 因为未具体研究 packetdrill 代码,仅根据个人判断,在 packetdrill 脚本执行完毕后,socket 被强行关闭,客户端内核会发送 FIN/ACK 结束连接.// 而最后一个服务器所发送的 RST/ACK 结束连接,也像是 packetdrill 脚本默认构造,用于快速重置连接使用的。// 因此这两个数据包一般与 packetdrill 构建的测试脚本无关,分析时可省略。


扩展测试

# cat tcp_3hs_008.pkt ...+0 `sleep 1000000`
脚本最后增加 sleep 语句,使得脚本执行完不要退出。

测试结果# packetdrill tcp_3hs_008.pkt
脚本执行完后未退出,可见光标闪烁。
# ss -anto | grep 8080ESTAB 0 0 192.168.98.82:33248 192.0.2.1:8080 # 通过 ss 查询 TCP 连接建立状态。
# ip a...276: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500 link/none inet 192.168.98.82/16 scope global tun0 valid_lft forever preferred_lft forever inet6 fe80::a716:b21b:711e:e4dd/64 scope link stable-privacy valid_lft forever preferred_lft forever# ip a 查询可见多了一个虚拟的网卡tun0,这也是packetdrill实现的基本原理,可自行查询相关介绍文章。

抓包结果# tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes22:02:31.277055 tun0 Out IP 192.168.98.82.33248 > 192.0.2.1.8080: Flags [S], seq 715879434, win 64240, options [mss 1460,sackOK,TS val 2853458540 ecr 0,nop,wscale 8], length 022:02:31.377167 tun0 In IP 192.0.2.1.8080 > 192.168.98.82.33248: Flags [S.], seq 0, ack 715879435, win 10000, options [mss 1000], length 022:02:31.377181 tun0 Out IP 192.168.98.82.33248 > 192.0.2.1.8080: Flags [.], ack 1, win 64240, length 0


Sleep 有无的情况下,数据包方面稍微的区别:在无 sleep 语句的情况下,脚本执行完成后就正常退出,通过抓包结果,除了 TCP 三次握手数据包,最后会默认出现客户端发的一个 FIN/ACK 和服务器端发的一个 RST/ACK 。在有 sleep 语句的情况下,脚本执行完成后并不退出,因此抓包结果仅有 TCP 三次握手数据包。
而在有 sleep 语句的脚本执行后,通过 CTRL+C 可终止脚本运行,如下:# packetdrill tcp_3hs_008.pkt ^Ctcp_3hs_008.pkt:11: error executing `sleep 1000000` command: got signal 2 (Interrupt)#
此时 ip a 查询,已无 tun0 网卡,通过 ss 查询 TCP 连接状态已经变成 FIN-WAIT-1# ss -anto | grep 8080FIN-WAIT-1 0 1 192.168.98.82:33248 192.0.2.1:8080 timer:(on,2.048ms,3)#
抓包结果如下,仅出现一个客户端发送的 FIN 数据包,与上面的 TCP 连接 FIN-WAIT-1 对应。22:06:40.327485 ? Out IP 192.168.98.82.33248 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 64240, length 0



Wireshark & Packetdrill | TCP 基础之三次握手续


往期推荐


1. Wireshark 提示和技巧 | 捕获点之 TCP 三次握手

2. Wireshark 提示和技巧 | a == ${a} 显示过滤宏

3. Wireshark TS | 防火墙空闲会话超时问题

4. Wireshark TS | HTTP 传输文件慢问题

5. 网络设备 MTU MSS Jumboframe 全解



后台回复「TT」获取 Wireshark 提示和技巧系列 合集
后台回复「TS」获取 Wireshark Troubleshooting 系列 合集
如需交流,可后台直接留言,我会在第一时间回复,谢谢!
Wireshark & Packetdrill | TCP 基础之三次握手续

原文始发于微信公众号(Echo Reply):Wireshark & Packetdrill | TCP 基础之三次握手续

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年11月13日11:48:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Wireshark & Packetdrill | TCP 基础之三次握手续https://cn-sec.com/archives/2200468.html

发表评论

匿名网友 填写信息