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 void 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 void 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 349 static void 350 ptp_print_1(netdissect_options *ndo) 351 { 352 ND_PRINT(" (not implemented)"); 353 } 354 355 static void 356 ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int length) 357 { 358 u_int len = length; 359 uint16_t msg_len, flags, port_id, seq_id; 360 uint8_t foct, domain_no, msg_type, major_sdo_id, rsvd1, lm_int, control; 361 uint64_t ns_corr; 362 uint16_t sns_corr; 363 uint32_t rsvd2; 364 uint64_t clk_id; 365 366 foct = GET_U_1(bp); 367 major_sdo_id = (foct & PTP_MAJOR_SDO_ID_MASK) >> 4; 368 ND_PRINT(", majorSdoId : 0x%x", major_sdo_id); 369 msg_type = foct & PTP_MSG_TYPE_MASK; 370 ND_PRINT(", msg type : %s", tok2str(ptp_msg_type, "Reserved", msg_type)); 371 372 /* msg length */ 373 len -= 2; bp += 2; msg_len = GET_BE_U_2(bp); ND_PRINT(", length : %u", msg_len); 374 375 /* domain */ 376 len -= 2; bp += 2; domain_no = (GET_BE_U_2(bp) & PTP_DOMAIN_MASK) >> 8; ND_PRINT(", domain : %u", domain_no); 377 378 /* rsvd 1*/ 379 rsvd1 = GET_BE_U_2(bp) & PTP_RSVD1_MASK; 380 ND_PRINT(", reserved1 : %u", rsvd1); 381 382 /* flags */ 383 len -= 2; bp += 2; flags = GET_BE_U_2(bp); ND_PRINT(", Flags [%s]", bittok2str(ptp_flag_values, "none", flags)); 384 385 /* correction NS (48 bits) */ 386 len -= 2; bp += 2; ns_corr = GET_BE_U_6(bp); ND_PRINT(", NS correction : %"PRIu64, ns_corr); 387 388 /* correction sub NS (16 bits) */ 389 len -= 6; bp += 6; sns_corr = GET_BE_U_2(bp); ND_PRINT(", sub NS correction : %u", sns_corr); 390 391 /* Reserved 2 */ 392 len -= 2; bp += 2; rsvd2 = GET_BE_U_4(bp); ND_PRINT(", reserved2 : %u", rsvd2); 393 394 /* clock identity */ 395 len -= 4; bp += 4; clk_id = GET_BE_U_8(bp); ND_PRINT(", clock identity : 0x%"PRIx64, clk_id); 396 397 /* port identity */ 398 len -= 8; bp += 8; port_id = GET_BE_U_2(bp); ND_PRINT(", port id : %u", port_id); 399 400 /* sequence ID */ 401 len -= 2; bp += 2; seq_id = GET_BE_U_2(bp); ND_PRINT(", seq id : %u", seq_id); 402 403 /* control */ 404 len -= 2; bp += 2; control = GET_U_1(bp) ; 405 ND_PRINT(", control : %u (%s)", control, tok2str(ptp_control_field, "Reserved", control)); 406 407 /* log message interval */ 408 lm_int = GET_BE_U_2(bp) & PTP_LOGMSG_MASK; ND_PRINT(", log message interval : %u", lm_int); len -= 2; bp += 2; 409 410 switch(msg_type) { 411 case M_SYNC: 412 ptp_print_timestamp(ndo, bp, &len, p_origin_ts); 413 break; 414 case M_DELAY_REQ: 415 ptp_print_timestamp(ndo, bp, &len, p_origin_ts); 416 break; 417 case M_PDELAY_REQ: 418 ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts); 419 break; 420 case M_PDELAY_RESP: 421 ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts); 422 break; 423 case M_FOLLOW_UP: 424 ptp_print_timestamp(ndo, bp, &len, p_porigin_ts); 425 break; 426 case M_DELAY_RESP: 427 ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts); 428 break; 429 case M_PDELAY_RESP_FOLLOW_UP: 430 ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts); 431 break; 432 case M_ANNOUNCE: 433 ptp_print_announce_msg(ndo, bp, &len); 434 break; 435 case M_SIGNALING: 436 ptp_print_port_id(ndo, bp, &len); 437 break; 438 case M_MANAGEMENT: 439 ptp_print_mgmt_msg(ndo, bp, &len); 440 break; 441 default: 442 break; 443 } 444 } 445 /* 446 * PTP general message 447 */ 448 void 449 ptp_print(netdissect_options *ndo, const u_char *bp, u_int length) 450 { 451 u_int major_vers; 452 u_int minor_vers; 453 454 /* In 1588-2019, a minorVersionPTP field has been created in the common PTP 455 * message header, from a previously reserved field. Implementations 456 * compatible to the 2019 edition shall indicate a versionPTP field value 457 * of 2 and minorVersionPTP field value of 1, indicating that this is PTP 458 * version 2.1. 459 */ 460 ndo->ndo_protocol = "ptp"; 461 ND_ICHECK_U(length, <, PTP_HDR_LEN); 462 major_vers = GET_BE_U_2(bp) & PTP_MAJOR_VERS_MASK; 463 minor_vers = (GET_BE_U_2(bp) & PTP_MINOR_VERS_MASK) >> 4; 464 if (minor_vers) 465 ND_PRINT("PTPv%u.%u", major_vers, minor_vers); 466 else 467 ND_PRINT("PTPv%u", major_vers); 468 469 switch(major_vers) { 470 case PTP_VER_1: 471 ptp_print_1(ndo); 472 break; 473 case PTP_VER_2: 474 ptp_print_2(ndo, bp, length); 475 break; 476 default: 477 //ND_PRINT("ERROR: unknown-version\n"); 478 break; 479 } 480 return; 481 482 invalid: 483 nd_print_invalid(ndo); 484 } 485 486 static void 487 ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype) 488 { 489 uint64_t secs; 490 uint32_t nsecs; 491 492 ND_PRINT(", %s :", stype); 493 /* sec time stamp 6 bytes */ 494 secs = GET_BE_U_6(bp); 495 ND_PRINT(" %"PRIu64" seconds,", secs); 496 *len -= 6; 497 bp += 6; 498 499 /* NS time stamp 4 bytes */ 500 nsecs = GET_BE_U_4(bp); 501 ND_PRINT(" %u nanoseconds", nsecs); 502 *len -= 4; 503 bp += 4; 504 } 505 static void 506 ptp_print_timestamp_identity(netdissect_options *ndo, 507 const u_char *bp, u_int *len, const char *ttype) 508 { 509 uint64_t secs; 510 uint32_t nsecs; 511 uint16_t port_id; 512 uint64_t port_identity; 513 514 ND_PRINT(", %s :", ttype); 515 /* sec time stamp 6 bytes */ 516 secs = GET_BE_U_6(bp); 517 ND_PRINT(" %"PRIu64" seconds,", secs); 518 *len -= 6; 519 bp += 6; 520 521 /* NS time stamp 4 bytes */ 522 nsecs = GET_BE_U_4(bp); 523 ND_PRINT(" %u nanoseconds", nsecs); 524 *len -= 4; 525 bp += 4; 526 527 /* port identity*/ 528 port_identity = GET_BE_U_8(bp); 529 ND_PRINT(", port identity : 0x%"PRIx64, port_identity); 530 *len -= 8; 531 bp += 8; 532 533 /* port id */ 534 port_id = GET_BE_U_2(bp); 535 ND_PRINT(", port id : %u", port_id); 536 *len -= 2; 537 bp += 2; 538 } 539 static void 540 ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len) 541 { 542 uint8_t rsvd, gm_prio_1, gm_prio_2, gm_clk_cls, gm_clk_acc, time_src; 543 uint16_t origin_cur_utc, gm_clk_var, steps_removed; 544 uint64_t gm_clock_id; 545 uint64_t secs; 546 uint32_t nsecs; 547 548 ND_PRINT(", %s :", p_origin_ts); 549 /* sec time stamp 6 bytes */ 550 secs = GET_BE_U_6(bp); 551 ND_PRINT(" %"PRIu64" seconds", secs); 552 *len -= 6; 553 bp += 6; 554 555 /* NS time stamp 4 bytes */ 556 nsecs = GET_BE_U_4(bp); 557 ND_PRINT(" %u nanoseconds", nsecs); 558 *len -= 4; 559 bp += 4; 560 561 /* origin cur utc */ 562 origin_cur_utc = GET_BE_U_2(bp); 563 ND_PRINT(", origin cur utc :%u", origin_cur_utc); 564 *len -= 2; 565 bp += 2; 566 567 /* rsvd */ 568 rsvd = GET_U_1(bp); 569 ND_PRINT(", rsvd : %u", rsvd); 570 *len -= 1; 571 bp += 1; 572 573 /* gm prio */ 574 gm_prio_1 = GET_U_1(bp); 575 ND_PRINT(", gm priority_1 : %u", gm_prio_1); 576 *len -= 1; 577 bp += 1; 578 579 /* GM clock class */ 580 gm_clk_cls = GET_U_1(bp); 581 ND_PRINT(", gm clock class : %u", gm_clk_cls); 582 *len -= 1; 583 bp += 1; 584 /* GM clock accuracy */ 585 gm_clk_acc = GET_U_1(bp); 586 ND_PRINT(", gm clock accuracy : %u", gm_clk_acc); 587 *len -= 1; 588 bp += 1; 589 /* GM clock variance */ 590 gm_clk_var = GET_BE_U_2(bp); 591 ND_PRINT(", gm clock variance : %u", gm_clk_var); 592 *len -= 2; 593 bp += 2; 594 /* GM Prio 2 */ 595 gm_prio_2 = GET_U_1(bp); 596 ND_PRINT(", gm priority_2 : %u", gm_prio_2); 597 *len -= 1; 598 bp += 1; 599 600 /* GM Clock Identity */ 601 gm_clock_id = GET_BE_U_8(bp); 602 ND_PRINT(", gm clock id : 0x%"PRIx64, gm_clock_id); 603 *len -= 8; 604 bp += 8; 605 /* steps removed */ 606 steps_removed = GET_BE_U_2(bp); 607 ND_PRINT(", steps removed : %u", steps_removed); 608 *len -= 2; 609 bp += 2; 610 /* Time source */ 611 time_src = GET_U_1(bp); 612 ND_PRINT(", time source : 0x%x", time_src); 613 *len -= 1; 614 bp += 1; 615 616 } 617 static void 618 ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len) 619 { 620 uint16_t port_id; 621 uint64_t port_identity; 622 623 /* port identity*/ 624 port_identity = GET_BE_U_8(bp); 625 ND_PRINT(", port identity : 0x%"PRIx64, port_identity); 626 *len -= 8; 627 bp += 8; 628 629 /* port id */ 630 port_id = GET_BE_U_2(bp); 631 ND_PRINT(", port id : %u", port_id); 632 *len -= 2; 633 bp += 2; 634 635 } 636 637 static void 638 ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len) 639 { 640 ptp_print_port_id(ndo, bp, len); 641 print_field(ndo, ", start boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE); 642 print_field(ndo, ", boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE); 643 print_field(ndo, ", flags ", PTP_UCHAR_LEN, bp, len, PTP_TRUE); 644 print_field(ndo, ", reserved ", PTP_UCHAR_LEN, bp, len, PTP_TRUE); 645 } 646