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

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 时间戳请求与应答
  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值