【系列文章】

《神探tcpdump第一招》-linux命令五分钟系列之三十五
《神探tcpdump第二招》-linux命令五分钟系列之三十六
《神探tcpdump第三招》-linux命令五分钟系列之三十七
《神探tcpdump第四招》-linux命令五分钟系列之三十八
《神探tcpdump第五招》-linux命令五分钟系列之三十九
《神探tcpdump第六招》-linux命令五分钟系列之四十
《神探tcpdump第七招》-linux命令五分钟系列之四十一

==

在这个系列文章的开篇部分,我提到“学习tcpdump,要掌握的是三个部分,即选项、过滤表达式和输出内容”。本篇文章,我们就进入“输出内容”的讲解。

还记得我们在第一篇文章里的“人生中第一次抓包”么,我们这次就来好好剖析剖析这第一个包。

?

1
2
3
4
5
6
7
8
9
10
11
# tcpdump -i eth0 -nn -X 'port 53' -c 1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
19:48:33.285838 IP 116.255.245.206.47940 > 8.8.8.8.53: 22768+ A? www.baidu.com. (31)
0x0000: 4500 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...
0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...
0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai
0x0030: 6475 0363 6f6d 0000 0100 01 du.com.....
1 packets captured
1 packets received by filter
0 packets dropped by kernel

【第2行】

“tcpdump: verbose output suppressed, use -v or -vv for full protocol decode”

这一行,是一句贴心的提醒,简单易懂,就是说你的命令里没有用到-v和-vv,如果希望看到更全的输出内容,可以使用这两个选项。
如果你有兴趣,可以试试,看看加上-vv后,到底输出内容里会多些什么。

【第3行】

“listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes”

这一句表示我们监听的是通过eth0这个NIC设备的网络包,且它的链路层是基于以太网的,要抓的包大小限制是65535字节。

包大小限制值可以通过-s选项来设置,如果你要追求高性能,建议把这个值调低,这样可以有效避免在大流量情况下的丢包现象。

【第4行】

“19:48:33.285838 IP 116.255.245.206.47940 > 8.8.8.8.53: 22768+ A? www.baidu.com. (31)”

19:48:33.285838,分别对应着这个包被抓到的“时”、“分”、“秒”、“微妙”。

IP,表示这个包在网络层是IP包。

116.255.245.206.47940,表示这个包的源IP为116.255.245.206,源端口为47940。

>,这个大于号表示数据包的传输方向。

8.8.8.8.53,表示这个包要发向的目的端IP是8.8.8.8,目标端口为53,也就是我们熟知的DNS服务端口。

22768+ A? www.baidu.com. (31),这是DNS协议的内容,即请求www.baidu.com的A纪录。

【第5/6/7/8行】

0x0000: 4500 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

接下来便是IP包的内容了,是除去了以太网之后剩下的内容,其中左侧红色字体部分是十六进制内容,右侧天蓝色字体部分是相应的ASCII码内容。
如果想看懂上面这些十六进制数字,前提就是大家要对IP、TCP/UDP的包格式很熟悉才可以。正好Linux大棚有一个系列文章就是来介绍这些重要协议:

计算机网络协议包头赏析-以太网
计算机网络协议包头赏析-IP
计算机网络协议包头赏析-TCP
计算机网络协议包头赏析-UDP

好,下面我们就来给大家解读下那些“晦涩的十六进制数字”。

0x0000: 【45】00 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

如上,最外层是IP数据包,最开始的一个字节(8bit)中,前4bit表示IP的版本,此处为4,表示这是一个IPv4版本的IP包;后4bit 表示这IP包的首部长度,此处的数字是5,由于单位是“4字节”,因此可以计算得出这个IP包的首部长度是固定的20字节。如下绿色字体部分都是IP数据 包的首部部分:

0x0000: 【4500 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808】 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

如下所示,在IP版本和首部长度之后,接下来的一个字节(8bit)是“00”,这是IP协议的服务类型域(TOS),由于已经很少使用,因此此处被置为00。

0x0000: 45【00】003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

