1. 相关ICMP协议概述
这里只讲解与gettime/getmask有关的ICMP消息类型
时间戳请求
请求端填写发起时间戳
时间戳应答
应答系统收到请求报文时填写接收时间戳;发送应答时填写发送时间戳
地址掩码请求
地址掩码应答
2. gettime流程
ICMP时间戳请求允许系统向另一个系统查询当前的时间,返回的值是自午夜开始计算的毫秒数,提供了毫秒级的分辨率。
请求端填写发起时间戳,接收时间戳、传送时间戳置0
应答端填写接收时间戳、传送时间戳,发起时间戳与请求报文中一致
3. getmask流程
ICMP地址掩码请求用于获取自己的子网掩码,流程比较简单,请求端填写请求报文,32位子网掩码字段填0;应答端填写报文32位子网掩码字段
注意的是该协议主要用于早期的无盘系统,因此现在大多数系统已不支持,对某些主机请求可能没有回应
4. gettime/getmask实现
• 使用SOCK_RAW发送与接收报文
• 时间戳报文-发送时间戳字段填写
时间戳是自午夜开始计算的毫秒数,即UTC,因此用得到时间对86400000取余即可;要注意的是使用gettimeofday得到的是格林尼治时间,计算了时差,如北京12:35对应的icmp_otime = 1623710
• 设置可以发送广播报文
• 对收到数据包处理
首先从IP报头得到IP报头长度
int hlen = ip->ip_hl << 2; // total ip header length
然后定位到ICMP报头,检查各字段合法性,时间戳报文处理
对地址请求报文处理
5. 程序源代码
gettime见http://download.youkuaiyun.com/source/2254635
getmask见http://download.youkuaiyun.com/source/2254643
6. 最终效果
gettime:
getmask: