96-ICMP 协议(时间戳请求与应答)

来源:互联网 发布:表白源码 编辑:程序博客网 时间:2024/05/29 05:52

ICMP 时间戳请求允许系统向另一个系统查询当前的时间。

1. ICMP 时间戳

1.1 首部格式


这里写图片描述
图1 ICMP 时间戳请求与应答报文

它的 type 字段为 17(请求)或 18(应答),code 字段为 0.

  • 发起时间戳:发送者的发送时间,由发送者填写
  • 接收时间戳:接收者的接收时间,由接收者填写
  • 发送时间戳:接收者的发送时间,由接收者填写

通常,接收时间戳等于发送时间戳。可以理解为接收者接收到 ICMP 时间戳请求报文后立即发送应答报文回去。

ICMP 时间戳请求与应答报文提供了毫秒级的分辨率,并且返回的时间是从午夜 00:00 开始到当前时间的毫秒数。这是它的一个缺陷。

1.2 ICMP 时间戳结构体

// icmp 时间戳头部struct icmp_time {  uint8_t icmp_type;  uint8_t icmp_code;  uint16_t icmp_cksum;  uint16_t icmp_id;  uint16_t icmp_seq;  uint32_t icmp_origtime;  uint32_t icmp_recvtime;  uint32_t icmp_sendtime;};

2. 程序设计

2.1 程序路径

本文使用的程序托管在 gitos 上:http://git.oschina.net/ivan_allen/unp

如果你已经 clone 过这个代码了,请使用 Git pull 更新一下。本节程序所使用的程序路径是 unp/program/icmp/icmptime.

2.2 注意

程序的编写方法其实和前面的 ping 命令基本上差不多,但是在这里需要注意的几个地方:

  • 发送的时候,时间戳需要填写午夜到当前的毫秒数,计算公式如下:
// 绝对时间cur = now() / 1000;// 午夜到当前的毫秒数origtime = cur % (24*60*60*1000);
  • 接收到的时间,都是网络字节序,打印它或者使用它的时候,注意要转换成本机字节序。我们自己在填写发起时间戳的时候,可以直接填写本机字节序,也可以填写网络字节序,因为接收者不会修改发起时间戳的任何内容。

3. 实验


这里写图片描述
图1 发送时间戳请求给 mars 主机并得到回应

要注意的是,并不是所有主机都会回应 ICMP 时间戳请求。很多主机都将此功能关闭了,因此你在运行的时候,可能会出现 no reply 字样,如图 2 所示。大量的 ICMP 请求会造成服务器的负担,为了防止被人利用,应该把服务器上的这些功能关掉。


这里写图片描述
图2 有些主机并不会产生 ICMP 时间戳应答报文

使用下面的命令可以把 ICMP 时间戳请求与应答报文关闭:

[mars]$ sudo iptables -A INPUT -p icmp --icmp-type 13 -j DROP[mars]$ sudo iptables -A OUTPUT -p icmp --icmp-type 14 -j DROP


这里写图片描述
图3 将 mars 上的 ICMP 时间戳请求与应答报文丢弃

4. 总结

  • 掌握 ICMP 时间戳请求与应答