Linux icmp 学习笔记 之一 icmp协议相关的格式

Linux icmp功能分析 icmp协议相关的格式

 

ICMP协议是网络层中一个非常重要的协议,其全称为Internet Control Message Protocol(因特网控制报文协议),ICMP协议弥补了IP的缺限,它使用IP协议进行信息传递,向数据包中的源端节点提供发生在网络层的错误信息 反馈。

  在实现中,路由器会使用该协议来报告问题,而主机则会使用该机制来测试目的站是否可达。该报文的最终目的地不是一个应用程序或者目的设备上的用户,而是目的设备上的网际协议软件,一般icmp报文的接收是linux内核里的icmp接收模块来处理的,而icmp请求报文的发送即可以是内核里相关子系统也可以是应用层的程序发送(比如ping应用)。

 

1、  ICMP报文的格式

各种ICMP报文的前32bits都是三个长度固定的字段,为8bit的type字段、8bit的code字段、16bit的校验和字段(包括icmp数据字段的校验和),而对于不同类型的icmp报文,其余下字段的含义则是不同的。

 

a)       type类型

icmp类型目前有40个,下面几个是比较常用的,也是目前linux支持的类型。

0 回显应答(ECHO-REPLY

3 不可到达

4 源站抑制

5 重定向

8 回显请求(ECHO-REQUEST

11 数据报超时

12 参数失灵

13 时间戳请求

14 时间戳应答

15 信息请求(已不再使用)

16 信息应答(已不再使用)

17 地址掩码请求(已不再使用)

18 地址掩码应答(已不再使用)

对于 以上类型,比较重要的有:回显请求与应答(type 0、8)、不可到达(3)、源站抑制(4)、路由重定向(5)、时间戳请求与应答(13、14)

 

 

2、 主要的ICMP格式

a)      回显请求与应答

其中type值表示是一个回显请求或应答,code值为0,而identifier在linux的实现为进程pid(因为ping请求是应用程序,通过该值能够确认是机器上的哪一个应用程序执行的ping操作,能够对进行的接收数据进行匹配操作),而sequence则为一个计数器,主要是为每一个回显请求数据包设置序列值。Option是可选数据,其大小是可变的。

 

TYPE(8/0)

CODE(0)

Checksum

identifier

Sequence

Option

 

b)     目的站不可达

TYPE(3)

CODE(0-15)

Checksum

Not used (must set 0)

Option

 

由于目的站不可达的原因很多,所以需要用code来进行进一步细分。对于option字段,其值为ip头部(包括可选项)加上原始ip数据部分的前8个字节。

而code的定义如下:

#define ICMP_NET_UNREACH0 /* Network Unreachable */

#define ICMP_HOST_UNREACH1 /* Host Unreachable */

#define ICMP_PROT_UNREACH2 /* Protocol Unreachable */

#define ICMP_PORT_UNREACH3 /* Port Unreachable */

#define ICMP_FRAG_NEEDED4 /* Fragmentation Needed/DF set */

#define ICMP_SR_FAILED5 /* Source Route failed */

#define ICMP_NET_UNKNOWN6

#define ICMP_HOST_UNKNOWN7

#define ICMP_HOST_ISOLATED8

#define ICMP_NET_ANO9

#define ICMP_HOST_ANO10

#define ICMP_NET_UNR_TOS11

#define ICMP_HOST_UNR_TOS12

#define ICMP_PKT_FILTERED13 /* Packet filtered */

#define ICMP_PREC_VIOLATION14 /* Precedence violation */

#define ICMP_PREC_CUTOFF15 /* Precedence cut off */

#define NR_ICMP_UNREACH15 /* instead of hardcoding immediate value */

 

c)重定向

 

TYPE(5)

CODE(0-3)

Checksum

Route’s ip

Option

对于option字段,其值为ip头部(包括可选项)加上原始ip数据部分的前8个字节。

第二个32bits代表路由器的wan側地址。

Code类型如下:

#defineICMP_REDIR_NET        0     /* Redirect Net                     */

#defineICMP_REDIR_HOST             1     /* Redirect Host            */

#defineICMP_REDIR_NETTOS  2     /* Redirect Net for TOS        */

#defineICMP_REDIR_HOSTTOS       3     /* Redirect Host for TOS      */

重定向报文仅限于在直接连接到同一网络上的路由器与主机间交互。

 

d)数据包超时

因为每一个ip数据包都有一个ttl计数器,即跳数计数器,当数据包中的ttl的值为0时,就丢弃数据包,并发送一个数据包超时的icmp 报文。下面即是icmp 数据包超时报文的格式

 

