tcpdump-icmp-ip报文分片

介绍主要演示了tcpdump捕捉icmp报文以及用ping命令指定icmp长度后ip分组的查看。 A发起正常包pingC:\Users\yaxia>ping 10.70.30.60正在 Ping 10.70.30.60 具有 32 字节的数据:来自 10.70.30.60 的回复: 字节=32 时间<1ms TTL=64来自 10.70.30.60 的回复: 字节=32 时间<1ms TTL=64来自 10.70.30.60 的回复: 字节=32 时间<1ms TTL=64来自 10.70.30.60 的回复: 字节=32 时间<1ms TTL=6410.70.30.60 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 0ms,平均 = 0msB 端查看结果root@php56:/home/tb# tcpdump -ntv -i enp0s3 icmptcpdump: listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytesIP (tos 0x0, ttl 128, id 27746, offset 0, flags [none], proto ICMP (1), length 60) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4795, length 40IP (tos 0x0, ttl 64, id 30075, offset 0, flags [none], proto ICMP (1), length 60) 10.70.30.60 > 10.70.30.47: ICMP echo reply, id 1, seq 4795, length 40IP (tos 0x0, ttl 128, id 27748, offset 0, flags [none], proto ICMP (1), length 60) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4796, length 40IP (tos 0x0, ttl 64, id 30127, offset 0, flags [none], proto ICMP (1), length 60) 10.70.30.60 > 10.70.30.47: ICMP echo reply, id 1, seq 4796, length 40IP (tos 0x0, ttl 128, id 27750, offset 0, flags [none], proto ICMP (1), length 60) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4797, length 40IP (tos 0x0, ttl 64, id 30365, offset 0, flags [none], proto ICMP (1), length 60) 10.70.30.60 > 10.70.30.47: ICMP echo reply, id 1, seq 4797, length 40IP (tos 0x0, ttl 128, id 27752, offset 0, flags [none], proto ICMP (1), length 60) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4798, length 40IP (tos 0x0, ttl 64, id 30534, offset 0, flags [none], proto ICMP (1), length 60) 10.70.30.60 > 10.70.30.47: ICMP echo reply, id 1, seq 4798, length 40A发送大于MTU的数据包C:\Users\yaxia>ping 10.70.30.60 -l 1473正在 Ping 10.70.30.60 具有 1473 字节的数据:来自 10.70.30.60 的回复: 字节=1473 时间<1ms TTL=64来自 10.70.30.60 的回复: 字节=1473 时间<1ms TTL=64来自 10.70.30.60 的回复: 字节=1473 时间<1ms TTL=64来自 10.70.30.60 的回复: 字节=1473 时间<1ms TTL=6410.70.30.60 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 0ms,平均 = 0msB接收结果(可以看到ip包多了一倍)P (tos 0x0, ttl 128, id 27801, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4799, length 1480IP (tos 0x0, ttl 128, id 27801, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.47 > 10.70.30.60: ip-proto-1IP (tos 0x0, ttl 64, id 10022, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.60 > 10.70.30.47: ICMP echo reply, id 1, seq 4799, length 1480IP (tos 0x0, ttl 64, id 10022, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.60 > 10.70.30.47: ip-proto-1IP (tos 0x0, ttl 128, id 27803, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4800, length 1480IP (tos 0x0, ttl 128, id 27803, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.47 > 10.70.30.60: ip-proto-1IP (tos 0x0, ttl 64, id 10189, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.60 > 10.70.30.47: ICMP echo reply, id 1, seq 4800, length 1480IP (tos 0x0, ttl 64, id 10189, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.60 > 10.70.30.47: ip-proto-1IP (tos 0x0, ttl 128, id 27805, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4801, length 1480IP (tos 0x0, ttl 128, id 27805, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.47 > 10.70.30.60: ip-proto-1IP (tos 0x0, ttl 64, id 10418, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.60 > 10.70.30.47: ICMP echo reply, id 1, seq 4801, length 1480IP (tos 0x0, ttl 64, id 10418, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.60 > 10.70.30.47: ip-proto-1IP (tos 0x0, ttl 128, id 27807, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4802, length 1480IP (tos 0x0, ttl 128, id 27807, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.47 > 10.70.30.60: ip-proto-1IP (tos 0x0, ttl 64, id 10429, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.60 > 10.70.30.47: ICMP echo reply, id 1, seq 4802, length 1480IP (tos 0x0, ttl 64, id 10429, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.60 > 10.70.30.47: ip-proto-1摘出来一个被分片的ip数据包IP (tos 0x0, ttl 128, id 27801, offset 0, flags [+], proto ICMP (1), length 1500) 10.70.30.47 > 10.70.30.60: ICMP echo request, id 1, seq 4799, length 1480IP (tos 0x0, ttl 128, id 27801, offset 1480, flags [none], proto ICMP (1), length 21) 10.70.30.47 > 10.70.30.60: ip-proto-1简单解释id都为27081,说明为同一个ip数据报的分片。第一个ip分组的offset 为0,第二个为1480.第一个ip分组的flags为+,实则设置了MF标志,表示后续还有分片,第二个flag为none第一个ip分组长度为1500,第二个为21-l 1473字节的由来win下查看A端mtu ...

