|
10.0.3.246.56894 > 192.168.0.92.22: Flags [S], cksum 0xcf28 (incorrect -> 0x0388), seq 682725222, win 29200, options [mss 1460,sackOK,TS val 619989005 ecr 0,nop,wscale 7], length 0
|
从上面的例子,我们可以判断这个数据包是一个 SYN 数据包。我们是通过 tcpdump 输出中的 [S] 标记字段得出这个结论,不同类型的数据包有不同类型的标记。不需要深入了解 TCP 协议中的数据包类型,你就可以通过下面的速查表来加以判断。
-
[S] – SYN (开始连接)
-
[.] – 没有标记
-
[P] – PSH (数据推送)
-
[F] – FIN (结束连接)
-
[R] – RST (重启连接)
在这个版本的 tcpdump 输出中,[S.] 标记代表这个数据包是 SYN-ACK 数据包。
16.不好的例子
15:15:43.323412 IP (tos 0x0, ttl 64, id 51051, offset 0, flags [DF], proto TCP (6), length 60)
10.0.3.246.56894 > 192.168.0.92.22: Flags [S], cksum 0xcf28 (incorrect -> 0x0388), seq 682725222, win 29200, options [mss 1460,sackOK,TS val 619989005 ecr 0,nop,wscale 7], length 0
15:15:44.321444 IP (tos 0x0, ttl 64, id 51052, offset 0, flags [DF], proto TCP (6), length 60)
10.0.3.246.56894 > 192.168.0.92.22: Flags [S], cksum 0xcf28 (incorrect -> 0x028e), seq 682725222, win 29200, options [mss 1460,sackOK,TS val 619989255 ecr 0,nop,wscale 7], length 0
15:15:46.321610 IP (tos 0x0, ttl 64, id 51053, offset 0, flags [DF], proto TCP (6), length 60)
10.0.3.246.56894 > 192.168.0.92.22: Flags [S], cksum 0xcf28 (incorrect -> 0x009a), seq 682725222, win 29200, options [mss 1460,sackOK,TS val 619989755 ecr 0,nop,wscale 7], length 0
上面显示了一个不好的通信例子,在这个例子中“不好”,代表通信没有建立起来。我们可以看到 10.0.3.246 发出一个 SYN 数据包给 主机 192.168.0.92,但是主机并没有应答。
17.好的例子
15:18:25.716453 IP (tos 0x10, ttl 64, id 53344, offset 0, flags [DF], proto TCP (6), length 60)
10.0.3.246.34908 > 192.168.0.110.22: Flags [S], cksum 0xcf3a (incorrect -> 0xc838), seq 1943877315, win 29200, options [mss 1460,sackOK,TS val 620029603 ecr 0,nop,wscale 7], length 0
15:18:25.716777 IP (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 60)
192.168.0.110.22 > 10.0.3.246.34908: Flags [S.], cksum 0x594a (correct), seq 4001145915, ack 1943877316, win 5792, options [mss 1460,sackOK,TS val 18495104 ecr 620029603,nop,wscale 2], length 0
15:18:25.716899 IP (tos 0x10, ttl 64, id 53345, offset 0, flags [DF], proto TCP (6), length 52)
10.0.3.246.34908 > 192.168.0.110.22: Flags [.], cksum 0xcf32 (incorrect -> 0x9dcc), ack 1, win 229, options [nop,nop,TS val 620029603 ecr 18495104], length 0
好的例子应该向上面这样,我们看到典型的 TCP 3次握手。第一数据包是 SYN 包,从主机 10.0.3.246 发送给 主机192.168.0.110,第二个包是 SYN-ACK 包,主机192.168.0.110 回应 SYN 包。最后一个包是一个 ACK 或者 SYN – ACK – ACK 包,是主机 10.0.3.246 回应收到了 SYN – ACK 包。从上面看到一个 TCP/IP 连接成功建立。
=======================================================================
数据包检查
18.用十六进制和 ASCII 码打印数据包
tcpdump -nvvv -i any -c 1 -XX 'port 80 and host 10.0.3.1'
排查应用程序网络问题的通常做法,就是用 tcpdump 的 -XX 标记打印出 16 进制和 ASCII 码格式的数据包。这是一个相当有用的命令,它可以让你看到源地址,目的地址,数据包类型以及数据包本身。但我不是这个命令输出的粉丝,我认为它太难读了。
19.只打印 ASCII 码格式的数据包
tcpdump -nvvv -i any -c 1 -A 'port 80 and host 10.0.3.1'
我倾向于只打印 ASCII 格式数据,这可以帮助我快速定位数据包中发送了什么,哪些是正确的,哪些是错误的。你可以通过 -A 标记来实现这一点。
tcpdump -nvvv -i any -c 1 -A 'port 80 and host 10.0.3.1'
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
19:59:52.011337 IP (tos 0x0, ttl 64, id 53757, offset 0, flags [DF], proto TCP (6), length 406)
10.0.3.1.46172 > 10.0.3.246.80: Flags [P.], cksum 0x1c7f (incorrect -> 0xead1), seq 1552520173:1552520527, ack 428165415, win 237, options [nop,nop,TS val 624251177 ecr 624247749], length 354
...
....\.P\.....I'...........
%5Q)%5C.GET /newpage HTTP/1.1
Host: 10.0.3.246
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
从上面的输出,你可以看到我们成功获取了一个 http 的 GET 请求包。如果网络通信没有被加密,用人类可阅读的格式打出包中数据,对于解决应用程序的问题是很有帮助。如果你排查一个网络通信被加密的问题,打印包中数据就不是很有用。不过如果你有证书的话,你还是可以使用 ssldump 或者 。
===================================================================
非 TCP 数据流
虽然这篇文章主要采用 TCP 传输来讲解 tcpdump ,但是 tcpdump 绝对不是只能抓 TCP 数据包。它还可以用来获取其他类型的数据包,例如 ICMP、 UDP 和 ARP 包。下面是一些简单的例子,说明 tcpdump 可以截获非 TCP 数据包。
20.ICMP 数据包
tcpdump -nvvv -i any -c 2 icmp
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
20:11:24.627824 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84)
10.0.3.169 > 10.0.3.246: ICMP echo request, id 15683, seq 1, length 64
20:11:24.627926 IP (tos 0x0, ttl 64, id 31312, offset 0, flags [none], proto ICMP (1), length 84)
10.0.3.246 > 10.0.3.169: ICMP echo reply, id 15683, seq 1, length 64
21.UDP 数据包
tcpdump -nvvv -i any -c 2 udp
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
20:12:41.726355 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 76)
10.0.3.246.123 > 198.55.111.50.123: [bad udp cksum 0x43a9 -> 0x7043!] NTPv4, length 48
Client, Leap indicator: clock unsynchronized (192), Stratum 2 (secondary reference), poll 6 (64s), precision -22
Root Delay: 0.085678, Root dispersion: 57.141830, Reference-ID: 199.102.46.75
Reference Timestamp: 3622133515.811991035 (2014/10/12 20:11:55)
Originator Timestamp: 3622133553.828614115 (2014/10/12 20:12:33)
Receive Timestamp: 3622133496.748308420 (2014/10/12 20:11:36)
Transmit Timestamp: 3622133561.726278364 (2014/10/12 20:12:41)
Originator - Receive Timestamp: -57.080305658
Originator - Transmit Timestamp: +7.897664248
20:12:41.748948 IP (tos 0x0, ttl 54, id 9285, offset 0, flags [none], proto UDP (17), length 76)
198.55.111.50.123 > 10.0.3.246.123: [udp sum ok] NTPv4, length 48
Server, Leap indicator: (0), Stratum 3 (secondary reference), poll 6 (64s), precision -20
Root Delay: 0.054077, Root dispersion: 0.058944, Reference-ID: 216.229.0.50
Reference Timestamp: 3622132887.136984840 (2014/10/12 20:01:27)
Originator Timestamp: 3622133561.726278364 (2014/10/12 20:12:41)
Receive Timestamp: 3622133618.830113530 (2014/10/12 20:13:38)
Transmit Timestamp: 3622133618.830129086 (2014/10/12 20:13:38)
Originator - Receive Timestamp: +57.103835195
Originator - Transmit Timestamp: +57.103850722