mirror of
https://github.com/the-tcpdump-group/tcpdump.git
synced 2024-11-23 01:53:55 +08:00
487405e871
`bp` was modified inside the function but the change was not reflected back outside, resulting in the fields afterwards accessing the wrong part of the packet. Signed-off-by: Casper Andersson <casper.casan@gmail.com>
651 lines
24 KiB
C
651 lines
24 KiB
C
/*
|
|
* 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*/
|
|
|
|
#include <config.h>
|
|
|
|
#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 |
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
*
|
|
* Signaling 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_SIGNALING 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_SIGNALING, "signaling 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_MAJOR_VERS_MASK 0x0F
|
|
#define PTP_MINOR_VERS_MASK 0xF0
|
|
#define PTP_MAJOR_SDO_ID_MASK 0xF0
|
|
#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 const u_char *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 const u_char *
|
|
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;
|
|
}
|
|
|
|
return bp;
|
|
}
|
|
|
|
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, major_sdo_id, rsvd1, lm_int, control;
|
|
uint64_t ns_corr;
|
|
uint16_t sns_corr;
|
|
uint32_t rsvd2;
|
|
uint64_t clk_id;
|
|
|
|
foct = GET_U_1(bp);
|
|
major_sdo_id = (foct & PTP_MAJOR_SDO_ID_MASK) >> 4;
|
|
ND_PRINT(", majorSdoId: 0x%x", major_sdo_id);
|
|
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_SIGNALING:
|
|
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 major_vers;
|
|
u_int minor_vers;
|
|
|
|
/* In 1588-2019, a minorVersionPTP field has been created in the common PTP
|
|
* message header, from a previously reserved field. Implementations
|
|
* compatible to the 2019 edition shall indicate a versionPTP field value
|
|
* of 2 and minorVersionPTP field value of 1, indicating that this is PTP
|
|
* version 2.1.
|
|
*/
|
|
ndo->ndo_protocol = "ptp";
|
|
nd_print_protocol_caps(ndo);
|
|
ND_ICHECK_U(length, <, PTP_HDR_LEN);
|
|
major_vers = GET_BE_U_2(bp) & PTP_MAJOR_VERS_MASK;
|
|
minor_vers = (GET_BE_U_2(bp) & PTP_MINOR_VERS_MASK) >> 4;
|
|
if (minor_vers)
|
|
ND_PRINT("v%u.%u", major_vers, minor_vers);
|
|
else
|
|
ND_PRINT("v%u", major_vers);
|
|
|
|
switch(major_vers) {
|
|
case PTP_VER_1:
|
|
ptp_print_1(ndo);
|
|
break;
|
|
case PTP_VER_2:
|
|
ptp_print_2(ndo, bp, length);
|
|
break;
|
|
default:
|
|
ND_PRINT(" (unsupported)");
|
|
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 const u_char *
|
|
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;
|
|
|
|
return bp;
|
|
}
|
|
|
|
static void
|
|
ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len)
|
|
{
|
|
bp = ptp_print_port_id(ndo, bp, len);
|
|
bp = print_field(ndo, "start boundary hops:", PTP_UCHAR_LEN, bp, len, PTP_FALSE);
|
|
bp = print_field(ndo, "boundary hops:", PTP_UCHAR_LEN, bp, len, PTP_FALSE);
|
|
bp = print_field(ndo, "flags:", PTP_UCHAR_LEN, bp, len, PTP_TRUE);
|
|
bp = print_field(ndo, "reserved:", PTP_UCHAR_LEN, bp, len, PTP_TRUE);
|
|
}
|