tcpdump进行IP抓包
在学习《Linux高性能服务器编程》中,看到作者对IP头部使用tcpdump
进行抓包,所以本着实践出真知、多看多练的道理,也进行抓包,顺带记录一下。
注意这里的IP协议都是指IPv4协议。
IP头部结构
IP协议可以说是网络通讯中最重要的协议之一,所以了解IP数据包的结构是非常有必要的。
IP数据报由报头和数据两部分组成,其中,数据是高层需要传输的数据,报头是为了正确传输高层数据而增加的控制信息。
IP的头部结构如下:
固定部分为实线部分,长度为20字节。可变长的选项部分长度最多40字节,所以IP头部最多60字节长。
- 版本号
占 4 位,表示 IP 协议的版本。在IPv4中的值是4。
- 头部长度
占 4 位,可表示的最大十进制数值是 15。头部长度表示IP头部有多少个32bit字(4字节),所以IP头部最长是60字节。
- 服务类型(tos)
占 8 位,用来获得更好的服务。分为3位的优先权字段(现在以及被忽略),4位的TOS字段和1位保留字段(必须置为0)。4位的TOS字段分别表示:最小延时,最大吞吐量,最高可靠性和最小非也。其中最多有一个能置为1,应用程序根据实际需要来设置,比如ssh和telnet这样的服务就需要最小延时服务。
- 总长度(totlen)
占16 位,表示整个数据报的长度(字节为单位),因此IP数据报的最大长度为 2^16-1=65535 字节。但是由于MTU的限制,长度超过MTU的数据报会被分片,所以实际传输IP数据报的长度远远没有达到最大值。
- 标识(identification)
占 16 位。IP 协议在存储器中维持一个计数器。每产生一个数据报,计数器就加 1,并将此值赋给标识字段,其初始值由系统随机生成。当数据报的长度超过网络的 MTU,而必须分片时,这个标识字段的值就被复制到所有的数据报的标识字段中。具有相同的标识字段值的分片报文会被重组成原来的数据报。
- 标志(flag)
占 3 位。第一位保留,其值为 0。第二位称为 DF(不分片),表示是否允许分片。取值为 0 时,表示允许分片;取值为 1 时,表示不允许分片。第三位称为 MF(更多分片),表示是否还有分片正在传输,设置为 0 时,表示没有更多分片需要发送,或数据报没有分片,比如:在分片的数据报中最后一个分片将这位设置位0,其他分片都要把它置为1。
- 片偏移(offsetfrag)
占 13 位。当报文被分片后,该字段标记该分片在原报文中的相对位置。片偏移以 8 个字节为偏移单位。所以,除了最后一个分片,其他分片的偏移值都是 8 字节(64 位)的整数倍。由于这个原因,每个IP分片的数据部分的长度必须是8的整数倍(最后一个分片除外)。
- 生存时间(TTL)
占 8 位,表示数据报在网络中的寿命。该字段由发出数据报的源主机设置。其目的是防止无法交付的数据报无限制地在网络中传输,从而消耗网络资源。
路由器在转发数据报之前,先把 TTL 值减 1。若 TTL 值减少到 0,则丢弃这个数据报,不再转发。因此,TTL 指明数据报在网络中最多可经过多少个路由器。TTL 的最大数值为 255。若把 TTL 的初始值设为 1,则表示这个数据报只能在本局域网中传送。
- 协议
占 8 位,表示该数据报文所携带的数据所使用的协议类型。该字段可以方便目的主机的 IP 层知道按照什么协议来处理数据部分。不同的协议有专门不同的协议号。
例如,TCP 的协议号为 6,UDP 的协议号为 17,ICMP 的协议号为 1。
- 头部检验和(checksum)
用于校验数据报的首部,占 16 位。数据报每经过一个路由器,首部的字段都可能发生变化(如TTL),所以需要重新校验。而数据部分不发生变化,所以不用重新生成校验值。
- 源地址
表示数据报的源 IP 地址,占 32 位。
- 目的地址
表示数据报的目的 IP 地址,占 32 位。该字段用于校验发送是否正确。
- 可选字段
该字段用于一些可选的报头设置,主要用于测试、调试和安全的目的。这些选项包括严格源路由(数据报必须经过指定的路由)、网际时间戳(经过每个路由器时的时间戳记录)和安全限制。
- 填充
由于可选字段中的长度不是固定的,使用若干个 0 填充该字段,可以保证整个报头的长度是 32 位的整数倍。
使用tcpdump观察IPv4头部结构
我们抓取本地回路上的数据包,通过telnet 127.0.0.1
配合tcpdump
进行抓包
抓包命令如下:
sudo tcpdump -ntx -i lo -c 1
其中
-n 不把主机的网络地址转换成名字
-t 在每列倾倒资料上不显示时间戳记
-x 用十六进制字码列出数据包资料
-i 抓取指定网卡的包
-c 抓取包的个数
最终抓包结果如图所示:
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数据报自然而然的会进行分片。
然还使用
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位分片偏移。它的二进制为文章来源:https://www.toymoban.com/news/detail-451334.html
0000 0000 1011 1001
前三位标志位都为0,表示这是最后一个分片包,0xb9
十进制是271,然后再乘以8等于1480,即偏移是1480字节,也和前面介绍的片偏移内容吻合。文章来源地址https://www.toymoban.com/news/detail-451334.html
到了这里,关于tcpdump进行IP抓包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!