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