以Sync报文为例,linux端执行sudo ptp4l -i eth0 -m -S,给windows端发送主节点报文,windows端用wireshark抓取到的报文如下图:
报文解析:
01 00 5e 00 01 81 :windows端mac地址;
78 d0 04 2c 63 0e:linux端mac地址;
08 00:IPv4类型;
45 00:4表示ip版本号为ip第4版;5表示首部长度为5个32 bit字长,即为20字节;
00 48:表示ip总长度为72字节,其中ip数据部分为52字节;
bc c6 :标识符,用来唯一标识主机发送的每一份数据报,通常每发一份报文,该值加1。;
40 00:表示3 bit标志、13 bit段偏移量,3bit的标志用来表示一份数据报文是否要求分段,这里40表示不分段;如果一份数据报要求分段的话,13bit的段偏移字段指明该段偏移距原始数据报开始的位置;
01:time to live(TTL),占8比特,用来设置数据报最多可以经过的路由器数。由发送数据的源主机设置,通常为32、64、128等。每经过一个路由器,其值减1,直到0时该数据报被丢弃;
11:十进制17表示udp报文类型,十进制6表示tcp报文;
19 50:表示头检验和,计算方法在下面;
c0 a8 01 65:linux端ip地址,192.168.1.101;
e0 00 01 81:ptp ip地址,224.0.1.129;
01 3f 01 3f:源端口号和目的端口号;
00 34:udp报文长度,52字节;
78 2f:udp报文校验和,计算方法如下2;
00 12 ......最后:PTP Sync报文内容,共44字节,包含34字节头和10字节时间戳信息;
头校验和计算方法:从帧长度45 00开始,到PTP IP e0000181截止,累加得到:
4500+0048+bcc6+4000+0111+c0a8+0165+e000+0181=2e6ad,把最高位的2bit加到最低位后最高位清零,得到e6ad+2=e6af,将结果取反得到1950;
udp检验和计算方法:包含UDP伪首部、UDP首部、UDP数据,累加后将得到的最高位加到最低位并清零最高位,取反后得到校验和。详细解释:
UDP伪首部包括:
4字节的源IP地址,c0 a8 01 65;
4字节的目的IP地址:e0 00 01 81;
1字节的udp类型:11;
2字节的UDP长度:00 34;
UDP首部包括:
2字节的源端口号:01 3f;
2字节的目的端口号:01 3f;
2字节的UDP长度:00 34(又加一遍);
2字节的UDP校验和:这个值是在计算过程中不用加它;
UDP数据:这里的数据为PTP协议的Sync报文,从00 12 一直到最后;
因此,校验和为:
c0a8+0165+e000+0181+0011+0034+013f+013f+0034+0012+002c+0000+0200+0000+0000+0000+0000+0000+0000+78d0+04ff+fe2c+630e+0001+0000+0000+0000+0000+0000+0000+0000=387cd,最高位加到最低位后清零,得到87d0,取反后为:782f,与wireshark抓到的数据一致。