November 4, 2019 · 4 min · jiezi

在-iOS-平台实现Ping-和-traceroute

ping 命令Ping是为了测试另一台主机是否可达,现在已经成为一种常用的网络状态检查工具。 常见的ping命令: /**** 往目的追击发送固定包数 ****/ping -c 3 www.baidu.com // ping百度发送3个包/**** 设置两次发包之间的等待时间 ****/ping -i 5 www.baidu.com // 两包之间的时间间隔为5sping -i 0.1 www.baidu.com // 两包之间的时间间隔为0.1s/**** 检查本地网络接口是否已经启动并正在运行 ****/ping 127.0.0.1 (linux: ping 0) ping localhost /**** 超级用户可以利用 -f 几秒钟发送数十万个包给主服务造成压力 *****/sudo ping -f www.baidu.com /**** 让电脑发出蜂鸣声: 响应包到达目时,会发出声音 ****/ping -a www.baidu.com /**** 只打印ping的汇总结果 ****/ping -c 5 -q www.baidu.com/**** 修改ping包(icmp包)的大小 ****/ping -s 100 -c 5 www.baidu.com示例: macdeiMac:PhoneNetSDK ethan$ ping www.baidu.comPING www.a.shifen.com (61.135.169.121): 56 data bytes64 bytes from 61.135.169.121: icmp_seq=0 ttl=49 time=32.559 ms64 bytes from 61.135.169.121: icmp_seq=1 ttl=49 time=32.413 ms64 bytes from 61.135.169.121: icmp_seq=2 ttl=49 time=32.489 ms^C--- www.a.shifen.com ping statistics ---3 packets transmitted, 3 packets received, 0.0% packet lossround-trip min/avg/max/stddev = 32.413/32.487/32.559/0.060 msmacdeiMac:PhoneNetSDK ethan$ 分析以上结果: ...

June 19, 2019 · 4 min · jiezi

记一次吐血的ping-unknown-host

摘要: ping域名提示unknown host,ping ip则可以通,ping的时候抓包没有解析的包出去,是解析的问题吗?背景: 某客户的ECS,ping域名提示unknown host,ping ip则可以通,ping的时候抓包没有解析的包出去,是解析的问题吗?1,测试ping域名以及抓包发现没有dns的解析包出去 # ping www.baidu.com -c 1ping: unknown host www.baidu.com# tcpdump -i any port 53 -nnvvtcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes2,测试ping ip dig getent等工作正常 # ping -c 1 115.239.210.27PING 115.239.210.27 (115.239.210.27) 56(84) bytes of data.64 bytes from 115.239.210.27: icmp_seq=1 ttl=55 time=1.87 ms--- 115.239.210.27 ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 1.875/1.875/1.875/0.000 ms# getent hosts www.baidu.com115.239.211.112 www.a.shifen.com www.baidu.com115.239.210.27 www.a.shifen.com www.baidu.com# dig www.baidu.com +shortwww.a.shifen.com.115.239.210.27115.239.211.1123,通过上述的测试可以确定,并非dns工作出现了问题,而是ping本身出现了问题 ...

May 13, 2019 · 6 min · jiezi

这个情人节,工程师用阿里云来试着表达不一样的爱意

