tcpdump进行IP抓包

tcpdump进行IP抓包

在学习《Linux高性能服务器编程》中,看到作者对IP头部使用tcpdump进行抓包,所以本着实践出真知、多看多练的道理,也进行抓包,顺带记录一下。

注意这里的IP协议都是指IPv4协议。

IP头部结构

IP协议可以说是网络通讯中最重要的协议之一,所以了解IP数据包的结构是非常有必要的。

IP数据报由报头数据两部分组成,其中,数据是高层需要传输的数据,报头是为了正确传输高层数据而增加的控制信息。

IP的头部结构如下:

tcpdump进行IP抓包_第1张图片

固定部分为实线部分,长度为20字节。可变长的选项部分长度最多40字节,所以IP头部最多60字节长。

  1. 版本号

占 4 位,表示 IP 协议的版本。在IPv4中的值是4。

  1. 头部长度

占 4 位,可表示的最大十进制数值是 15。头部长度表示IP头部有多少个32bit字(4字节),所以IP头部最长是60字节。

  1. 服务类型(tos)

占 8 位,用来获得更好的服务。分为3位的优先权字段(现在以及被忽略),4位的TOS字段和1位保留字段(必须置为0)。4位的TOS字段分别表示:最小延时,最大吞吐量,最高可靠性和最小非也。其中最多有一个能置为1,应用程序根据实际需要来设置,比如ssh和telnet这样的服务就需要最小延时服务。

  1. 总长度(totlen)

占16 位,表示整个数据报的长度(字节为单位),因此IP数据报的最大长度为 2^16-1=65535 字节。但是由于MTU的限制,长度超过MTU的数据报会被分片,所以实际传输IP数据报的长度远远没有达到最大值。

  1. 标识(identification)

占 16 位。IP 协议在存储器中维持一个计数器。每产生一个数据报,计数器就加 1,并将此值赋给标识字段,其初始值由系统随机生成。当数据报的长度超过网络的 MTU,而必须分片时,这个标识字段的值就被复制到所有的数据报的标识字段中。具有相同的标识字段值的分片报文会被重组成原来的数据报。

  1. 标志(flag)

占 3 位。第一位保留,其值为 0。第二位称为 DF(不分片),表示是否允许分片。取值为 0 时,表示允许分片;取值为 1 时,表示不允许分片。第三位称为 MF(更多分片),表示是否还有分片正在传输,设置为 0 时,表示没有更多分片需要发送,或数据报没有分片,比如:在分片的数据报中最后一个分片将这位设置位0,其他分片都要把它置为1。

  1. 片偏移(offsetfrag)

占 13 位。当报文被分片后,该字段标记该分片在原报文中的相对位置。片偏移以 8 个字节为偏移单位。所以,除了最后一个分片,其他分片的偏移值都是 8 字节(64 位)的整数倍。由于这个原因,每个IP分片的数据部分的长度必须是8的整数倍(最后一个分片除外)。

  1. 生存时间(TTL)

占 8 位,表示数据报在网络中的寿命。该字段由发出数据报的源主机设置。其目的是防止无法交付的数据报无限制地在网络中传输,从而消耗网络资源。

路由器在转发数据报之前,先把 TTL 值减 1。若 TTL 值减少到 0,则丢弃这个数据报,不再转发。因此,TTL 指明数据报在网络中最多可经过多少个路由器。TTL 的最大数值为 255。若把 TTL 的初始值设为 1,则表示这个数据报只能在本局域网中传送。

  1. 协议

占 8 位,表示该数据报文所携带的数据所使用的协议类型。该字段可以方便目的主机的 IP 层知道按照什么协议来处理数据部分。不同的协议有专门不同的协议号。

例如,TCP 的协议号为 6,UDP 的协议号为 17,ICMP 的协议号为 1。

  1. 头部检验和(checksum)

用于校验数据报的首部,占 16 位。数据报每经过一个路由器,首部的字段都可能发生变化(如TTL),所以需要重新校验。而数据部分不发生变化,所以不用重新生成校验值。

  1. 源地址

表示数据报的源 IP 地址,占 32 位。

  1. 目的地址

表示数据报的目的 IP 地址,占 32 位。该字段用于校验发送是否正确。

  1. 可选字段

该字段用于一些可选的报头设置,主要用于测试、调试和安全的目的。这些选项包括严格源路由(数据报必须经过指定的路由)、网际时间戳(经过每个路由器时的时间戳记录)和安全限制。

  1. 填充

由于可选字段中的长度不是固定的,使用若干个 0 填充该字段,可以保证整个报头的长度是 32 位的整数倍。

使用tcpdump观察IPv4头部结构

我们抓取本地回路上的数据包,通过telnet 127.0.0.1配合tcpdump进行抓包

image-20220806142812432

抓包命令如下:

