Fork me on GitHub

网络协议之抓包大作战

网络协议之抓包大作战

使用 Wireshark工具抓包,学习网络协议

  1. ping测试 -> 拆解 IPv4、ICMP 协议
  2. Http测试 -> 拆解 TCP、HTTP协议

为避免过早陷入网络协议的细节,建议提前阅读各种协议头部结构体中的插图

1. Ping -> 拆解 IPv4、ICMP 协议

1
2
3
4
5
6
7
8
9
10
11
12
【终端】
// 终端执行 Ping 命令:
lee@localhost  ~  ping baidu.com
PING baidu.com (220.181.57.216): 56 data bytes
64 bytes from 220.181.57.216: icmp_seq=0 ttl=49 time=32.353 ms
64 bytes from 220.181.57.216: icmp_seq=1 ttl=49 time=31.132 ms
64 bytes from 220.181.57.216: icmp_seq=2 ttl=49 time=31.420 ms
64 bytes from 220.181.57.216: icmp_seq=3 ttl=49 time=36.666 ms
^C
--- baidu.com ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 31.132/32.893/36.666/2.225 ms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
【抓包流水】
// 抓包查看分组列表:
// 注:本机 IP:[本机 IP 和谐和谐]
"No.","Time","Source","Destination","Protocol","Length","Info"
"8","6.484284","[本机 IP 和谐和谐]","221.12.33.227","DNS","69","Standard query 0x624f A baidu.com"
"9","6.489842","221.12.33.227","[本机 IP 和谐和谐]","DNS","271","Standard query response 0x624f A baidu.com A 220.181.57.216 ... ..."
"10","6.490159","[本机 IP 和谐和谐]","220.181.57.216","ICMP","98","Echo (ping) request id=0x7853, seq=0/0, ttl=64 (reply in 11)"
"11","6.522460","220.181.57.216","[本机 IP 和谐和谐]","ICMP","98","Echo (ping) reply id=0x7853, seq=0/0, ttl=49 (request in 10)"
"13","7.492527","[本机 IP 和谐和谐]","220.181.57.216","ICMP","98","Echo (ping) request id=0x7853, seq=1/256, ttl=64 (reply in 14)"
"14","7.523576","220.181.57.216","[本机 IP 和谐和谐]","ICMP","98","Echo (ping) reply id=0x7853, seq=1/256, ttl=49 (request in 13)"
"27","8.494129","[本机 IP 和谐和谐]","220.181.57.216","ICMP","98","Echo (ping) request id=0x7853, seq=2/512, ttl=64 (reply in 28)"
"28","8.525455","220.181.57.216","[本机 IP 和谐和谐]","ICMP","98","Echo (ping) reply id=0x7853, seq=2/512, ttl=49 (request in 27)"
"50","9.495770","[本机 IP 和谐和谐]","220.181.57.216","ICMP","98","Echo (ping) request id=0x7853, seq=3/768, ttl=64 (reply in 51)"
"51","9.532351","220.181.57.216","[本机 IP 和谐和谐]","ICMP","98","Echo (ping) reply id=0x7853, seq=3/768, ttl=49 (request in 50)"

分析:

  1. 在 Ping baidu.com 时,首先进行 DNS 查询 IP 地址,
  2. 然后获取到若干个包,都是基于 ICMP 协议 的。
    • ICMP消息是以未确认的IPv4数据报传送的,它们自己也不可靠。
    • 按以太网首部、IPv4、ICMP 顺序拆解,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
【协议详情】
//(以上面的 No.11 ICMP reply 为例)

// 算是信息总览吧(包括 Wireshark 的着色标记等),没有体现在字节上(即不占物理空间)
Frame 10: 98 bytes on wire (784 bits), 98 bytes captured (784 bits) on interface 0
Interface id: 0 (en0)
Interface name: en0
Interface description: Wi-Fi
Encapsulation type: Ethernet (1)
Arrival Time: Apr 5, 2019 18:03:13.866956000 CST
[Time shift for this packet: 0.000000000 seconds]
Epoch Time: 1554458593.866956000 seconds
[Time delta from previous captured frame: 0.000317000 seconds]
[Time delta from previous displayed frame: 0.000317000 seconds]
[Time since reference or first frame: 6.490159000 seconds]
Frame Number: 10
Frame Length: 98 bytes (784 bits)
Capture Length: 98 bytes (784 bits)
[Frame is marked: False]
[Frame is ignored: False]
[Protocols in frame: eth:ethertype:ip:icmp:data] // 说明本数据帧中涉及到的哪些协议
[Coloring Rule Name: ICMP]
[Coloring Rule String: icmp || icmpv6]


