首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

[linux][network]ICMP协议分析

前言:

ICMP比较基础,说简单不简单,说难不难。 简单在于字段少,不能携带用户数据,没什么地方可以玩出太多花样;一般和它相关的就是ping和traceroute程序。 难在于它并不是工作在用户态,向基于TCP/UDP的echo服务一样,listen一个port,收到数据就存到buffer,再一模一样的返回数据。它到底怎样工作的呢?怎样能清晰的描述出来呢?

分析:

代码:linux-4.0.4/net/ipv4/icmp.c

1,在分析icmp之前,先分析一下:linux-4.0.4/net/ipv4/af_inet.c

在ipv4初始化的时候,向inet注册了icmp,tcp,udp,igmp协议。可见,至少在代码层面上,这四个协议是在同一个层面的。那么,就意味着,inet拿到数据(即IP层拿到数据),会根据protocol number选择向上述四个协议提交数据。

icmp协议的handler是icmp_rcv:

2,icmp_echo

icmp_rcv收到icmp request,回复icmp reply。

ping命令就是通过这样的逻辑的判断“网络是否可达”。

3,那么,是不是可以屏蔽掉icmp请求呢?

答案是可以,而且方法还很多。下面列举几种办法,效果一致,都是ping不通,但是工作原理不同。(不包括网卡断电~ifconfig eth0 down)

4,icmp_echo_ignore_all

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

从上面的代码中可以看到,icmp echo之前先要判断是否ignore。

5,修改kernel

没错,找到icmp.c, 和方法一类似,找到static void icmp_echo(struct sk_buff *skb),mark掉原有code,直接return。或者找到ICMP_ECHO的handler,改成icmp_discard,再或者,在int icmp_rcv(struct sk_buff *skb)收到IP层传递过来包的时候,直接drop。再或者,还记得inet_add_protocol吧,注册ICMP的地方,mark掉! 改完代码,剩下的就是make和make install了。

6,使用iptables iptables,一个运行在用户空间的应用软件,通过控制Linux内核netfilter模块,来管理网络数据包的流动与转送。在大部分的Linux系统上面,iptables是使用/usr/sbin/iptables来操作,文件则放置在手册页(Man page)底下,可以通过 man iptables 指令获取。通常iptables都需要内核层级的模块来配合运作,Xtables是主要在内核层级里面iptables API运作功能的模块。因相关动作上的需要,iptables的操作需要用到root的权限。 在INPUT的地方创建规则,如果是ICMP的echo-request请求,直接drop。 iptables -A INPUT -t filter -p icmp --icmp-type 8 -j DROP 在OUTPUT的地方创建规则,如果是ICMP的echo-reply回包,直接drop。 iptables -A OUTPUT -t filter -p icmp --icmp-type 0 -j DROP

7,netfilter

但是是自己编写规则,把代码编译成ko,动态安装/卸载。 自己编写内核模块,自由度更高,可以自己编写代码,所以比iptables更加灵活,相应的要求也要更高一些。但是总体方法类似:要么在ICMP请求的地方drop,要么就是在ICMP回包的地方drop。

8,kprobe

编写ko,方法通7类似。不过二者原理有本质差别。

后记:

说来惭愧,作者曾经面试某鹅的事后,被问到是否知道ping的实现。作者那是没有看过代码,只是记得书本上的ICMP四个字母,说出来怕被深问,所以只回答了:”对网络没有概念“。后来才知道,面试官是部门的总监。

囧囧囧~

下一篇
举报
领券