Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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 | } |