1*05b00f60SXin Li /*
2*05b00f60SXin Li * Redistribution and use in source and binary forms, with or without
3*05b00f60SXin Li * modification, are permitted provided that: (1) source code
4*05b00f60SXin Li * distributions retain the above copyright notice and this paragraph
5*05b00f60SXin Li * in its entirety, and (2) distributions including binary code include
6*05b00f60SXin Li * the above copyright notice and this paragraph in its entirety in
7*05b00f60SXin Li * the documentation or other materials provided with the distribution.
8*05b00f60SXin Li * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9*05b00f60SXin Li * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10*05b00f60SXin Li * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11*05b00f60SXin Li * FOR A PARTICULAR PURPOSE.
12*05b00f60SXin Li *
13*05b00f60SXin Li * Original code by Partha S. Ghosh (psglinux dot gmail dot com)
14*05b00f60SXin Li */
15*05b00f60SXin Li
16*05b00f60SXin Li /* \summary: Precision Time Protocol (PTP) printer */
17*05b00f60SXin Li
18*05b00f60SXin Li /* specification: https://standards.ieee.org/findstds/standard/1588-2008.html*/
19*05b00f60SXin Li
20*05b00f60SXin Li #ifdef HAVE_CONFIG_H
21*05b00f60SXin Li #include <config.h>
22*05b00f60SXin Li #endif
23*05b00f60SXin Li
24*05b00f60SXin Li #include "netdissect-stdinc.h"
25*05b00f60SXin Li #include "netdissect.h"
26*05b00f60SXin Li #include "extract.h"
27*05b00f60SXin Li
28*05b00f60SXin Li /*
29*05b00f60SXin Li * PTP header
30*05b00f60SXin Li * 0 1 2 3
31*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
32*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33*05b00f60SXin Li * | R | |msgtype| version | Msg Len |
34*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35*05b00f60SXin Li * | domain No | rsvd1 | flag Field |
36*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37*05b00f60SXin Li * | Correction NS |
38*05b00f60SXin Li * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39*05b00f60SXin Li * | | Correction Sub NS |
40*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41*05b00f60SXin Li * | Reserved2 |
42*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43*05b00f60SXin Li * | Clock Identity |
44*05b00f60SXin Li * | |
45*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46*05b00f60SXin Li * | Port Identity | Sequence ID |
47*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48*05b00f60SXin Li * | control | log msg int |
49*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
51*05b00f60SXin Li * 0 1 2 3
52*05b00f60SXin Li *
53*05b00f60SXin Li * Announce Message (msg type=0xB)
54*05b00f60SXin Li * 0 1 2 3
55*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57*05b00f60SXin Li * | |
58*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
59*05b00f60SXin Li * | Seconds |
60*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61*05b00f60SXin Li * | Nano Seconds |
62*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63*05b00f60SXin Li * | Origin Cur UTC Offset | Reserved | GM Prio 1 |
64*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65*05b00f60SXin Li * |GM Clock Class | GM Clock Accu | GM Clock Variance |
66*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67*05b00f60SXin Li * | GM Prio 2 | |
68*05b00f60SXin Li * +-+-+-+-+-+-+-+-+ +
69*05b00f60SXin Li * | GM Clock Identity |
70*05b00f60SXin Li * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71*05b00f60SXin Li * | | Steps Removed | Time Source |
72*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
74*05b00f60SXin Li * 0 1 2 3
75*05b00f60SXin Li *
76*05b00f60SXin Li * Sync Message (msg type=0x0)
77*05b00f60SXin Li * 0 1 2 3
78*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
79*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80*05b00f60SXin Li * | |
81*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
82*05b00f60SXin Li * | Seconds |
83*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84*05b00f60SXin Li * | Nano Seconds |
85*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86*05b00f60SXin Li *
87*05b00f60SXin Li * Delay Request Message (msg type=0x1)
88*05b00f60SXin Li * 0 1 2 3
89*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
90*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
91*05b00f60SXin Li * | |
92*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
93*05b00f60SXin Li * | Origin Time Stamp Seconds |
94*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95*05b00f60SXin Li * | Nano Seconds |
96*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
97*05b00f60SXin Li *
98*05b00f60SXin Li * Followup Message (msg type=0x8)
99*05b00f60SXin Li * 0 1 2 3
100*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
101*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102*05b00f60SXin Li * | |
103*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
104*05b00f60SXin Li * | Precise Origin Time Stamp Seconds |
105*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106*05b00f60SXin Li * | Nano Seconds |
107*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108*05b00f60SXin Li *
109*05b00f60SXin Li * Delay Resp Message (msg type=0x9)
110*05b00f60SXin Li * 0 1 2 3
111*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
112*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113*05b00f60SXin Li * | |
114*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
115*05b00f60SXin Li * | Seconds |
116*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117*05b00f60SXin Li * | Nano Seconds |
118*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119*05b00f60SXin Li * | Port Identity |
120*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
121*05b00f60SXin Li *
122*05b00f60SXin Li * PDelay Request Message (msg type=0x2)
123*05b00f60SXin Li * 0 1 2 3
124*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
125*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126*05b00f60SXin Li * | |
127*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
128*05b00f60SXin Li * | Origin Time Stamp Seconds |
129*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130*05b00f60SXin Li * | Origin Time Stamp Nano Seconds |
131*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
132*05b00f60SXin Li * | Port Identity |
133*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
134*05b00f60SXin Li *
135*05b00f60SXin Li * PDelay Response Message (msg type=0x3)
136*05b00f60SXin Li * 0 1 2 3
137*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
138*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
139*05b00f60SXin Li * | |
140*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
141*05b00f60SXin Li * | Request receipt Time Stamp Seconds |
142*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
143*05b00f60SXin Li * | Nano Seconds |
144*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145*05b00f60SXin Li * | Requesting Port Identity |
146*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147*05b00f60SXin Li *
148*05b00f60SXin Li * PDelay Resp Follow up Message (msg type=0xA)
149*05b00f60SXin Li * 0 1 2 3
150*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
151*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
152*05b00f60SXin Li * | |
153*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
154*05b00f60SXin Li * | Response Origin Time Stamp Seconds |
155*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156*05b00f60SXin Li * | Nano Seconds |
157*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158*05b00f60SXin Li * | Requesting Port Identity |
159*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160*05b00f60SXin Li *
161*05b00f60SXin Li * Signalling Message (msg type=0xC)
162*05b00f60SXin Li * 0 1 2 3
163*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
164*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165*05b00f60SXin Li * | Requesting Port Identity |
166*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167*05b00f60SXin Li *
168*05b00f60SXin Li * Management Message (msg type=0xD)
169*05b00f60SXin Li * 0 1 2 3
170*05b00f60SXin Li * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
171*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
172*05b00f60SXin Li * | Requesting Port Identity |
173*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
174*05b00f60SXin Li * |Start Bndry Hps| Boundary Hops | flags | Reserved |
175*05b00f60SXin Li * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
176*05b00f60SXin Li *
177*05b00f60SXin Li */
178*05b00f60SXin Li
179*05b00f60SXin Li /* Values from IEEE1588-2008: 13.3.2.2 messageType (Enumeration4) */
180*05b00f60SXin Li #define M_SYNC 0x0
181*05b00f60SXin Li #define M_DELAY_REQ 0x1
182*05b00f60SXin Li #define M_PDELAY_REQ 0x2
183*05b00f60SXin Li #define M_PDELAY_RESP 0x3
184*05b00f60SXin Li #define M_FOLLOW_UP 0x8
185*05b00f60SXin Li #define M_DELAY_RESP 0x9
186*05b00f60SXin Li #define M_PDELAY_RESP_FOLLOW_UP 0xA
187*05b00f60SXin Li #define M_ANNOUNCE 0xB
188*05b00f60SXin Li #define M_SIGNALLING 0xC
189*05b00f60SXin Li #define M_MANAGEMENT 0xD
190*05b00f60SXin Li
191*05b00f60SXin Li static const struct tok ptp_msg_type[] = {
192*05b00f60SXin Li { M_SYNC, "sync msg"},
193*05b00f60SXin Li { M_DELAY_REQ, "delay req msg"},
194*05b00f60SXin Li { M_PDELAY_REQ, "peer delay req msg"},
195*05b00f60SXin Li { M_PDELAY_RESP, "peer delay resp msg"},
196*05b00f60SXin Li { M_FOLLOW_UP, "follow up msg"},
197*05b00f60SXin Li { M_DELAY_RESP, "delay resp msg"},
198*05b00f60SXin Li { M_PDELAY_RESP_FOLLOW_UP, "pdelay resp fup msg"},
199*05b00f60SXin Li { M_ANNOUNCE, "announce msg"},
200*05b00f60SXin Li { M_SIGNALLING, "signalling msg"},
201*05b00f60SXin Li { M_MANAGEMENT, "management msg"},
202*05b00f60SXin Li { 0, NULL}
203*05b00f60SXin Li };
204*05b00f60SXin Li
205*05b00f60SXin Li /* Values from IEEE1588-2008: 13.3.2.10 controlField (UInteger8) */
206*05b00f60SXin Li /*
207*05b00f60SXin Li * The use of this field by the receiver is deprecated.
208*05b00f60SXin Li * NOTE-This field is provided for compatibility with hardware designed
209*05b00f60SXin Li * to conform to version 1 of this standard.
210*05b00f60SXin Li */
211*05b00f60SXin Li #define C_SYNC 0x0
212*05b00f60SXin Li #define C_DELAY_REQ 0x1
213*05b00f60SXin Li #define C_FOLLOW_UP 0x2
214*05b00f60SXin Li #define C_DELAY_RESP 0x3
215*05b00f60SXin Li #define C_MANAGEMENT 0x4
216*05b00f60SXin Li #define C_OTHER 0x5
217*05b00f60SXin Li
218*05b00f60SXin Li static const struct tok ptp_control_field[] = {
219*05b00f60SXin Li { C_SYNC, "Sync"},
220*05b00f60SXin Li { C_DELAY_REQ, "Delay_Req"},
221*05b00f60SXin Li { C_FOLLOW_UP, "Follow_Up"},
222*05b00f60SXin Li { C_DELAY_RESP, "Delay_Resp"},
223*05b00f60SXin Li { C_MANAGEMENT, "Management"},
224*05b00f60SXin Li { C_OTHER, "Other"},
225*05b00f60SXin Li { 0, NULL}
226*05b00f60SXin Li };
227*05b00f60SXin Li
228*05b00f60SXin Li #define PTP_TRUE 1
229*05b00f60SXin Li #define PTP_FALSE !PTP_TRUE
230*05b00f60SXin Li
231*05b00f60SXin Li #define PTP_HDR_LEN 0x22
232*05b00f60SXin Li
233*05b00f60SXin Li /* mask based on the first byte */
234*05b00f60SXin Li #define PTP_VERS_MASK 0xFF
235*05b00f60SXin Li #define PTP_V1_COMPAT 0x10
236*05b00f60SXin Li #define PTP_MSG_TYPE_MASK 0x0F
237*05b00f60SXin Li
238*05b00f60SXin Li /*mask based 2byte */
239*05b00f60SXin Li #define PTP_DOMAIN_MASK 0xFF00
240*05b00f60SXin Li #define PTP_RSVD1_MASK 0xFF
241*05b00f60SXin Li #define PTP_CONTROL_MASK 0xFF
242*05b00f60SXin Li #define PTP_LOGMSG_MASK 0xFF
243*05b00f60SXin Li
244*05b00f60SXin Li /* mask based on the flags 2 bytes */
245*05b00f60SXin Li
246*05b00f60SXin Li #define PTP_L161_MASK 0x1
247*05b00f60SXin Li #define PTP_L1_59_MASK 0x2
248*05b00f60SXin Li #define PTP_UTC_REASONABLE_MASK 0x4
249*05b00f60SXin Li #define PTP_TIMESCALE_MASK 0x8
250*05b00f60SXin Li #define PTP_TIME_TRACABLE_MASK 0x10
251*05b00f60SXin Li #define PTP_FREQUENCY_TRACABLE_MASK 0x20
252*05b00f60SXin Li #define PTP_ALTERNATE_MASTER_MASK 0x100
253*05b00f60SXin Li #define PTP_TWO_STEP_MASK 0x200
254*05b00f60SXin Li #define PTP_UNICAST_MASK 0x400
255*05b00f60SXin Li #define PTP_PROFILE_SPEC_1_MASK 0x1000
256*05b00f60SXin Li #define PTP_PROFILE_SPEC_2_MASK 0x2000
257*05b00f60SXin Li #define PTP_SECURITY_MASK 0x4000
258*05b00f60SXin Li #define PTP_FLAGS_UNKNOWN_MASK 0x18C0
259*05b00f60SXin Li
260*05b00f60SXin Li static const struct tok ptp_flag_values[] = {
261*05b00f60SXin Li { PTP_L161_MASK, "l1 61"},
262*05b00f60SXin Li { PTP_L1_59_MASK, "l1 59"},
263*05b00f60SXin Li { PTP_UTC_REASONABLE_MASK, "utc reasonable"},
264*05b00f60SXin Li { PTP_TIMESCALE_MASK, "timescale"},
265*05b00f60SXin Li { PTP_TIME_TRACABLE_MASK, "time tracable"},
266*05b00f60SXin Li { PTP_FREQUENCY_TRACABLE_MASK, "frequency tracable"},
267*05b00f60SXin Li { PTP_ALTERNATE_MASTER_MASK, "alternate master"},
268*05b00f60SXin Li { PTP_TWO_STEP_MASK, "two step"},
269*05b00f60SXin Li { PTP_UNICAST_MASK, "unicast"},
270*05b00f60SXin Li { PTP_PROFILE_SPEC_1_MASK, "profile specific 1"},
271*05b00f60SXin Li { PTP_PROFILE_SPEC_2_MASK, "profile specific 2"},
272*05b00f60SXin Li { PTP_SECURITY_MASK, "security mask"},
273*05b00f60SXin Li { PTP_FLAGS_UNKNOWN_MASK, "unknown"},
274*05b00f60SXin Li {0, NULL}
275*05b00f60SXin Li };
276*05b00f60SXin Li
277*05b00f60SXin Li static const char *p_porigin_ts = "preciseOriginTimeStamp";
278*05b00f60SXin Li static const char *p_origin_ts = "originTimeStamp";
279*05b00f60SXin Li static const char *p_recv_ts = "receiveTimeStamp";
280*05b00f60SXin Li
281*05b00f60SXin Li #define PTP_VER_1 0x1
282*05b00f60SXin Li #define PTP_VER_2 0x2
283*05b00f60SXin Li
284*05b00f60SXin Li #define PTP_UCHAR_LEN sizeof(uint8_t)
285*05b00f60SXin Li #define PTP_UINT16_LEN sizeof(uint16_t)
286*05b00f60SXin Li #define PTP_UINT32_LEN sizeof(uint32_t)
287*05b00f60SXin Li #define PTP_6BYTES_LEN sizeof(uint32_t)+sizeof(uint16_t)
288*05b00f60SXin Li #define PTP_UINT64_LEN sizeof(uint64_t)
289*05b00f60SXin Li
290*05b00f60SXin Li static void ptp_print_1(netdissect_options *ndo);
291*05b00f60SXin Li static void ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int len);
292*05b00f60SXin Li
293*05b00f60SXin Li static void ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype);
294*05b00f60SXin Li static void ptp_print_timestamp_identity(netdissect_options *ndo, const u_char *bp, u_int *len, const char *ttype);
295*05b00f60SXin Li static void ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len);
296*05b00f60SXin Li static void ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len);
297*05b00f60SXin Li static void ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len);
298*05b00f60SXin Li
299*05b00f60SXin Li static void
print_field(netdissect_options * ndo,const char * st,uint32_t flen,const u_char * bp,u_int * len,uint8_t hex)300*05b00f60SXin Li print_field(netdissect_options *ndo, const char *st, uint32_t flen,
301*05b00f60SXin Li const u_char *bp, u_int *len, uint8_t hex)
302*05b00f60SXin Li {
303*05b00f60SXin Li uint8_t u8_val;
304*05b00f60SXin Li uint16_t u16_val;
305*05b00f60SXin Li uint32_t u32_val;
306*05b00f60SXin Li uint64_t u64_val;
307*05b00f60SXin Li
308*05b00f60SXin Li switch(flen) {
309*05b00f60SXin Li case PTP_UCHAR_LEN:
310*05b00f60SXin Li u8_val = GET_U_1(bp);
311*05b00f60SXin Li ND_PRINT(", %s", st);
312*05b00f60SXin Li if (hex)
313*05b00f60SXin Li ND_PRINT(" 0x%x", u8_val);
314*05b00f60SXin Li else
315*05b00f60SXin Li ND_PRINT(" %u", u8_val);
316*05b00f60SXin Li *len -= 1; bp += 1;
317*05b00f60SXin Li break;
318*05b00f60SXin Li case PTP_UINT16_LEN:
319*05b00f60SXin Li u16_val = GET_BE_U_2(bp);
320*05b00f60SXin Li ND_PRINT(", %s", st);
321*05b00f60SXin Li if (hex)
322*05b00f60SXin Li ND_PRINT(" 0x%x", u16_val);
323*05b00f60SXin Li else
324*05b00f60SXin Li ND_PRINT(" %u", u16_val);
325*05b00f60SXin Li *len -= 2; bp += 2;
326*05b00f60SXin Li break;
327*05b00f60SXin Li case PTP_UINT32_LEN:
328*05b00f60SXin Li u32_val = GET_BE_U_4(bp);
329*05b00f60SXin Li ND_PRINT(", %s", st);
330*05b00f60SXin Li if (hex)
331*05b00f60SXin Li ND_PRINT(" 0x%x", u32_val);
332*05b00f60SXin Li else
333*05b00f60SXin Li ND_PRINT(" %u", u32_val);
334*05b00f60SXin Li *len -= 4; bp += 4;
335*05b00f60SXin Li break;
336*05b00f60SXin Li case PTP_UINT64_LEN:
337*05b00f60SXin Li u64_val = GET_BE_U_8(bp);
338*05b00f60SXin Li ND_PRINT(", %s", st);
339*05b00f60SXin Li if (hex)
340*05b00f60SXin Li ND_PRINT(" 0x%"PRIx64, u64_val);
341*05b00f60SXin Li else
342*05b00f60SXin Li ND_PRINT(" 0x%"PRIu64, u64_val);
343*05b00f60SXin Li *len -= 8; bp += 8;
344*05b00f60SXin Li break;
345*05b00f60SXin Li default:
346*05b00f60SXin Li break;
347*05b00f60SXin Li }
348*05b00f60SXin Li }
349*05b00f60SXin Li
350*05b00f60SXin Li static void
ptp_print_1(netdissect_options * ndo)351*05b00f60SXin Li ptp_print_1(netdissect_options *ndo)
352*05b00f60SXin Li {
353*05b00f60SXin Li ND_PRINT(" (not implemented)");
354*05b00f60SXin Li }
355*05b00f60SXin Li
356*05b00f60SXin Li static void
ptp_print_2(netdissect_options * ndo,const u_char * bp,u_int length)357*05b00f60SXin Li ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int length)
358*05b00f60SXin Li {
359*05b00f60SXin Li u_int len = length;
360*05b00f60SXin Li uint16_t msg_len, flags, port_id, seq_id;
361*05b00f60SXin Li uint8_t foct, domain_no, msg_type, v1_compat, rsvd1, lm_int, control;
362*05b00f60SXin Li uint64_t ns_corr;
363*05b00f60SXin Li uint16_t sns_corr;
364*05b00f60SXin Li uint32_t rsvd2;
365*05b00f60SXin Li uint64_t clk_id;
366*05b00f60SXin Li
367*05b00f60SXin Li foct = GET_U_1(bp);
368*05b00f60SXin Li v1_compat = foct & PTP_V1_COMPAT;
369*05b00f60SXin Li ND_PRINT(", v1 compat : %s", v1_compat?"yes":"no");
370*05b00f60SXin Li msg_type = foct & PTP_MSG_TYPE_MASK;
371*05b00f60SXin Li ND_PRINT(", msg type : %s", tok2str(ptp_msg_type, "Reserved", msg_type));
372*05b00f60SXin Li
373*05b00f60SXin Li /* msg length */
374*05b00f60SXin Li len -= 2; bp += 2; msg_len = GET_BE_U_2(bp); ND_PRINT(", length : %u", msg_len);
375*05b00f60SXin Li
376*05b00f60SXin Li /* domain */
377*05b00f60SXin Li len -= 2; bp += 2; domain_no = (GET_BE_U_2(bp) & PTP_DOMAIN_MASK) >> 8; ND_PRINT(", domain : %u", domain_no);
378*05b00f60SXin Li
379*05b00f60SXin Li /* rsvd 1*/
380*05b00f60SXin Li rsvd1 = GET_BE_U_2(bp) & PTP_RSVD1_MASK;
381*05b00f60SXin Li ND_PRINT(", reserved1 : %u", rsvd1);
382*05b00f60SXin Li
383*05b00f60SXin Li /* flags */
384*05b00f60SXin Li len -= 2; bp += 2; flags = GET_BE_U_2(bp); ND_PRINT(", Flags [%s]", bittok2str(ptp_flag_values, "none", flags));
385*05b00f60SXin Li
386*05b00f60SXin Li /* correction NS (48 bits) */
387*05b00f60SXin Li len -= 2; bp += 2; ns_corr = GET_BE_U_6(bp); ND_PRINT(", NS correction : %"PRIu64, ns_corr);
388*05b00f60SXin Li
389*05b00f60SXin Li /* correction sub NS (16 bits) */
390*05b00f60SXin Li len -= 6; bp += 6; sns_corr = GET_BE_U_2(bp); ND_PRINT(", sub NS correction : %u", sns_corr);
391*05b00f60SXin Li
392*05b00f60SXin Li /* Reserved 2 */
393*05b00f60SXin Li len -= 2; bp += 2; rsvd2 = GET_BE_U_4(bp); ND_PRINT(", reserved2 : %u", rsvd2);
394*05b00f60SXin Li
395*05b00f60SXin Li /* clock identity */
396*05b00f60SXin Li len -= 4; bp += 4; clk_id = GET_BE_U_8(bp); ND_PRINT(", clock identity : 0x%"PRIx64, clk_id);
397*05b00f60SXin Li
398*05b00f60SXin Li /* port identity */
399*05b00f60SXin Li len -= 8; bp += 8; port_id = GET_BE_U_2(bp); ND_PRINT(", port id : %u", port_id);
400*05b00f60SXin Li
401*05b00f60SXin Li /* sequence ID */
402*05b00f60SXin Li len -= 2; bp += 2; seq_id = GET_BE_U_2(bp); ND_PRINT(", seq id : %u", seq_id);
403*05b00f60SXin Li
404*05b00f60SXin Li /* control */
405*05b00f60SXin Li len -= 2; bp += 2; control = GET_U_1(bp) ;
406*05b00f60SXin Li ND_PRINT(", control : %u (%s)", control, tok2str(ptp_control_field, "Reserved", control));
407*05b00f60SXin Li
408*05b00f60SXin Li /* log message interval */
409*05b00f60SXin Li lm_int = GET_BE_U_2(bp) & PTP_LOGMSG_MASK; ND_PRINT(", log message interval : %u", lm_int); len -= 2; bp += 2;
410*05b00f60SXin Li
411*05b00f60SXin Li switch(msg_type) {
412*05b00f60SXin Li case M_SYNC:
413*05b00f60SXin Li ptp_print_timestamp(ndo, bp, &len, p_origin_ts);
414*05b00f60SXin Li break;
415*05b00f60SXin Li case M_DELAY_REQ:
416*05b00f60SXin Li ptp_print_timestamp(ndo, bp, &len, p_origin_ts);
417*05b00f60SXin Li break;
418*05b00f60SXin Li case M_PDELAY_REQ:
419*05b00f60SXin Li ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts);
420*05b00f60SXin Li break;
421*05b00f60SXin Li case M_PDELAY_RESP:
422*05b00f60SXin Li ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts);
423*05b00f60SXin Li break;
424*05b00f60SXin Li case M_FOLLOW_UP:
425*05b00f60SXin Li ptp_print_timestamp(ndo, bp, &len, p_porigin_ts);
426*05b00f60SXin Li break;
427*05b00f60SXin Li case M_DELAY_RESP:
428*05b00f60SXin Li ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts);
429*05b00f60SXin Li break;
430*05b00f60SXin Li case M_PDELAY_RESP_FOLLOW_UP:
431*05b00f60SXin Li ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts);
432*05b00f60SXin Li break;
433*05b00f60SXin Li case M_ANNOUNCE:
434*05b00f60SXin Li ptp_print_announce_msg(ndo, bp, &len);
435*05b00f60SXin Li break;
436*05b00f60SXin Li case M_SIGNALLING:
437*05b00f60SXin Li ptp_print_port_id(ndo, bp, &len);
438*05b00f60SXin Li break;
439*05b00f60SXin Li case M_MANAGEMENT:
440*05b00f60SXin Li ptp_print_mgmt_msg(ndo, bp, &len);
441*05b00f60SXin Li break;
442*05b00f60SXin Li default:
443*05b00f60SXin Li break;
444*05b00f60SXin Li }
445*05b00f60SXin Li }
446*05b00f60SXin Li /*
447*05b00f60SXin Li * PTP general message
448*05b00f60SXin Li */
449*05b00f60SXin Li void
ptp_print(netdissect_options * ndo,const u_char * bp,u_int length)450*05b00f60SXin Li ptp_print(netdissect_options *ndo, const u_char *bp, u_int length)
451*05b00f60SXin Li {
452*05b00f60SXin Li u_int vers;
453*05b00f60SXin Li
454*05b00f60SXin Li ndo->ndo_protocol = "ptp";
455*05b00f60SXin Li ND_LCHECK_U(length, PTP_HDR_LEN);
456*05b00f60SXin Li vers = GET_BE_U_2(bp) & PTP_VERS_MASK;
457*05b00f60SXin Li ND_PRINT("PTPv%u",vers);
458*05b00f60SXin Li switch(vers) {
459*05b00f60SXin Li case PTP_VER_1:
460*05b00f60SXin Li ptp_print_1(ndo);
461*05b00f60SXin Li break;
462*05b00f60SXin Li case PTP_VER_2:
463*05b00f60SXin Li ptp_print_2(ndo, bp, length);
464*05b00f60SXin Li break;
465*05b00f60SXin Li default:
466*05b00f60SXin Li //ND_PRINT("ERROR: unknown-version\n");
467*05b00f60SXin Li break;
468*05b00f60SXin Li }
469*05b00f60SXin Li return;
470*05b00f60SXin Li
471*05b00f60SXin Li invalid:
472*05b00f60SXin Li nd_print_invalid(ndo);
473*05b00f60SXin Li }
474*05b00f60SXin Li
475*05b00f60SXin Li static void
ptp_print_timestamp(netdissect_options * ndo,const u_char * bp,u_int * len,const char * stype)476*05b00f60SXin Li ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype)
477*05b00f60SXin Li {
478*05b00f60SXin Li uint64_t secs;
479*05b00f60SXin Li uint32_t nsecs;
480*05b00f60SXin Li
481*05b00f60SXin Li ND_PRINT(", %s :", stype);
482*05b00f60SXin Li /* sec time stamp 6 bytes */
483*05b00f60SXin Li secs = GET_BE_U_6(bp);
484*05b00f60SXin Li ND_PRINT(" %"PRIu64" seconds,", secs);
485*05b00f60SXin Li *len -= 6;
486*05b00f60SXin Li bp += 6;
487*05b00f60SXin Li
488*05b00f60SXin Li /* NS time stamp 4 bytes */
489*05b00f60SXin Li nsecs = GET_BE_U_4(bp);
490*05b00f60SXin Li ND_PRINT(" %u nanoseconds", nsecs);
491*05b00f60SXin Li *len -= 4;
492*05b00f60SXin Li bp += 4;
493*05b00f60SXin Li }
494*05b00f60SXin Li static void
ptp_print_timestamp_identity(netdissect_options * ndo,const u_char * bp,u_int * len,const char * ttype)495*05b00f60SXin Li ptp_print_timestamp_identity(netdissect_options *ndo,
496*05b00f60SXin Li const u_char *bp, u_int *len, const char *ttype)
497*05b00f60SXin Li {
498*05b00f60SXin Li uint64_t secs;
499*05b00f60SXin Li uint32_t nsecs;
500*05b00f60SXin Li uint16_t port_id;
501*05b00f60SXin Li uint64_t port_identity;
502*05b00f60SXin Li
503*05b00f60SXin Li ND_PRINT(", %s :", ttype);
504*05b00f60SXin Li /* sec time stamp 6 bytes */
505*05b00f60SXin Li secs = GET_BE_U_6(bp);
506*05b00f60SXin Li ND_PRINT(" %"PRIu64" seconds,", secs);
507*05b00f60SXin Li *len -= 6;
508*05b00f60SXin Li bp += 6;
509*05b00f60SXin Li
510*05b00f60SXin Li /* NS time stamp 4 bytes */
511*05b00f60SXin Li nsecs = GET_BE_U_4(bp);
512*05b00f60SXin Li ND_PRINT(" %u nanoseconds", nsecs);
513*05b00f60SXin Li *len -= 4;
514*05b00f60SXin Li bp += 4;
515*05b00f60SXin Li
516*05b00f60SXin Li /* port identity*/
517*05b00f60SXin Li port_identity = GET_BE_U_8(bp);
518*05b00f60SXin Li ND_PRINT(", port identity : 0x%"PRIx64, port_identity);
519*05b00f60SXin Li *len -= 8;
520*05b00f60SXin Li bp += 8;
521*05b00f60SXin Li
522*05b00f60SXin Li /* port id */
523*05b00f60SXin Li port_id = GET_BE_U_2(bp);
524*05b00f60SXin Li ND_PRINT(", port id : %u", port_id);
525*05b00f60SXin Li *len -= 2;
526*05b00f60SXin Li bp += 2;
527*05b00f60SXin Li }
528*05b00f60SXin Li static void
ptp_print_announce_msg(netdissect_options * ndo,const u_char * bp,u_int * len)529*05b00f60SXin Li ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len)
530*05b00f60SXin Li {
531*05b00f60SXin Li uint8_t rsvd, gm_prio_1, gm_prio_2, gm_clk_cls, gm_clk_acc, time_src;
532*05b00f60SXin Li uint16_t origin_cur_utc, gm_clk_var, steps_removed;
533*05b00f60SXin Li uint64_t gm_clock_id;
534*05b00f60SXin Li uint64_t secs;
535*05b00f60SXin Li uint32_t nsecs;
536*05b00f60SXin Li
537*05b00f60SXin Li ND_PRINT(", %s :", p_origin_ts);
538*05b00f60SXin Li /* sec time stamp 6 bytes */
539*05b00f60SXin Li secs = GET_BE_U_6(bp);
540*05b00f60SXin Li ND_PRINT(" %"PRIu64" seconds", secs);
541*05b00f60SXin Li *len -= 6;
542*05b00f60SXin Li bp += 6;
543*05b00f60SXin Li
544*05b00f60SXin Li /* NS time stamp 4 bytes */
545*05b00f60SXin Li nsecs = GET_BE_U_4(bp);
546*05b00f60SXin Li ND_PRINT(" %u nanoseconds", nsecs);
547*05b00f60SXin Li *len -= 4;
548*05b00f60SXin Li bp += 4;
549*05b00f60SXin Li
550*05b00f60SXin Li /* origin cur utc */
551*05b00f60SXin Li origin_cur_utc = GET_BE_U_2(bp);
552*05b00f60SXin Li ND_PRINT(", origin cur utc :%u", origin_cur_utc);
553*05b00f60SXin Li *len -= 2;
554*05b00f60SXin Li bp += 2;
555*05b00f60SXin Li
556*05b00f60SXin Li /* rsvd */
557*05b00f60SXin Li rsvd = GET_U_1(bp);
558*05b00f60SXin Li ND_PRINT(", rsvd : %u", rsvd);
559*05b00f60SXin Li *len -= 1;
560*05b00f60SXin Li bp += 1;
561*05b00f60SXin Li
562*05b00f60SXin Li /* gm prio */
563*05b00f60SXin Li gm_prio_1 = GET_U_1(bp);
564*05b00f60SXin Li ND_PRINT(", gm priority_1 : %u", gm_prio_1);
565*05b00f60SXin Li *len -= 1;
566*05b00f60SXin Li bp += 1;
567*05b00f60SXin Li
568*05b00f60SXin Li /* GM clock class */
569*05b00f60SXin Li gm_clk_cls = GET_U_1(bp);
570*05b00f60SXin Li ND_PRINT(", gm clock class : %u", gm_clk_cls);
571*05b00f60SXin Li *len -= 1;
572*05b00f60SXin Li bp += 1;
573*05b00f60SXin Li /* GM clock accuracy */
574*05b00f60SXin Li gm_clk_acc = GET_U_1(bp);
575*05b00f60SXin Li ND_PRINT(", gm clock accuracy : %u", gm_clk_acc);
576*05b00f60SXin Li *len -= 1;
577*05b00f60SXin Li bp += 1;
578*05b00f60SXin Li /* GM clock variance */
579*05b00f60SXin Li gm_clk_var = GET_BE_U_2(bp);
580*05b00f60SXin Li ND_PRINT(", gm clock variance : %u", gm_clk_var);
581*05b00f60SXin Li *len -= 2;
582*05b00f60SXin Li bp += 2;
583*05b00f60SXin Li /* GM Prio 2 */
584*05b00f60SXin Li gm_prio_2 = GET_U_1(bp);
585*05b00f60SXin Li ND_PRINT(", gm priority_2 : %u", gm_prio_2);
586*05b00f60SXin Li *len -= 1;
587*05b00f60SXin Li bp += 1;
588*05b00f60SXin Li
589*05b00f60SXin Li /* GM Clock Identity */
590*05b00f60SXin Li gm_clock_id = GET_BE_U_8(bp);
591*05b00f60SXin Li ND_PRINT(", gm clock id : 0x%"PRIx64, gm_clock_id);
592*05b00f60SXin Li *len -= 8;
593*05b00f60SXin Li bp += 8;
594*05b00f60SXin Li /* steps removed */
595*05b00f60SXin Li steps_removed = GET_BE_U_2(bp);
596*05b00f60SXin Li ND_PRINT(", steps removed : %u", steps_removed);
597*05b00f60SXin Li *len -= 2;
598*05b00f60SXin Li bp += 2;
599*05b00f60SXin Li /* Time source */
600*05b00f60SXin Li time_src = GET_U_1(bp);
601*05b00f60SXin Li ND_PRINT(", time source : 0x%x", time_src);
602*05b00f60SXin Li *len -= 1;
603*05b00f60SXin Li bp += 1;
604*05b00f60SXin Li
605*05b00f60SXin Li }
606*05b00f60SXin Li static void
ptp_print_port_id(netdissect_options * ndo,const u_char * bp,u_int * len)607*05b00f60SXin Li ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len)
608*05b00f60SXin Li {
609*05b00f60SXin Li uint16_t port_id;
610*05b00f60SXin Li uint64_t port_identity;
611*05b00f60SXin Li
612*05b00f60SXin Li /* port identity*/
613*05b00f60SXin Li port_identity = GET_BE_U_8(bp);
614*05b00f60SXin Li ND_PRINT(", port identity : 0x%"PRIx64, port_identity);
615*05b00f60SXin Li *len -= 8;
616*05b00f60SXin Li bp += 8;
617*05b00f60SXin Li
618*05b00f60SXin Li /* port id */
619*05b00f60SXin Li port_id = GET_BE_U_2(bp);
620*05b00f60SXin Li ND_PRINT(", port id : %u", port_id);
621*05b00f60SXin Li *len -= 2;
622*05b00f60SXin Li bp += 2;
623*05b00f60SXin Li
624*05b00f60SXin Li }
625*05b00f60SXin Li
626*05b00f60SXin Li static void
ptp_print_mgmt_msg(netdissect_options * ndo,const u_char * bp,u_int * len)627*05b00f60SXin Li ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len)
628*05b00f60SXin Li {
629*05b00f60SXin Li ptp_print_port_id(ndo, bp, len);
630*05b00f60SXin Li print_field(ndo, ", start boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE);
631*05b00f60SXin Li print_field(ndo, ", boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE);
632*05b00f60SXin Li print_field(ndo, ", flags ", PTP_UCHAR_LEN, bp, len, PTP_TRUE);
633*05b00f60SXin Li print_field(ndo, ", reserved ", PTP_UCHAR_LEN, bp, len, PTP_TRUE);
634*05b00f60SXin Li }
635