// 以太网首部
Ethernet II, Src: Apple_ec:6d:8d ([本机 mac 和谐和谐]), Dst: Cisco_28:dc:80 (10:8c:cf:28:dc:80)
Destination: Cisco_28:dc:80 (10:8c:cf:28:dc:80) // 6个字节,代表目的地 mac 地址
Address: Cisco_28:dc:80 (10:8c:cf:28:dc:80)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
Source: Apple_ec:6d:8d ([本机 mac 和谐和谐]) // 6个字节,代表源 mac 地址
Address: Apple_ec:6d:8d ([本机 mac 和谐和谐])
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
Type: IPv4 (0x0800)


// IPv4 协议 可以参考本站另一篇博客:
[IPv4数据报格式](http://likehui.fun/2018/09/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E7%AC%AC%E5%9B%9B%E7%AB%A0-1/)

Internet Protocol Version 4, Src: [本机 IP 和谐和谐], Dst: 220.181.57.216
0100 .... = Version: 4
.... 0101 = Header Length: 20 bytes (5)
Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) // 服务类型(定义优先级、低延时、高吞吐量等等)
0000 00.. = Differentiated Services Codepoint: Default (0)
.... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
Total Length: 84
Identification: 0xe203 (57859) // 同一个原始数据报的唯一编号(因为分片,多个 IP 报可以归属于同一个原始数据报)
Flags: 0x0000
0... .... .... .... = Reserved bit: Not set // 未投入使用
.0.. .... .... .... = Don't fragment: Not set // 不对数据分片
..0. .... .... .... = More fragments: Not set // 1表示还有分片,0表再无分片
...0 0000 0000 0000 = Fragment offset: 0 // 分片偏移,相对于原始数据报
Time to live: 64 // 经过一个路由器此数字减一,若发现为0,路由器将丢弃此包
Protocol: ICMP (1) // 1表示ICMP,2表示IGMP,6表示TCP,17表示UDP,89表示OSPF
Header checksum: 0xb2f0 [validation disabled]
[Header checksum status: Unverified]
Source: [本机 IP 和谐和谐]
Destination: 220.181.57.216


// ICMP 协议
// Internet Control Message Protocol
Type: 0 (Echo (ping) reply) // 如果是 ping request,此处 Type 是8,占1byte,1~127 差错报文,128 以上信息报文
Code: 0 // 占1byte,它与类型字段一起共同标识了ICMP报文的详细类型
Checksum: 0xdda4 [correct]
[Checksum Status: Good]
Identifier (BE): 30803 (0x7853) // BE、LE wireshark 软件 linux window 系统的做出的标识(区别大端、小端),可以不予理会。
Identifier (LE): 21368 (0x5378)
Sequence number (BE): 0 (0x0000)
Sequence number (LE): 0 (0x0000)
[Request frame: 10]
[Response time: 32.301 ms] // 如果是 ping request,则无此 response time 参数
Timestamp from icmp data: Apr 5, 2019 18:03:13.866927000 CST
[Timestamp from icmp data (relative): 0.032330000 seconds]
Data (48 bytes)
Data: 08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f…
[Length: 48]

