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 } 621