vendor/TCPDUMP: Import libpcap 4.99.1
[dragonfly.git] / contrib / 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 }