2. 访问Http -> 拆解 TCP、HTTP协议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
【抓包流水】
// 访问 http://www.cst.zju.edu.cn/网站
"No.","Time","Source","Destination","Protocol","Length","Info"
"1008","149.200741","[本机 ip 和谐和谐]","210.32.0.218","TCP","78","57206 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=32 TSval=980646922 TSecr=0 SACK_PERM=1"
"1009","149.249935","210.32.0.218","[本机 ip 和谐和谐]","TCP","74","80 → 57206 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=4012697143 TSecr=980646922 WS=128"
"1010","149.250013","[本机 ip 和谐和谐]","210.32.0.218","TCP","66","57206 → 80 [ACK] Seq=1 Ack=1 Win=131744 Len=0 TSval=980646971 TSecr=4012697143"
"1011","149.250191","[本机 ip 和谐和谐]","210.32.0.218","HTTP","468","GET / HTTP/1.1 "
"1013","149.305859","210.32.0.218","[本机 ip 和谐和谐]","TCP","66","80 → 57206 [ACK] Seq=1 Ack=403 Win=15616 Len=0 TSval=4012697199 TSecr=980646971"
"1014","149.371354","210.32.0.218","[本机 ip 和谐和谐]","TCP","1514","80 → 57206 [ACK] Seq=1 Ack=403 Win=15616 Len=1448 TSval=4012697262 TSecr=980646971 [TCP segment of a reassembled PDU]"
"1015","149.371367","210.32.0.218","[本机 ip 和谐和谐]","TCP","1514","80 → 57206 [ACK] Seq=1449 Ack=403 Win=15616 Len=1448 TSval=4012697262 TSecr=980646971 [TCP segment of a reassembled PDU]"
"1016","149.371458","210.32.0.218","[本机 ip 和谐和谐]","TCP","1514","80 → 57206 [ACK] Seq=2897 Ack=403 Win=15616 Len=1448 TSval=4012697262 TSecr=980646971 [TCP segment of a reassembled PDU]"
"1017","149.371524","[本机 ip 和谐和谐]","210.32.0.218","TCP","66","57206 → 80 [ACK] Seq=403 Ack=2897 Win=128864 Len=0 TSval=980647090 TSecr=4012697262"
"1018","149.371568","[本机 ip 和谐和谐]","210.32.0.218","TCP","66","57206 → 80 [ACK] Seq=403 Ack=4345 Win=130816 Len=0 TSval=980647090 TSecr=4012697262"
"1019","149.371969","210.32.0.218","[本机 ip 和谐和谐]","HTTP","950","[TCP Previous segment not captured] Continuation"
"1020","149.372023","[本机 ip 和谐和谐]","210.32.0.218","TCP","78","[TCP Dup ACK 1018#1] 57206 → 80 [ACK] Seq=403 Ack=4345 Win=130816 Len=0 TSval=980647090 TSecr=4012697262 SLE=8689 SRE=9573"
"1021","149.372272","210.32.0.218","[本机 ip 和谐和谐]","TCP","1514","[TCP Out-Of-Order] 80 → 57206 [ACK] Seq=4345 Ack=403 Win=15616 Len=1448 TSval=4012697262 TSecr=980646971"
"1022","149.372278","210.32.0.218","[本机 ip 和谐和谐]","TCP","1514","[TCP Out-Of-Order] 80 → 57206 [ACK] Seq=5793 Ack=403 Win=15616 Len=1448 TSval=4012697262 TSecr=980646971"
"1023","149.372335","[本机 ip 和谐和谐]","210.32.0.218","TCP","78","57206 → 80 [ACK] Seq=403 Ack=5793 Win=129376 Len=0 TSval=980647090 TSecr=4012697262 SLE=8689 SRE=9573"
。。。

按编号分别解释:

  • 1008:Client -> Server三次握手之一
  • 1009:Server -> Client 三次握手之二
  • 1010:Client -> Server 三次握手之三
  • 1011:三次握手结束,Client -> Server 发送 Http 的 Get 请求,从 IP 请求头我们知道此 Http 不分片,此协议见下方代码。
  • 1013:Server -> Client ,回应 Get 请求,即回应 1011。
  • 1014、1015、1016,Server -> Client 发送常规数据,长度都是 1514。
  • 1017:Client -> Server ,Ack 2897,同时回应了1014、1015.
  • 1018:Client -> Server, Ack 4345,作为 1016 的回应。
  • 1019:Server -> Client,但是中途出现丢包(57938689 的数据包丢了),此1019包数据seq为 86899573,缓存在 Client 端的窗口中。
  • 1020:Client -> Server ,重复包,相当于又发了一次1018。
  • 1021:Server -> Client,因为网络问题,导致包抵达时间不同,延时长、包丢失等。这里可以明显看到 Ack=403 有问题,因为 Client 发来的 403 早就到达 Server 了。
  • 1022:Sever -> Client,乱序,理由同上。
  • 1023:Client -> Server,告知需要5793的数据,结合 SLE=8689 SRE=9573 说明:我等你的5793后面的数据,但是 8689~9573 之间的数据我已经缓存了,用不着再发。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
【协议详情】
... 编号1011,即 Http Get 请求,client 发往 server,下面的以太网头和 IPv4 省略