如下所示,后面的2字节(16bit)是“003b”,表示整个IP包的总长度(首部长度+数据长度),单位是字节,因此可以知道这个IP包的总长度是59字节(0x3b需要转换为十进制)。你可以数数下面的红色部分,应该是正好59个字节

0x0000: 4500 【003b】 c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

再向下的2字节(16bit)是“标识域”,如果IP包的大小超过了数据链路层的MTU限制,就需要对IP包进行分拆,此时就要用这个域来表示哪些包在分拆前是同一组的。此处的标识域值为0xc341。

0x0000: 4500 003b 【c341】 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

再继续向向下看,便是3bit的标志位,最高位为保留位,中间一位为DF(don’t fragment),最低位为MF(more fragments),可以看到这三位是用来控制IP拆包后的组装所用。由于此包没有拆包,因此这三位都被置为0,如下所示:

0x0000: 4500 003b c341 【0】000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

和上面的标志位配合的是紧接着的13bit的片便宜,但由于本包没有拆包,因此此域也无用,因此为0。

0x0000: 4500 003b c341 【0000】 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

如下,紧接着是8bit的TTL(Time To Live,即生存周期),此包的值为0x40,换算成十进制是64,这表明这个网络包,如果经过了超过64个中间路由节点,则认为目的地不可达,中间路由器会将此包抛弃掉。

0x0000: 4500 003b c341 0000 【40】11 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

继续的8bit为协议域,用于指代上一层协议类型。此处的值为0x11,对应十进制的17,而17是UDP协议的代号,因此可以知道这个网络包所用的传输层协议是UDP,而非TCP(TCP的协议号是6、TCMP的协议号是1)。

0x0000: 4500 003b c341 0000 40【11】 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

接下来的2个字节表示IP首部校验和,此处计算出来的结果是3c93。

0x0000: 4500 003b c341 0000 4011 【3c93】 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

如下,再往下就是大家非常熟悉的4字节的IP源地址,即“74 ff f5 ce”,转换成IP地址则为116.255.245.206。

0x0000: 4500 003b c341 0000 4011 3c93 【74ff f5ce】 E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

以此类推,再下面的4字节则为IP目的地址,即“08 08 08 08”,转换成IP地址则为8.8.8.8,这是著名的Google-DNS服务器地址。

0x0000: 4500 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 【0808 0808】 bb44 0035 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

至此,网络层IP协议的首部20字节已经分析完了。再向下我们即将进入传输层UDP协议的包分析阶段。

相对于TCP包来说,UDP包的首部还是比较简单的,总共只有8个字节,如下绿色部分便是UDP首部部分:

0x0000: 4500 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 【bb44 0035 0027 b457】 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

UDP首部的前2个字节(如下棕色部分)为源端口,此处为“bb 44”,即47940;而接下来的2字节(如下粉色部分)为目的端口,值为“00 35”,即53(DNS服务)。

0x0000: 4500 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 【bb44】 【0035】 0027 b457 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

而接下来的2字节(如下棕色部分)则表示UDP包的总长度(报头+数据部分),此处的值为“00 27”,这算成十进制则为39,就表示此UDP包的总长度为39字节,减去首部的8字节外,还有31字节来存储真正要传输的数据。

0x0000: 4500 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 【0027】 【b457】 58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01             du.com.....

而UDP首部的最后两个字节(如上粉色部分)则是校验和部分,此处的值为0xb457。

再向下的部分(绿色部分),则是应用层协议的内容(本例中是DNS协议)了,如果你有兴趣,可以继续了解下DNS协议、HTTP协议、FTP协议等众多的应用层协议,这非常有利于大家在学习协议、追查网络问题时,透过现象看本质。

0x0000: 4500 003b c341 0000 4011 3c93 74ff f5ce E..;.A..@.<.t...0x0010: 0808 0808 bb44 0035 0027 b457 【58f0 0100 .....D.5.'.WX...0x0020: 0001 0000 0000 0000 0377 7777 0562 6169 .........www.bai0x0030: 6475 0363 6f6d 0000 0100 01】             du.com.....

谢谢!