TYPE(11)

CODE(0-1)

Checksum

Not used(must set 0)

Option

对于option字段,其值为ip头部(包括可选项)加上原始ip数据部分的前8个字节。

 

对于命令traceroute(windows 下为tracert),即是根据ttl来实现查找到目的站点所有跳点的ip地址的。即先发送3个ttl为1的数据包,根据接收到的icmp 数据包超时报文获取到第一个下一跳地址;然后再发送3个ttl为的数据包,根据接收到的数据包超时报文获取到第二个下一跳地址;依此类推直到找到所有的跳点地址或者已经到了ttl的max值还没有到目的站点则程序返回。

 

基本上这4个icmp报文是最重要的了。

3、 linux中icmp相关的数据结构

 

#defineICMP_ECHOREPLY              0     /* Echo Reply               */

#defineICMP_DEST_UNREACH       3     /* Destination Unreachable    */

#defineICMP_SOURCE_QUENCH    4     /* Source Quench          */

#defineICMP_REDIRECT          5     /* Redirect (change route)     */

#defineICMP_ECHO           8     /* Echo Request                   */

#defineICMP_TIME_EXCEEDED     11    /* Time Exceeded          */

#defineICMP_PARAMETERPROB     12    /* Parameter Problem           */

#defineICMP_TIMESTAMP        13    /* Timestamp Request           */

#defineICMP_TIMESTAMPREPLY    14    /* Timestamp Reply              */

#defineICMP_INFO_REQUEST  15    /* Information Request         */

#defineICMP_INFO_REPLY              16    /* Information Reply            */

#defineICMP_ADDRESS           17    /* Address Mask Request              */

#defineICMP_ADDRESSREPLY 18    /* Address Mask Reply          */

#defineNR_ICMP_TYPES          18

 

 

/*Codes for UNREACH. */

#defineICMP_NET_UNREACH  0     /* Network Unreachable        */

#defineICMP_HOST_UNREACH       1     /* Host Unreachable             */

#defineICMP_PROT_UNREACH       2     /* Protocol Unreachable        */

#defineICMP_PORT_UNREACH       3     /* Port Unreachable              */

#defineICMP_FRAG_NEEDED  4     /* Fragmentation Needed/DF set   */

#defineICMP_SR_FAILED         5     /* Source Route failed          */

#defineICMP_NET_UNKNOWN 6

#defineICMP_HOST_UNKNOWN     7

#defineICMP_HOST_ISOLATED       8

#defineICMP_NET_ANO           9

#defineICMP_HOST_ANO         10

#defineICMP_NET_UNR_TOS   11

#defineICMP_HOST_UNR_TOS 12

#defineICMP_PKT_FILTERED   13    /* Packet filtered */

#defineICMP_PREC_VIOLATION     14    /* Precedence violation */

#defineICMP_PREC_CUTOFF    15    /* Precedence cut off */

#defineNR_ICMP_UNREACH           15    /* instead of hardcoding immediate value */

 

/*Codes for REDIRECT. */

#defineICMP_REDIR_NET        0     /* Redirect Net                     */

#defineICMP_REDIR_HOST             1     /* Redirect Host            */

#defineICMP_REDIR_NETTOS  2     /* Redirect Net for TOS        */

#defineICMP_REDIR_HOSTTOS       3     /* Redirect Host for TOS      */

 

/*Codes for TIME_EXCEEDED. */

#defineICMP_EXC_TTL             0     /* TTL count exceeded          */

#defineICMP_EXC_FRAGTIME 1     /* Fragment Reass time exceeded  */

 

Icmp头部定义:

structicmphdr {

  __u8           type;

  __u8           code;

  __sum16     checksum;

  union {

       struct {

              __be16    id;

              __be16    sequence;

       } echo;

       __be32    gateway;

       struct {

              __be16    __unused;

              __be16    mtu;

       } frag;

  } un;

};

在该数据结构中,前32bits的定义是一样的,而后面32bits的定义,因回显请求与应答、重定向等报文定义不同而有不同的含义。

 

发送icmp报文相关的数据结构。

structicmp_bxm {

       struct sk_buff *skb;//接收到的icmp报文

       int offset;//选项数据在icmp数据中的偏移量

       int data_len;//icmp数据报文长度

 

       struct {

              struct icmphdr icmph;/icmp头部/

              __be32           times[3];

       } data;

       int head_len;//icmp头部长度

       struct ip_options replyopts;//存储的接收icmp报文的选项数据,待发送时使用

       unsigned char  optbuf[40];

};

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值