// TCP
Transmission Control Protocol, Src Port: 57206, Dst Port: 80, Seq: 1, Ack: 1, Len: 402
Source Port: 57206 //占 2 bytes
Destination Port: 80 //占 2 bytes
[Stream index: 56]
[TCP Segment Len: 402]
Sequence number: 1 (relative sequence number) //占 4 bytes
[Next sequence number: 403 (relative sequence number)]
Acknowledgment number: 1 (relative ack number) //占 4 bytes
1000 .... = Header Length: 32 bytes (8) // 4 bits,此处的 8 表示长度 32 bytes
Flags: 0x018 (PSH, ACK)
000. .... .... = Reserved: Not set // 保留字符
...0 .... .... = Nonce: Not set // 保留字符
.... 0... .... = Congestion Window Reduced (CWR): Not set // 保留字符,CWR,拥塞窗口减少,接收者如果发现此处为1,可能就会缩小窗口的大小
.... .0.. .... = ECN-Echo: Not set // 保留字符,ECE,若被设置为1,在路由过程中,可能被不支持 ECN router 给丢掉了
.... ..0. .... = Urgent: Not set // 紧急标志,此报文时紧急报文优先发送,不再按序发送。激活紧急指针,与后面的紧急指针(Urgent pointer)配合,向后偏移至此报文处,发送此报文。
.... ...1 .... = Acknowledgment: Set // 确认标志
.... .... 1... = Push: Set // 推,表示发送方通知接收方传输层应该尽快的将这个报文段交给应用层,而不是等缓冲区满了才交付。
.... .... .0.. = Reset: Not set // 重置连接
.... .... ..0. = Syn: Not set // 同步标志
.... .... ...0 = Fin: Not set // 完成标志
[TCP Flags: ·······AP···]
Window size value: 4117 // 2 bytes
[Calculated window size: 131744]
[Window size scaling factor: 32]
Checksum: 0x2eb2 [unverified] // 2 bytes
[Checksum Status: Unverified]
Urgent pointer: 0 // 2 bytes
Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
TCP Option - No-Operation (NOP) // 0. 代表选项表结束; 1.代表无操作; 2.代表MSS; 3.代表窗口扩大因子; 8.代表时间戳
Kind: No-Operation (1)
TCP Option - No-Operation (NOP)
Kind: No-Operation (1)
TCP Option - Timestamps: TSval 980646971, TSecr 4012697143
Kind: Time Stamp Option (8)
Length: 10
Timestamp value: 980646971
Timestamp echo reply: 4012697143
[SEQ/ACK analysis] // 相当于wireshark 的状态解读,不占物理空间
[iRTT: 0.049272000 seconds]
[Bytes in flight: 402]
[Bytes sent since last PSH flag: 402]
[Timestamps]
[Time since first frame in this TCP stream: 0.049450000 seconds]
[Time since previous frame in this TCP stream: 0.000178000 seconds]
TCP payload (402 bytes)

// HTTP
Hypertext Transfer Protocol
GET / HTTP/1.1\r\n
[Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
[GET / HTTP/1.1\r\n]
[Severity level: Chat]
[Group: Sequence]
Request Method: GET
Request URI: /
Request Version: HTTP/1.1
Host: www.cst.zju.edu.cn\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: [本机信息 和谐和谐]
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: en,zh-CN;q=0.9,zh;q=0.8\r\n
\r\n
[Full request URI: http://www.cst.zju.edu.cn/]
[HTTP request 1/8]
[Next request in frame: 1028]

推荐阅读:聊一聊TCP协议中的push标志位
Wireshark 抓包工具–TCP 数据包解读

  • 由于 SYN包是用来初始化连接的, 它不可能和 FIN和RST标记一起出现。

  • 为什么正常包的长度是1514?

    1. 首先最大帧的长度应该是1526字节,1526 bytes = 前同步码(7 bytes)+ 帧开始定界符(1 byte)+ MTU + FCS(4 bytes) 。
    2. 但是抓包拿到的包是已经去掉了前导同步码和帧开始定界符,已经经过CRC 验证后的了,所以只能拿到1514字节。
    3. 1514 bytes = 源 mac (6 bytes)+ 目的 mac (6 bytes) + 长度 (2 bytes) + MTU (1500 bytes)
    4. MTU 是最大传输单元,MTU = IP 头(20 Bytes)+ Data。
    5. 以1015包为例,Data 占1448bytes,TCP 头部32bytes,IP 头部20bytes,汇总就是1500字节。

参考解答:MTU问题,为何抓包到1514

超 np 的 TCP 协议解读:TCP协议解析

-------------The End-------------