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