/* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Partha S. Ghosh (psglinux dot gmail dot com) */ /* \summary: Precision Time Protocol (PTP) printer */ /* specification: https://standards.ieee.org/findstds/standard/1588-2008.html*/ #ifdef HAVE_CONFIG_H #include #endif #include "netdissect-stdinc.h" #include "netdissect.h" #include "extract.h" /* * PTP header * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | R | |msgtype| version | Msg Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | domain No | rsvd1 | flag Field | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Correction NS | * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | Correction Sub NS | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Reserved2 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Clock Identity | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Port Identity | Sequence ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | control | log msg int | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 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 * 0 1 2 3 * * Announce Message (msg type=0xB) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nano Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Origin Cur UTC Offset | Reserved | GM Prio 1 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |GM Clock Class | GM Clock Accu | GM Clock Variance | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | GM Prio 2 | | * +-+-+-+-+-+-+-+-+ + * | GM Clock Identity | * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | Steps Removed | Time Source | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 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 * 0 1 2 3 * * Sync Message (msg type=0x0) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nano Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Delay Request Message (msg type=0x1) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Origin Time Stamp Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nano Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Followup Message (msg type=0x8) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Precise Origin Time Stamp Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nano Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Delay Resp Message (msg type=0x9) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nano Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Port Identity | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * PDelay Request Message (msg type=0x2) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Origin Time Stamp Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Origin Time Stamp Nano Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Port Identity | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * PDelay Response Message (msg type=0x3) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Request receipt Time Stamp Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nano Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Requesting Port Identity | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * PDelay Resp Follow up Message (msg type=0xA) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Response Origin Time Stamp Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Nano Seconds | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Requesting Port Identity | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Signalling Message (msg type=0xC) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Requesting Port Identity | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Management Message (msg type=0xD) * 0 1 2 3 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Requesting Port Identity | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |Start Bndry Hps| Boundary Hops | flags | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ /* Values from IEEE1588-2008: 13.3.2.2 messageType (Enumeration4) */ #define M_SYNC 0x0 #define M_DELAY_REQ 0x1 #define M_PDELAY_REQ 0x2 #define M_PDELAY_RESP 0x3 #define M_FOLLOW_UP 0x8 #define M_DELAY_RESP 0x9 #define M_PDELAY_RESP_FOLLOW_UP 0xA #define M_ANNOUNCE 0xB #define M_SIGNALLING 0xC #define M_MANAGEMENT 0xD static const struct tok ptp_msg_type[] = { { M_SYNC, "sync msg"}, { M_DELAY_REQ, "delay req msg"}, { M_PDELAY_REQ, "peer delay req msg"}, { M_PDELAY_RESP, "peer delay resp msg"}, { M_FOLLOW_UP, "follow up msg"}, { M_DELAY_RESP, "delay resp msg"}, { M_PDELAY_RESP_FOLLOW_UP, "pdelay resp fup msg"}, { M_ANNOUNCE, "announce msg"}, { M_SIGNALLING, "signalling msg"}, { M_MANAGEMENT, "management msg"}, { 0, NULL} }; /* Values from IEEE1588-2008: 13.3.2.10 controlField (UInteger8) */ /* * The use of this field by the receiver is deprecated. * NOTE-This field is provided for compatibility with hardware designed * to conform to version 1 of this standard. */ #define C_SYNC 0x0 #define C_DELAY_REQ 0x1 #define C_FOLLOW_UP 0x2 #define C_DELAY_RESP 0x3 #define C_MANAGEMENT 0x4 #define C_OTHER 0x5 static const struct tok ptp_control_field[] = { { C_SYNC, "Sync"}, { C_DELAY_REQ, "Delay_Req"}, { C_FOLLOW_UP, "Follow_Up"}, { C_DELAY_RESP, "Delay_Resp"}, { C_MANAGEMENT, "Management"}, { C_OTHER, "Other"}, { 0, NULL} }; #define PTP_TRUE 1 #define PTP_FALSE !PTP_TRUE #define PTP_HDR_LEN 0x22 /* mask based on the first byte */ #define PTP_VERS_MASK 0xFF #define PTP_V1_COMPAT 0x10 #define PTP_MSG_TYPE_MASK 0x0F /*mask based 2byte */ #define PTP_DOMAIN_MASK 0xFF00 #define PTP_RSVD1_MASK 0xFF #define PTP_CONTROL_MASK 0xFF #define PTP_LOGMSG_MASK 0xFF /* mask based on the flags 2 bytes */ #define PTP_L161_MASK 0x1 #define PTP_L1_59_MASK 0x2 #define PTP_UTC_REASONABLE_MASK 0x4 #define PTP_TIMESCALE_MASK 0x8 #define PTP_TIME_TRACABLE_MASK 0x10 #define PTP_FREQUENCY_TRACABLE_MASK 0x20 #define PTP_ALTERNATE_MASTER_MASK 0x100 #define PTP_TWO_STEP_MASK 0x200 #define PTP_UNICAST_MASK 0x400 #define PTP_PROFILE_SPEC_1_MASK 0x1000 #define PTP_PROFILE_SPEC_2_MASK 0x2000 #define PTP_SECURITY_MASK 0x4000 #define PTP_FLAGS_UNKNOWN_MASK 0x18C0 static const struct tok ptp_flag_values[] = { { PTP_L161_MASK, "l1 61"}, { PTP_L1_59_MASK, "l1 59"}, { PTP_UTC_REASONABLE_MASK, "utc reasonable"}, { PTP_TIMESCALE_MASK, "timescale"}, { PTP_TIME_TRACABLE_MASK, "time tracable"}, { PTP_FREQUENCY_TRACABLE_MASK, "frequency tracable"}, { PTP_ALTERNATE_MASTER_MASK, "alternate master"}, { PTP_TWO_STEP_MASK, "two step"}, { PTP_UNICAST_MASK, "unicast"}, { PTP_PROFILE_SPEC_1_MASK, "profile specific 1"}, { PTP_PROFILE_SPEC_2_MASK, "profile specific 2"}, { PTP_SECURITY_MASK, "security mask"}, { PTP_FLAGS_UNKNOWN_MASK, "unknown"}, {0, NULL} }; static const char *p_porigin_ts = "preciseOriginTimeStamp"; static const char *p_origin_ts = "originTimeStamp"; static const char *p_recv_ts = "receiveTimeStamp"; #define PTP_VER_1 0x1 #define PTP_VER_2 0x2 #define PTP_UCHAR_LEN sizeof(uint8_t) #define PTP_UINT16_LEN sizeof(uint16_t) #define PTP_UINT32_LEN sizeof(uint32_t) #define PTP_6BYTES_LEN sizeof(uint32_t)+sizeof(uint16_t) #define PTP_UINT64_LEN sizeof(uint64_t) static void ptp_print_1(netdissect_options *ndo); static void ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int len); static void ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype); static void ptp_print_timestamp_identity(netdissect_options *ndo, const u_char *bp, u_int *len, const char *ttype); static void ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len); static void ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len); static void ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len); static void print_field(netdissect_options *ndo, const char *st, uint32_t flen, const u_char *bp, u_int *len, uint8_t hex) { uint8_t u8_val; uint16_t u16_val; uint32_t u32_val; uint64_t u64_val; switch(flen) { case PTP_UCHAR_LEN: u8_val = GET_U_1(bp); ND_PRINT(", %s", st); if (hex) ND_PRINT(" 0x%x", u8_val); else ND_PRINT(" %u", u8_val); *len -= 1; bp += 1; break; case PTP_UINT16_LEN: u16_val = GET_BE_U_2(bp); ND_PRINT(", %s", st); if (hex) ND_PRINT(" 0x%x", u16_val); else ND_PRINT(" %u", u16_val); *len -= 2; bp += 2; break; case PTP_UINT32_LEN: u32_val = GET_BE_U_4(bp); ND_PRINT(", %s", st); if (hex) ND_PRINT(" 0x%x", u32_val); else ND_PRINT(" %u", u32_val); *len -= 4; bp += 4; break; case PTP_UINT64_LEN: u64_val = GET_BE_U_8(bp); ND_PRINT(", %s", st); if (hex) ND_PRINT(" 0x%"PRIx64, u64_val); else ND_PRINT(" 0x%"PRIu64, u64_val); *len -= 8; bp += 8; break; default: break; } } static void ptp_print_1(netdissect_options *ndo) { ND_PRINT(" (not implemented)"); } static void ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int length) { u_int len = length; uint16_t msg_len, flags, port_id, seq_id; uint8_t foct, domain_no, msg_type, v1_compat, rsvd1, lm_int, control; uint64_t ns_corr; uint16_t sns_corr; uint32_t rsvd2; uint64_t clk_id; foct = GET_U_1(bp); v1_compat = foct & PTP_V1_COMPAT; ND_PRINT(", v1 compat : %s", v1_compat?"yes":"no"); msg_type = foct & PTP_MSG_TYPE_MASK; ND_PRINT(", msg type : %s", tok2str(ptp_msg_type, "Reserved", msg_type)); /* msg length */ len -= 2; bp += 2; msg_len = GET_BE_U_2(bp); ND_PRINT(", length : %u", msg_len); /* domain */ len -= 2; bp += 2; domain_no = (GET_BE_U_2(bp) & PTP_DOMAIN_MASK) >> 8; ND_PRINT(", domain : %u", domain_no); /* rsvd 1*/ rsvd1 = GET_BE_U_2(bp) & PTP_RSVD1_MASK; ND_PRINT(", reserved1 : %u", rsvd1); /* flags */ len -= 2; bp += 2; flags = GET_BE_U_2(bp); ND_PRINT(", Flags [%s]", bittok2str(ptp_flag_values, "none", flags)); /* correction NS (48 bits) */ len -= 2; bp += 2; ns_corr = GET_BE_U_6(bp); ND_PRINT(", NS correction : %"PRIu64, ns_corr); /* correction sub NS (16 bits) */ len -= 6; bp += 6; sns_corr = GET_BE_U_2(bp); ND_PRINT(", sub NS correction : %u", sns_corr); /* Reserved 2 */ len -= 2; bp += 2; rsvd2 = GET_BE_U_4(bp); ND_PRINT(", reserved2 : %u", rsvd2); /* clock identity */ len -= 4; bp += 4; clk_id = GET_BE_U_8(bp); ND_PRINT(", clock identity : 0x%"PRIx64, clk_id); /* port identity */ len -= 8; bp += 8; port_id = GET_BE_U_2(bp); ND_PRINT(", port id : %u", port_id); /* sequence ID */ len -= 2; bp += 2; seq_id = GET_BE_U_2(bp); ND_PRINT(", seq id : %u", seq_id); /* control */ len -= 2; bp += 2; control = GET_U_1(bp) ; ND_PRINT(", control : %u (%s)", control, tok2str(ptp_control_field, "Reserved", control)); /* log message interval */ lm_int = GET_BE_U_2(bp) & PTP_LOGMSG_MASK; ND_PRINT(", log message interval : %u", lm_int); len -= 2; bp += 2; switch(msg_type) { case M_SYNC: ptp_print_timestamp(ndo, bp, &len, p_origin_ts); break; case M_DELAY_REQ: ptp_print_timestamp(ndo, bp, &len, p_origin_ts); break; case M_PDELAY_REQ: ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts); break; case M_PDELAY_RESP: ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts); break; case M_FOLLOW_UP: ptp_print_timestamp(ndo, bp, &len, p_porigin_ts); break; case M_DELAY_RESP: ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts); break; case M_PDELAY_RESP_FOLLOW_UP: ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts); break; case M_ANNOUNCE: ptp_print_announce_msg(ndo, bp, &len); break; case M_SIGNALLING: ptp_print_port_id(ndo, bp, &len); break; case M_MANAGEMENT: ptp_print_mgmt_msg(ndo, bp, &len); break; default: break; } } /* * PTP general message */ void ptp_print(netdissect_options *ndo, const u_char *bp, u_int length) { u_int vers; ndo->ndo_protocol = "ptp"; ND_LCHECK_U(length, PTP_HDR_LEN); vers = GET_BE_U_2(bp) & PTP_VERS_MASK; ND_PRINT("PTPv%u",vers); switch(vers) { case PTP_VER_1: ptp_print_1(ndo); break; case PTP_VER_2: ptp_print_2(ndo, bp, length); break; default: //ND_PRINT("ERROR: unknown-version\n"); break; } return; invalid: nd_print_invalid(ndo); } static void ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype) { uint64_t secs; uint32_t nsecs; ND_PRINT(", %s :", stype); /* sec time stamp 6 bytes */ secs = GET_BE_U_6(bp); ND_PRINT(" %"PRIu64" seconds,", secs); *len -= 6; bp += 6; /* NS time stamp 4 bytes */ nsecs = GET_BE_U_4(bp); ND_PRINT(" %u nanoseconds", nsecs); *len -= 4; bp += 4; } static void ptp_print_timestamp_identity(netdissect_options *ndo, const u_char *bp, u_int *len, const char *ttype) { uint64_t secs; uint32_t nsecs; uint16_t port_id; uint64_t port_identity; ND_PRINT(", %s :", ttype); /* sec time stamp 6 bytes */ secs = GET_BE_U_6(bp); ND_PRINT(" %"PRIu64" seconds,", secs); *len -= 6; bp += 6; /* NS time stamp 4 bytes */ nsecs = GET_BE_U_4(bp); ND_PRINT(" %u nanoseconds", nsecs); *len -= 4; bp += 4; /* port identity*/ port_identity = GET_BE_U_8(bp); ND_PRINT(", port identity : 0x%"PRIx64, port_identity); *len -= 8; bp += 8; /* port id */ port_id = GET_BE_U_2(bp); ND_PRINT(", port id : %u", port_id); *len -= 2; bp += 2; } static void ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len) { uint8_t rsvd, gm_prio_1, gm_prio_2, gm_clk_cls, gm_clk_acc, time_src; uint16_t origin_cur_utc, gm_clk_var, steps_removed; uint64_t gm_clock_id; uint64_t secs; uint32_t nsecs; ND_PRINT(", %s :", p_origin_ts); /* sec time stamp 6 bytes */ secs = GET_BE_U_6(bp); ND_PRINT(" %"PRIu64" seconds", secs); *len -= 6; bp += 6; /* NS time stamp 4 bytes */ nsecs = GET_BE_U_4(bp); ND_PRINT(" %u nanoseconds", nsecs); *len -= 4; bp += 4; /* origin cur utc */ origin_cur_utc = GET_BE_U_2(bp); ND_PRINT(", origin cur utc :%u", origin_cur_utc); *len -= 2; bp += 2; /* rsvd */ rsvd = GET_U_1(bp); ND_PRINT(", rsvd : %u", rsvd); *len -= 1; bp += 1; /* gm prio */ gm_prio_1 = GET_U_1(bp); ND_PRINT(", gm priority_1 : %u", gm_prio_1); *len -= 1; bp += 1; /* GM clock class */ gm_clk_cls = GET_U_1(bp); ND_PRINT(", gm clock class : %u", gm_clk_cls); *len -= 1; bp += 1; /* GM clock accuracy */ gm_clk_acc = GET_U_1(bp); ND_PRINT(", gm clock accuracy : %u", gm_clk_acc); *len -= 1; bp += 1; /* GM clock variance */ gm_clk_var = GET_BE_U_2(bp); ND_PRINT(", gm clock variance : %u", gm_clk_var); *len -= 2; bp += 2; /* GM Prio 2 */ gm_prio_2 = GET_U_1(bp); ND_PRINT(", gm priority_2 : %u", gm_prio_2); *len -= 1; bp += 1; /* GM Clock Identity */ gm_clock_id = GET_BE_U_8(bp); ND_PRINT(", gm clock id : 0x%"PRIx64, gm_clock_id); *len -= 8; bp += 8; /* steps removed */ steps_removed = GET_BE_U_2(bp); ND_PRINT(", steps removed : %u", steps_removed); *len -= 2; bp += 2; /* Time source */ time_src = GET_U_1(bp); ND_PRINT(", time source : 0x%x", time_src); *len -= 1; bp += 1; } static void ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len) { uint16_t port_id; uint64_t port_identity; /* port identity*/ port_identity = GET_BE_U_8(bp); ND_PRINT(", port identity : 0x%"PRIx64, port_identity); *len -= 8; bp += 8; /* port id */ port_id = GET_BE_U_2(bp); ND_PRINT(", port id : %u", port_id); *len -= 2; bp += 2; } static void ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len) { ptp_print_port_id(ndo, bp, len); print_field(ndo, ", start boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE); print_field(ndo, ", boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE); print_field(ndo, ", flags ", PTP_UCHAR_LEN, bp, len, PTP_TRUE); print_field(ndo, ", reserved ", PTP_UCHAR_LEN, bp, len, PTP_TRUE); }