专栏首页皮振伟的专栏[linux][network]ICMP协议分析

[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四个字母,说出来怕被深问,所以只回答了:”对网络没有概念“。后来才知道,面试官是部门的总监。

囧囧囧~

本文分享自微信公众号 - AlwaysGeek(gh_d0972b1eeb60),作者:AlwaysGeek

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-02-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [virt][concept]虚拟化技术概论--KVM,QEMU,Libvirt

    前言: 以作者的经验来看,虚拟化的跨度比较大,很多概念比较难以理解,本来以为“硬件行为,就是这样的”好多概念,都变成虚拟的了。 作者对kernel略懂一二,结合...

    皮振伟
  • [gcc][glibc]va_start嵌套导致的问题

    使用tgt-1.0.75创建好target之后,在initiator端执行login操作大约卡3s~5s左右。同时观察tgt,CPU消耗到达100%。

    皮振伟
  • linux、memory、memcmp 几种实现和性能对比

    memcmp是最基本的库函数了。本文选择几版代码,分析kernel和glibc的memcmp实现,并对比其性能,希望对大家了解有所帮助。

    皮振伟
  • JavaScript中的比较运算符

    JavaScript中的比较运算符 JavaScript中的比较运算符粗略的可以分为两种: 相等运算符(==、===、!==)这些 ...

    贾顺名
  • JavaScript中的比较运算符

    最后一个null >= 0的结果为true。 刚看到这个代码的时候,下意识地会认为结果应该也是false,毕竟上边标明了三种情况都为false。 然而这个就露出...

    贾顺名
  • flowchart.js徒手绘制流程图

    要画20个流程(时序)图,于是昨天捣鼓了到半夜,安装了plantUML + vscode,虽然丑了些,但勉强能看,目前已用plantUML完成了10个。...

    周星星9527
  • Python 中的神秘运算符

    今天我们来讲讲 Python 里一个不为众人所知的运算符。你可能会觉得疑惑:还有我不知道的运算符?别急着下结论,先往下看看再说。

    Crossin先生
  • R语言基础教程——第3章:数据结构综合运用

    在之前R语言基础教程——第3章:数据结构——向量中我们介绍过向量的加减乘除运算,在这里介绍一下>,<运算。

    DoubleHelix
  • 大数据之脚踏实地学08--搭建Hadoop集群【2】

    在《大数据之脚踏实地学07--搭建Hadoop集群【1】》中,讲解的是虚拟机的配置(包括网络设置、主机名修改和克隆等),文中我们在VMware中虚拟了3台计算机...

    1480
  • 替换Debug Probes其实很简单

    在使用Vivado Logic Analyzer调试时,常会遇到这样的情形:当前阶段需要观测信号xa_reg,下一阶段需要观测xb_reg,两个阶段原始设计并没...

    Lauren的FPGA

扫码关注云+社区

领取腾讯云代金券