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