tcpdump/print-ptp.c

622 lines
22 KiB
C
Raw Normal View History

/*
* 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 <config.h>
#endif
#include "netdissect-stdinc.h"
#include "netdissect.h"
#include "extract.h"
#include <string.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 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
#define M_SYNC 0x0
#define M_DELAY_REQ 0x1
#define M_PDELAY_REQ 0x2
#define M_PDELAY_RESP 0x3
#define M_OTHER 0x5
#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_OTHER, "Other"},
{ 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}
};
#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}
};
#define PTP_PRINT_MSG_TYPE(e) \
{ \
ND_PRINT("(%s)", tok2str(ptp_msg_type, "unknown", e)); \
}
const char *p_porigin_ts = "preciseOriginTimeStamp";
const char *p_origin_ts = "originTimeStamp";
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;
uint32_t ns_corr, sns_corr, 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, "none", 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; 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 */
len -= 2; bp += 2; ns_corr = GET_BE_U_4(bp); ND_PRINT(", NS correction : %u", ns_corr);
/* correction sub NS */
len -= 4; bp += 4; sns_corr = GET_BE_U_4(bp); ND_PRINT(", sub NS correction : %u", sns_corr);
/* Reserved 2 */
len -= 4; bp += 4; 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_msg_type, "none", 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 len)
{
u_int vers;
ndo->ndo_protocol = "ptp";
if (len < PTP_HDR_LEN) {
goto trunc;
}
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, len);
break;
default:
//ND_PRINT("ERROR: unknown-version\n");
break;
}
return;
trunc:
nd_print_trunc(ndo);
return;
}
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_2(bp) + GET_BE_U_4(bp+2);
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_2(bp) + GET_BE_U_4(bp+2);
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_2(bp) + GET_BE_U_4(bp+2);
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);
}