6_ICMP

  • ICMP 报文由 IP 层负责传输,ICMP 报文的格式以下:算法

类型: 1 byte,用于指定 ICMP 报文的类型.
代码: 1 byte,用于进一步描述 ICMP 报文为什么生成.
检验和: 2 bytes,使用的算法与 IP 首部检验和算法相同,覆盖了整个 ICMP 报文.
其余内容: 不一样类型和代码的 ICMP 报文有不一样的内容.

ICMP 目的不可达

  • 报文格式:shell

    1. 类型: 1 byte,取值为 3.网络

    2. 代码: 1 byte,取值为 [0,16)spa

    3. 检验和: 2 byte,code

    4. 未用位: 4 byte,必须置 0,但当代码字段的值为4('须要分片但设置了不分片比特')时,容许路由器把外出接口的 MTU 填在这个32 bit字的低 16 bit中.接口

    5. 引发该 ICMP 差错报文的 IP 数据包的IP 首部(包括选项)+数据部分的前8字节(正好将 TCP,UDP 的端口号也包含了其中).进程

ICMP 回显

  • ICMP 回显请求,应答报文的格式:路由

类型: 1 byte
代码: 1 byte
检验和: 2 byte
标识符: 2 byte
序列号: 2 byte
额外的数据

请求报文的取值:{8;0;算法生成;任意设置;任意设置;...}
应答报文的取值:{0;0;算法生成;不变;不变;不变}

ICMP 地址掩码请求/应答

  • 用于无盘主机在引导过程当中获取本身所处子网的子网掩码.此时分组格式:字符串

ICMP 地址掩码格式:
类型: 1 byte,
代码: 1 byte,
检验和: 2 byte,
标识符: 2 byte,
序列号: 2 byte,
子网掩码: 4 byte.
请求格式:{17;0;算法生成;多是随机生成;多是随机生成;0}
应答格式:{18;0;算法生成;不变;不变;子网掩码}

    • 其中应答格式中的'子网掩码'必须是必须是'收到 ICMP 地址掩码请求'的网络接口的子网掩码,由于一个主机可能具备多个网络接口,每个网络接口具备不一样的掩码,如:it

# icmpaddrmask 用于向主机名为 argv[1] 的主机发送 ICMP 地址掩码请求
sun$ icmpaddrmask sun  # 此时 ICMP 地址掩码请求会转交给环回接口,因此返回的是环回接口的地址掩码.
received mask= ff000000, from 140.252.13.33
sun$ icmpaddrmask localhost # 此时 ICMP 地址掩码请求直接交给环回接口,
received mask= ff000000, from 127.0.0.

ICMP 时间戳请求/应答

  • 容许主机向另外一个主机查询当前的时间,下面的'时间戳'是指自午夜(不是 1900-01-01 00:00:00 了)开始计算的毫秒数,协调的统一时间 UTC.此时 ICMP 报文格式:

类型: 1 byte,
代码: 1 byte,
检验和: 2 byte,
标识符: 2 byte,
序列号: 2 byte,
发起时间戳: 4 byte
接受时间戳: 4 byte
传送时间戳: 4 byte

# 请求格式:
{13;0;算法生成;多是随机生成;多是随机生成;发送'ICMP 时间戳请求报文'时的时间戳;0(TODO 不肯定),0 }
# 应答格式:
{14,0,算法生成,不变,不变,不变,接受到'ICMP 时间戳请求报文'时的时间戳,发送'ICMP 时间戳应答报文'时的时间戳};

  • 根据 ICMP 时间戳应答报文的内容与 RTT 调整时间:

var orig; /* 发起时间戳 */
var recv; /* 接受时间戳 */
var xmit; /* 传送时间戳 */  
var rtt;  /* RTT,往返时间,假设 RTT 的一半用于请求报文的传输,另外一半用于应答报文的传输 */
则本机时间应该加上 recv-(orig+rtt/2);

若干个概念

  • 日期服务程序,以人们可读的格式返回当前的时间和日期,是一行 ASCII 字符.

  • 时间服务程序,返回的是一个 32 bit 的二制进数值,表示自 UTC,1900年1月1日午夜起算的秒数

  • NTP,采用先进的技术来保证 LAN 或 WAN 上的一组主机的时钟偏差在毫秒级之内.

BSD 系统对 ICMP 报文的处理

  • 仅看成一个参考.对处理方法的解释:

    • 若处理方法指明为'用户进程',则报文就被传送到全部在内核中登记的用户进程,以读取收到的 ICMP 报文.若是不存在任何这样的用户进程,那么报文就悄悄地被丢弃

    • 若处理方法指明为'内核',则 ICMP 报文就由内核来处理,在处理完毕以后,内核会将该 ICMP 报文拷贝给'感兴趣'的用户进程(即已经在内核中登记的用户进程)

    • 标明的是引号内的一串字符,那么它就是对应的 Unix 差错,即 errno 的字符串描述.如当内核收到类型为3,代码为3的 ICMP 差错报文时,内核会根据差错报文中带有的端口号来找到引发差错的用户进程,而后让该用户进程中的 errno 变量取值为'链接被拒绝'.

本站公众号
   欢迎关注本站公众号,获取更多信息