sudo tcpdump -ntx -i lo -c 1

其中

-n 不把主机的网络地址转换成名字
-t 在每列倾倒资料上不显示时间戳记
-x 用十六进制字码列出数据包资料
-i 抓取指定网卡的包
-c 抓取包的个数

最终抓包结果如图所示:

tcpdump进行IP抓包_第2张图片

IP 127.0.0.1.52904 > 127.0.0.1.23: Flags [S], seq 1003093548, win 65495, options [mss 65495,sackOK,TS val 3642507651 ecr 0,nop,wscale 7], length 0
	0x0000:  4510 003c af8c 4000 4006 8d1d 7f00 0001
	0x0010:  7f00 0001 cea8 0017 3bc9 fe2c 0000 0000
	0x0020:  a002 ffd7 fe30 0000 0204 ffd7 0402 080a
	0x0030:  d91c 4183 0000 0000 0103 0307

因为我们是telnet 127.0.0.1所以我们源地址和目标地址都是127.0.0.1只不过一个是客户端端口52904到目标端口23(telnet端口)。

“Flag”、“seq”、“win”和“options”都是TCP头部信息(telnet使用的是TCP协议),所以在这里不是我们的重点。

length表示应用程序数据的长度(并不是IP数据部分)。这里数据包共包含60字节,其中前20字节是IP头部,后40字节是TCP头部,不包含应用程序数据(length值为0)。

接下来我们重点关注IP头部的数据,截取一下:

0x0000:  4510 003c af8c 4000 4006 8d1d 7f00 0001
0x0010:  7f00 0001
十六进制数 十进制数 IP头部信息
0x4 4 IP版本号
0x5 5 头部长度为5个32位(20字节)
0x10 TOS选项中最小延时服务被开启
0x003c 60 数据包总长度,60字节
0xaf8c 数据报标识
0x4 3位标志,设置禁止分片
0x000 0 分片偏移
0x40 64 TTL被设为64
0x06 6 协议字段为6,表示上层协议是TCP协议
0x8d1d IP头部校验和
0x7f00 0001 源端IP地址127.0.0.1
0x7f00 0001 目的端IP地址127.0.0.1

IP分片抓包

上面抓包并没有进行分片,所以为了了解分片,还需要进行抓包,查看分片情况。

这次使用ping命令配合tcpdump进行抓包

ping baidu.com -s 1473

因为以太网帧MTU是1500字节,因此它所携带的IP数据报的数据部分最多1480字节(IP头部占20字节),然还因为ping使用的是ICMP协议,ICMP头部占8字节,所以ICMP数据部分最多占1472字节。

我们使用ping命令发送1473个字节,那么这个IP数据报自然而然的会进行分片。

tcpdump进行IP抓包_第3张图片

然还使用

sudo tcpdump -ntx -i eth0  icmp > a.txt

将抓的包的内容放到文件a.txt当中。

然后去除其中有用的部分如下:

IP 10.0.4.5 > 110.242.68.66: ICMP echo request, id 25, seq 1, length 1480
	0x0000:  4500 05dc a74e 2000 4001 ec99 0a00 0405
	0x0010:  6ef2 4442 0800 2d22 0019 0001 4df3 ed62
	0x0020:  0000 0000 7e4a 0400 0000 0000 1011 1213
	0x0030:  1415 1617 1819 1a1b 1c1d 1e1f 2021 2223
	...(数据太多不进行全部展示)
	
IP 10.0.4.5 > 110.242.68.66: ip-proto-1
	0x0000:  4500 0015 a74e 00b9 4001 11a8 0a00 0405
	0x0010:  6ef2 4442 c0

可以看到

第一个包的IP头部

IP 10.0.4.5 > 110.242.68.66: ICMP echo request, id 25, seq 1, length 1480
	0x0000:  4500 05dc a74e 2000 4001 ec99 0a00 0405
	0x0010:  6ef2 4442 

其中0x05dc代表IP数据报的总长度为1500字节

其中0X2000是3位标志字段和13位分片偏移。它的二进制为

0010 0000 0000 0000

标志位第三位(MF)为1,表示有分片。因为是一个分片包所以偏移为0

第二个 包的IP头部

IP 10.0.4.5 > 110.242.68.66: ip-proto-1
	0x0000:  4500 0015 a74e 00b9 4001 11a8 0a00 0405
	0x0010:  6ef2 4442 

其中0x0015代表IP数据报的总长度为21字节

其中0X00b9是3位标志字段和13位分片偏移。它的二进制为

0000 0000 1011 1001

前三位标志位都为0,表示这是最后一个分片包,0xb9十进制是271,然后再乘以8等于1480,即偏移是1480字节,也和前面介绍的片偏移内容吻合。

你可能感兴趣的:(Linux,tcp/ip,tcpdump,网络)