年轻的时候谈的恋爱就像TCP链接,恋爱时三次握手即可,可分手时却分了四次。而常常久久的爱情,更像是icmp协议,无论对方身在何处,无论是否是可靠连接,无论你何时去ping她/他,她/他都默默地响应你。这篇文章就是说说,如何在内核中增加几行代码,让你的女神/男神当ping你(的服务器)的时候,来传达表达你的爱。效果如下(左边为ping的结果,需要破解ascii码转换为对应字符,右边为使用tcpdump抓包直接读取的信息):对于UNIX_LIKE系统来说,如果ping的发送内容与接收内容不同,会显示不同的部分,那么就让你的女神或者男神,慢慢将ASCII码解析成你想告诉她/他的话吧。或者告诉她/他,使用tcpdump来直接抓包隐藏在ping中的悄悄话。(对于windows来说本人没有充分测试,只是知道不会像unix_like系统一样直接显示出请求消息和回显消息的不同,所以需要大家抓包认真提取信息)一、ICMP协议这些你需要了解:学过计算机网络的一定知道,一个网络包的封装主要由多个属于不同网络协议层的报文头和用户数据共同组成:链路层报文头+网络层IP报文头+传输层报文头+携带的内容+帧尾。而ICMP报文在整个以太帧位于如下位置: 上图显示的是一个未分片ICMP报文或者是一个较长ICMP报文的第一个IP分片的报文(被分片的报文中不会带有ICMP报头)。RFC792(https://tools.ietf.org/html/r…)中定义了11种ICMP报文类型,通过ICMP报头8bit"类型"字段进行区分。并且每种"类型“会和其”代码"字段以及报文头的最后4字节,共同表达每种报文类型所表示的信息。这些ICMP报文类型被主要分为差错报文和查询报文:查询报文主要包括:回送请求(TYPE8),回送应答(TYPE0),地址掩码或时间戳的请求/应答等差错报文主要包括:目标主机不可达(TYPE3),超时,源抑制,路由重定向等 ping作为ICMP协议最为典型的运用,主要和回送请求,和回送应答这两个类型相关,这也是本文主要关心的两个类型。当然,当主机不可达或者网络路由不可达出现的时候,ping会收到路由器传来的TYPE为3的目标主机不可达的报文(我们可以通过tcpdump抓包获取)。对于其他的类型,有兴趣的同学可以自行学习,如icmp重定向攻击,洪水攻击都是利用了ICMP协议进行的网络攻击。二、动手写一个简单的ping,了解Linux ping作为本文的主角之一ping,有必要动手写一个简单的ping,帮助我们更好的理解整个请求应答的过程。我本人的测试机器centos 7中使用的是iputils这个工具进行ping操作,所以我们可以从iputils源码入手学习如何写一个简单的ping。学习过c网络编程的一定都了解socket套接字这个概念。对于ping来说发送请求和接受应答也同样是通过套接字来完成。只不过,ICMP协议虽然在内核中和TCP、UDP相似属于L4层协议,但是本质是附属于IP协议的网络层协议,所以需要使用原始套接字(SOCK_RAW)构建套接字,而非TCP或UDP使用的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM)。SOCK_RAW的用途在于用户可以自定义填充IP报文头,并且对于ICMP报文自定义填充ICMP报文头。下面一张图,展示了代码中整个ping的逻辑发送以及处理应答的逻辑。具体代码可以参考这个:https://github.com/xiaobaidemu/myping/blob/master/ping.c 整个流程非常简单,需要说明的是,对于ping 127.0.0.1来说,程序极有可能先收到type为0的回显请求报文,再收到type为8的回显应答报文。这是因为icmp报文可以同时被内核接收处理,也会被原始套接字接收处理,如下为Understanding Linux Network Internals书中所述。三、添加内核代码前,你只需要知道一个结构体和icmp.c理解了ping的整个过程,接下来就是需要修改内核来传达你想说的话。但是最重要的是,需要分析出修改的位置,即回显应答可能发送的字节在内核代码中的位置。这里有一个非常重要的结构体——struct sk_buff,其定义位于<include/linux/skbuff.h>。内核中sk_buff结构体做到了可以不使用拷贝或删除的方式,使得数据在各层协议之间传输——即移动指针头的方式,具体为在处理不同的协议头时,代表协议头的指针,指向的是不同数据区域(如从L2到L4层协议,分别指向二层mac头,三层IP头,四层传输头)。以下是几个比较重要和混淆的字段说明,结合示意图说明: 上图简单说明了四个指针和指向区域之间的关系。另外对于data_len和len的关系,如果假设icmp报文比较小,ip层不会对其分片,那么data_len即为0,而len即为当前协议头长度+数据报文长度。关于data_len和len之间的关系涉及到skb_shared_info这个结构体的相关内容,因为和文章中心关系不大,有兴趣的同学可以自行查阅一下文章来学习http://blog.51cto.com/weiguozhihui/1586777https://0x657573.wordpress.com/2010/11/22/the-relation-between-skb-len-and-skb-data_len-and-what-they-represent/https://blog.csdn.net/farmwang/article/details/54233975 上述内容中data指针和表征协议层数据长度的len,和后文中修改的sk_buff指向的数据直接相关。另外sk_buff关联了众多其他结构体,这里只简要的讲解部分重要的字段含义,更为具体详细的说明可以参考Understanding Linux Network Internal第二章或者https://blog.csdn.net/YuZhiHui_No1/article/details/38666589系列文章进行更深入学习。 了解了sk_buff结构体,之后需要定位处理icmp协议的文件在哪里。icmp.c位于内核目录中net/ipv4/icmp.c中,且ICMP协议通常是静态编译至内核中,而非通过模块配置的。这里我从Understanding Linux Network Internal这本书中抠出来一张Big Picture,来简要说明一下对于ping发出的回显请求,sk_buff结构体对象是如何在icmp中众多函数中传递。首先ip_local_deliver_finish会传递ICMP消息到icmp_rcv, icmp_rcv会解析icmp报头中类型字段,对于属于查询报文的类型(如type8)会传递给icmp_reply, 而对于差错报文会传递给icmp_send处理,并且ICMP协议也会和其他诸如TCP/UDP协议进行交互传递信息。对于ping进程发出的请求,会先传递给icmp_echo函数进行处理。而icmp_echo正是处理ping请求很重要的一步,内核会把请求中附带的数据报文部分原封不动的拷贝并发送回源主机。因此我们可以在icmp_echo函数中,添加进我们"爱的语句"。static bool icmp_echo(struct sk_buff skb){ struct net net; net = dev_net(skb_dst(skb)->dev); if (!net->ipv4.sysctl_icmp_echo_ignore_all) { struct icmp_bxm icmp_param; icmp_param.data.icmph = icmp_hdr(skb); icmp_param.data.icmph.type = ICMP_ECHOREPLY; icmp_param.skb = skb; //———–添加开始———– char sentence1[] = “I LOVE U, xxxx.”; char sentence2[] = “I MISS U, xxxx.”; char sentence3[] = “Happy Valentine’s Day!”; int sentence_len_list[] = {sizeof(sentence1), sizeof(sentence2), sizeof(sentence3)}; char sentence_list[] = {sentence1, sentence2, sentence3}; int sentence_index = icmp_param.data.icmph.un.echo.sequence % 3; if(skb->len >= 16 + sentence_len_list[sentence_index]) { char tmp = (char)(skb->data+16); char* target_sentence = sentence_list[sentence_index]; int i=0; for(;i<sentence_len_list[sentence_index];++i) { tmp[i] = target_sentence[i]; } for(;i < skb->len-16;++i) { tmp[i] = 0; } } //———–添加结束———— icmp_param.offset = 0; icmp_param.data_len = skb->len; icmp_param.head_len = sizeof(struct icmphdr); icmp_reply(&icmp_param, skb); } /* should there be an ICMP stat for ignored echos? */ return true;}上述代码中icmp_bxm结构体包含了在后续icmp消息传递过程中的所有需要的信息,包括icmp报文头,sk_buff对象,icmp 报文payload大小等。需要注意的是,由于icmp_rcv已经解析过sk_buff中属于icmp协议的报文头部分,所以参数中skb->data指向的是icmp数据部分,即不包含报文头,而skb->len也只有icmp数据部分的长度。假设ping请求中所带的数据部分为56字节,则此时skb->len大小为56。由于ping数据部分的前16字节为携带的是发送是struct timeval对象——发送时的时间,所以在真实替换时,从data指向的数据部分的第16个字节开始,用memcpy复制到对应区域,或者如上例子傻傻的循环赋值即可。上面代码所表示的就是根据echo请求中seq_id循环回复上述三句话。当然有创意的小伙伴可以增加更多表达难度。四、创建一个阿里云ECS服务器,十分钟完成所有修改分析完了整个icmp处理流程,和修改方法,我们只需要创建一个阿里云ECS,并简单编译修改后的内核即可。具体流程如下:阿里云创建任意规格服务器(大规格可以加快内核编译速度,此处创建一个4vcpu服务器),使用centos作为os下载linux内核代码,并解压放置到/usr/src/kernels目录下,本文使用的是4.20.6内核版本。编译前基于原centos系统中/boot目录下的config文件,生成编译配置项,根据此编译项来定制内核。拷贝原配置文件至内核文件目录 sudo cp /boot/config-3.10.0-693.el7.x86_64 ./.config;执行make oldconfig,生成新的.config文件编译源码:make -j 4 ,可能编译过程中缺少某些库,此时yum安装缺少的库,如openssl-devel, elfutils-libelf-devel安装内核模块:make modules_install -j 4拷贝内核和配置文件至/boot目录,并生成System.map文件:make install -j 4更新引导:grub2-mkconfig -o /boot/grub2/grub.cfg修改默认默认启动引导内核:修改/etc/default/grub文件,将GRUB_DEFAULT设为0,0表示第一个启动项,即为最新编译的内核。重启服务器:reboot 至此告诉你的女神/男神,你想说的话都在ping中。部分参考文章:Understanding Linux Network Internal 第2章&第25章https://www.geeksforgeeks.org/ping-in-c/https://medium.freecodecamp.org/building-and-installing-the-latest-linux-kernel-from-source-6d8df5345980https://github.com/iputils/ip…本文作者:贺小白同学阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

February 18, 2019 · 1 min · jiezi