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 * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 39 * | | Correction Sub NS | 40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 41 * | Reserved2 | 42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 43 * | Clock Identity | 44 * | | 45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 46 * | Port Identity | Sequence ID | 47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 48 * | control | log msg int | 49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 50 * 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 51 * 0 1 2 3 52 * 53 * Announce Message (msg type=0xB) 54 * 0 1 2 3 55 * 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 56 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 57 * | | 58 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 59 * | Seconds | 60 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 61 * | Nano Seconds | 62 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63 * | Origin Cur UTC Offset | Reserved | GM Prio 1 | 64 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 65 * |GM Clock Class | GM Clock Accu | GM Clock Variance | 66 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 67 * | GM Prio 2 | | 68 * +-+-+-+-+-+-+-+-+ + 69 * | GM Clock Identity | 70 * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 71 * | | Steps Removed | Time Source | 72 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 73 * 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 74 * 0 1 2 3 75 * 76 * Sync Message (msg type=0x0) 77 * 0 1 2 3 78 * 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 79 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 80 * | | 81 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 82 * | Seconds | 83 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 84 * | Nano Seconds | 85 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 86 * 87 * Delay Request Message (msg type=0x1) 88 * 0 1 2 3 89 * 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 90 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 91 * | | 92 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 93 * | Origin Time Stamp Seconds | 94 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 95 * | Nano Seconds | 96 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 97 * 98 * Followup Message (msg type=0x8) 99 * 0 1 2 3 100 * 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 101 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 102 * | | 103 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 104 * | Precise Origin Time Stamp Seconds | 105 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 106 * | Nano Seconds | 107 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 108 * 109 * Delay Resp Message (msg type=0x9) 110 * 0 1 2 3 111 * 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 112 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 113 * | | 114 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 115 * | Seconds | 116 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 117 * | Nano Seconds | 118 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 119 * | Port Identity | 120 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 121 * 122 * PDelay Request Message (msg type=0x2) 123 * 0 1 2 3 124 * 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 125 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 126 * | | 127 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 128 * | Origin Time Stamp Seconds | 129 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 130 * | Origin Time Stamp Nano Seconds | 131 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 132 * | Port Identity | 133 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 134 * 135 * PDelay Response Message (msg type=0x3) 136 * 0 1 2 3 137 * 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 138 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 139 * | | 140 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 141 * | Request receipt Time Stamp Seconds | 142 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 143 * | Nano Seconds | 144 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 145 * | Requesting Port Identity | 146 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 147 * 148 * PDelay Resp Follow up Message (msg type=0xA) 149 * 0 1 2 3 150 * 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 151 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 152 * | | 153 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 154 * | Response Origin Time Stamp Seconds | 155 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 156 * | Nano Seconds | 157 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 158 * | Requesting Port Identity | 159 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 160 * 161 * Signalling Message (msg type=0xC) 162 * 0 1 2 3 163 * 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 164 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 165 * | Requesting Port Identity | 166 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 167 * 168 * Management Message (msg type=0xD) 169 * 0 1 2 3 170 * 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 171 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 172 * | Requesting Port Identity | 173 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 174 * |Start Bndry Hps| Boundary Hops | flags | Reserved | 175 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 176 * 177 */ 178 179 /* Values from IEEE1588-2008: 13.3.2.2 messageType (Enumeration4) */ 180 #define M_SYNC 0x0 181 #define M_DELAY_REQ 0x1 182 #define M_PDELAY_REQ 0x2 183 #define M_PDELAY_RESP 0x3 184 #define M_FOLLOW_UP 0x8 185 #define M_DELAY_RESP 0x9 186 #define M_PDELAY_RESP_FOLLOW_UP 0xA 187 #define M_ANNOUNCE 0xB 188 #define M_SIGNALLING 0xC 189 #define M_MANAGEMENT 0xD 190 191 static const struct tok ptp_msg_type[] = { 192 { M_SYNC, "sync msg"}, 193 { M_DELAY_REQ, "delay req msg"}, 194 { M_PDELAY_REQ, "peer delay req msg"}, 195 { M_PDELAY_RESP, "peer delay resp msg"}, 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 /* Values from IEEE1588-2008: 13.3.2.10 controlField (UInteger8) */ 206 /* 207 * The use of this field by the receiver is deprecated. 208 * NOTE-This field is provided for compatibility with hardware designed 209 * to conform to version 1 of this standard. 210 */ 211 #define C_SYNC 0x0 212 #define C_DELAY_REQ 0x1 213 #define C_FOLLOW_UP 0x2 214 #define C_DELAY_RESP 0x3 215 #define C_MANAGEMENT 0x4 216 #define C_OTHER 0x5 217 218 static const struct tok ptp_control_field[] = { 219 { C_SYNC, "Sync"}, 220 { C_DELAY_REQ, "Delay_Req"}, 221 { C_FOLLOW_UP, "Follow_Up"}, 222 { C_DELAY_RESP, "Delay_Resp"}, 223 { C_MANAGEMENT, "Management"}, 224 { C_OTHER, "Other"}, 225 { 0, NULL} 226 }; 227 228 #define PTP_TRUE 1 229 #define PTP_FALSE !PTP_TRUE 230 231 #define PTP_HDR_LEN 0x22 232 233 /* mask based on the first byte */ 234 #define PTP_VERS_MASK 0xFF 235 #define PTP_V1_COMPAT 0x10 236 #define PTP_MSG_TYPE_MASK 0x0F 237 238 /*mask based 2byte */ 239 #define PTP_DOMAIN_MASK 0xFF00 240 #define PTP_RSVD1_MASK 0xFF 241 #define PTP_CONTROL_MASK 0xFF 242 #define PTP_LOGMSG_MASK 0xFF 243 244 /* mask based on the flags 2 bytes */ 245 246 #define PTP_L161_MASK 0x1 247 #define PTP_L1_59_MASK 0x2 248 #define PTP_UTC_REASONABLE_MASK 0x4 249 #define PTP_TIMESCALE_MASK 0x8 250 #define PTP_TIME_TRACABLE_MASK 0x10 251 #define PTP_FREQUENCY_TRACABLE_MASK 0x20 252 #define PTP_ALTERNATE_MASTER_MASK 0x100 253 #define PTP_TWO_STEP_MASK 0x200 254 #define PTP_UNICAST_MASK 0x400 255 #define PTP_PROFILE_SPEC_1_MASK 0x1000 256 #define PTP_PROFILE_SPEC_2_MASK 0x2000 257 #define PTP_SECURITY_MASK 0x4000 258 #define PTP_FLAGS_UNKNOWN_MASK 0x18C0 259 260 static const struct tok ptp_flag_values[] = { 261 { PTP_L161_MASK, "l1 61"}, 262 { PTP_L1_59_MASK, "l1 59"}, 263 { PTP_UTC_REASONABLE_MASK, "utc reasonable"}, 264 { PTP_TIMESCALE_MASK, "timescale"}, 265 { PTP_TIME_TRACABLE_MASK, "time tracable"}, 266 { PTP_FREQUENCY_TRACABLE_MASK, "frequency tracable"}, 267 { PTP_ALTERNATE_MASTER_MASK, "alternate master"}, 268 { PTP_TWO_STEP_MASK, "two step"}, 269 { PTP_UNICAST_MASK, "unicast"}, 270 { PTP_PROFILE_SPEC_1_MASK, "profile specific 1"}, 271 { PTP_PROFILE_SPEC_2_MASK, "profile specific 2"}, 272 { PTP_SECURITY_MASK, "security mask"}, 273 { PTP_FLAGS_UNKNOWN_MASK, "unknown"}, 274 {0, NULL} 275 }; 276 277 static const char *p_porigin_ts = "preciseOriginTimeStamp"; 278 static const char *p_origin_ts = "originTimeStamp"; 279 static const char *p_recv_ts = "receiveTimeStamp"; 280 281 #define PTP_VER_1 0x1 282 #define PTP_VER_2 0x2 283 284 #define PTP_UCHAR_LEN sizeof(uint8_t) 285 #define PTP_UINT16_LEN sizeof(uint16_t) 286 #define PTP_UINT32_LEN sizeof(uint32_t) 287 #define PTP_6BYTES_LEN sizeof(uint32_t)+sizeof(uint16_t) 288 #define PTP_UINT64_LEN sizeof(uint64_t) 289 290 static void ptp_print_1(netdissect_options *ndo); 291 static void ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int len); 292 293 static void ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype); 294 static void ptp_print_timestamp_identity(netdissect_options *ndo, const u_char *bp, u_int *len, const char *ttype); 295 static void ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len); 296 static void ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len); 297 static void ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len); 298 299 static void 300 print_field(netdissect_options *ndo, const char *st, uint32_t flen, 301 const u_char *bp, u_int *len, uint8_t hex) 302 { 303 uint8_t u8_val; 304 uint16_t u16_val; 305 uint32_t u32_val; 306 uint64_t u64_val; 307 308 switch(flen) { 309 case PTP_UCHAR_LEN: 310 u8_val = GET_U_1(bp); 311 ND_PRINT(", %s", st); 312 if (hex) 313 ND_PRINT(" 0x%x", u8_val); 314 else 315 ND_PRINT(" %u", u8_val); 316 *len -= 1; bp += 1; 317 break; 318 case PTP_UINT16_LEN: 319 u16_val = GET_BE_U_2(bp); 320 ND_PRINT(", %s", st); 321 if (hex) 322 ND_PRINT(" 0x%x", u16_val); 323 else 324 ND_PRINT(" %u", u16_val); 325 *len -= 2; bp += 2; 326 break; 327 case PTP_UINT32_LEN: 328 u32_val = GET_BE_U_4(bp); 329 ND_PRINT(", %s", st); 330 if (hex) 331 ND_PRINT(" 0x%x", u32_val); 332 else 333 ND_PRINT(" %u", u32_val); 334 *len -= 4; bp += 4; 335 break; 336 case PTP_UINT64_LEN: 337 u64_val = GET_BE_U_8(bp); 338 ND_PRINT(", %s", st); 339 if (hex) 340 ND_PRINT(" 0x%"PRIx64, u64_val); 341 else 342 ND_PRINT(" 0x%"PRIu64, u64_val); 343 *len -= 8; bp += 8; 344 break; 345 default: 346 break; 347 } 348 } 349 350 static void 351 ptp_print_1(netdissect_options *ndo) 352 { 353 ND_PRINT(" (not implemented)"); 354 } 355 356 static void 357 ptp_print_2(netdissect_options *ndo, const u_char *bp, u_int length) 358 { 359 u_int len = length; 360 uint16_t msg_len, flags, port_id, seq_id; 361 uint8_t foct, domain_no, msg_type, v1_compat, rsvd1, lm_int, control; 362 uint64_t ns_corr; 363 uint16_t sns_corr; 364 uint32_t rsvd2; 365 uint64_t clk_id; 366 367 foct = GET_U_1(bp); 368 v1_compat = foct & PTP_V1_COMPAT; 369 ND_PRINT(", v1 compat : %s", v1_compat?"yes":"no"); 370 msg_type = foct & PTP_MSG_TYPE_MASK; 371 ND_PRINT(", msg type : %s", tok2str(ptp_msg_type, "Reserved", msg_type)); 372 373 /* msg length */ 374 len -= 2; bp += 2; msg_len = GET_BE_U_2(bp); ND_PRINT(", length : %u", msg_len); 375 376 /* domain */ 377 len -= 2; bp += 2; domain_no = (GET_BE_U_2(bp) & PTP_DOMAIN_MASK) >> 8; ND_PRINT(", domain : %u", domain_no); 378 379 /* rsvd 1*/ 380 rsvd1 = GET_BE_U_2(bp) & PTP_RSVD1_MASK; 381 ND_PRINT(", reserved1 : %u", rsvd1); 382 383 /* flags */ 384 len -= 2; bp += 2; flags = GET_BE_U_2(bp); ND_PRINT(", Flags [%s]", bittok2str(ptp_flag_values, "none", flags)); 385 386 /* correction NS (48 bits) */ 387 len -= 2; bp += 2; ns_corr = GET_BE_U_6(bp); ND_PRINT(", NS correction : %"PRIu64, ns_corr); 388 389 /* correction sub NS (16 bits) */ 390 len -= 6; bp += 6; sns_corr = GET_BE_U_2(bp); ND_PRINT(", sub NS correction : %u", sns_corr); 391 392 /* Reserved 2 */ 393 len -= 2; bp += 2; rsvd2 = GET_BE_U_4(bp); ND_PRINT(", reserved2 : %u", rsvd2); 394 395 /* clock identity */ 396 len -= 4; bp += 4; clk_id = GET_BE_U_8(bp); ND_PRINT(", clock identity : 0x%"PRIx64, clk_id); 397 398 /* port identity */ 399 len -= 8; bp += 8; port_id = GET_BE_U_2(bp); ND_PRINT(", port id : %u", port_id); 400 401 /* sequence ID */ 402 len -= 2; bp += 2; seq_id = GET_BE_U_2(bp); ND_PRINT(", seq id : %u", seq_id); 403 404 /* control */ 405 len -= 2; bp += 2; control = GET_U_1(bp) ; 406 ND_PRINT(", control : %u (%s)", control, tok2str(ptp_control_field, "Reserved", control)); 407 408 /* log message interval */ 409 lm_int = GET_BE_U_2(bp) & PTP_LOGMSG_MASK; ND_PRINT(", log message interval : %u", lm_int); len -= 2; bp += 2; 410 411 switch(msg_type) { 412 case M_SYNC: 413 ptp_print_timestamp(ndo, bp, &len, p_origin_ts); 414 break; 415 case M_DELAY_REQ: 416 ptp_print_timestamp(ndo, bp, &len, p_origin_ts); 417 break; 418 case M_PDELAY_REQ: 419 ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts); 420 break; 421 case M_PDELAY_RESP: 422 ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts); 423 break; 424 case M_FOLLOW_UP: 425 ptp_print_timestamp(ndo, bp, &len, p_porigin_ts); 426 break; 427 case M_DELAY_RESP: 428 ptp_print_timestamp_identity(ndo, bp, &len, p_recv_ts); 429 break; 430 case M_PDELAY_RESP_FOLLOW_UP: 431 ptp_print_timestamp_identity(ndo, bp, &len, p_porigin_ts); 432 break; 433 case M_ANNOUNCE: 434 ptp_print_announce_msg(ndo, bp, &len); 435 break; 436 case M_SIGNALLING: 437 ptp_print_port_id(ndo, bp, &len); 438 break; 439 case M_MANAGEMENT: 440 ptp_print_mgmt_msg(ndo, bp, &len); 441 break; 442 default: 443 break; 444 } 445 } 446 /* 447 * PTP general message 448 */ 449 void 450 ptp_print(netdissect_options *ndo, const u_char *bp, u_int length) 451 { 452 u_int vers; 453 454 ndo->ndo_protocol = "ptp"; 455 ND_LCHECK_U(length, PTP_HDR_LEN); 456 vers = GET_BE_U_2(bp) & PTP_VERS_MASK; 457 ND_PRINT("PTPv%u",vers); 458 switch(vers) { 459 case PTP_VER_1: 460 ptp_print_1(ndo); 461 break; 462 case PTP_VER_2: 463 ptp_print_2(ndo, bp, length); 464 break; 465 default: 466 //ND_PRINT("ERROR: unknown-version\n"); 467 break; 468 } 469 return; 470 471 invalid: 472 nd_print_invalid(ndo); 473 } 474 475 static void 476 ptp_print_timestamp(netdissect_options *ndo, const u_char *bp, u_int *len, const char *stype) 477 { 478 uint64_t secs; 479 uint32_t nsecs; 480 481 ND_PRINT(", %s :", stype); 482 /* sec time stamp 6 bytes */ 483 secs = GET_BE_U_6(bp); 484 ND_PRINT(" %"PRIu64" seconds,", secs); 485 *len -= 6; 486 bp += 6; 487 488 /* NS time stamp 4 bytes */ 489 nsecs = GET_BE_U_4(bp); 490 ND_PRINT(" %u nanoseconds", nsecs); 491 *len -= 4; 492 bp += 4; 493 } 494 static void 495 ptp_print_timestamp_identity(netdissect_options *ndo, 496 const u_char *bp, u_int *len, const char *ttype) 497 { 498 uint64_t secs; 499 uint32_t nsecs; 500 uint16_t port_id; 501 uint64_t port_identity; 502 503 ND_PRINT(", %s :", ttype); 504 /* sec time stamp 6 bytes */ 505 secs = GET_BE_U_6(bp); 506 ND_PRINT(" %"PRIu64" seconds,", secs); 507 *len -= 6; 508 bp += 6; 509 510 /* NS time stamp 4 bytes */ 511 nsecs = GET_BE_U_4(bp); 512 ND_PRINT(" %u nanoseconds", nsecs); 513 *len -= 4; 514 bp += 4; 515 516 /* port identity*/ 517 port_identity = GET_BE_U_8(bp); 518 ND_PRINT(", port identity : 0x%"PRIx64, port_identity); 519 *len -= 8; 520 bp += 8; 521 522 /* port id */ 523 port_id = GET_BE_U_2(bp); 524 ND_PRINT(", port id : %u", port_id); 525 *len -= 2; 526 bp += 2; 527 } 528 static void 529 ptp_print_announce_msg(netdissect_options *ndo, const u_char *bp, u_int *len) 530 { 531 uint8_t rsvd, gm_prio_1, gm_prio_2, gm_clk_cls, gm_clk_acc, time_src; 532 uint16_t origin_cur_utc, gm_clk_var, steps_removed; 533 uint64_t gm_clock_id; 534 uint64_t secs; 535 uint32_t nsecs; 536 537 ND_PRINT(", %s :", p_origin_ts); 538 /* sec time stamp 6 bytes */ 539 secs = GET_BE_U_6(bp); 540 ND_PRINT(" %"PRIu64" seconds", secs); 541 *len -= 6; 542 bp += 6; 543 544 /* NS time stamp 4 bytes */ 545 nsecs = GET_BE_U_4(bp); 546 ND_PRINT(" %u nanoseconds", nsecs); 547 *len -= 4; 548 bp += 4; 549 550 /* origin cur utc */ 551 origin_cur_utc = GET_BE_U_2(bp); 552 ND_PRINT(", origin cur utc :%u", origin_cur_utc); 553 *len -= 2; 554 bp += 2; 555 556 /* rsvd */ 557 rsvd = GET_U_1(bp); 558 ND_PRINT(", rsvd : %u", rsvd); 559 *len -= 1; 560 bp += 1; 561 562 /* gm prio */ 563 gm_prio_1 = GET_U_1(bp); 564 ND_PRINT(", gm priority_1 : %u", gm_prio_1); 565 *len -= 1; 566 bp += 1; 567 568 /* GM clock class */ 569 gm_clk_cls = GET_U_1(bp); 570 ND_PRINT(", gm clock class : %u", gm_clk_cls); 571 *len -= 1; 572 bp += 1; 573 /* GM clock accuracy */ 574 gm_clk_acc = GET_U_1(bp); 575 ND_PRINT(", gm clock accuracy : %u", gm_clk_acc); 576 *len -= 1; 577 bp += 1; 578 /* GM clock variance */ 579 gm_clk_var = GET_BE_U_2(bp); 580 ND_PRINT(", gm clock variance : %u", gm_clk_var); 581 *len -= 2; 582 bp += 2; 583 /* GM Prio 2 */ 584 gm_prio_2 = GET_U_1(bp); 585 ND_PRINT(", gm priority_2 : %u", gm_prio_2); 586 *len -= 1; 587 bp += 1; 588 589 /* GM Clock Identity */ 590 gm_clock_id = GET_BE_U_8(bp); 591 ND_PRINT(", gm clock id : 0x%"PRIx64, gm_clock_id); 592 *len -= 8; 593 bp += 8; 594 /* steps removed */ 595 steps_removed = GET_BE_U_2(bp); 596 ND_PRINT(", steps removed : %u", steps_removed); 597 *len -= 2; 598 bp += 2; 599 /* Time source */ 600 time_src = GET_U_1(bp); 601 ND_PRINT(", time source : 0x%x", time_src); 602 *len -= 1; 603 bp += 1; 604 605 } 606 static void 607 ptp_print_port_id(netdissect_options *ndo, const u_char *bp, u_int *len) 608 { 609 uint16_t port_id; 610 uint64_t port_identity; 611 612 /* port identity*/ 613 port_identity = GET_BE_U_8(bp); 614 ND_PRINT(", port identity : 0x%"PRIx64, port_identity); 615 *len -= 8; 616 bp += 8; 617 618 /* port id */ 619 port_id = GET_BE_U_2(bp); 620 ND_PRINT(", port id : %u", port_id); 621 *len -= 2; 622 bp += 2; 623 624 } 625 626 static void 627 ptp_print_mgmt_msg(netdissect_options *ndo, const u_char *bp, u_int *len) 628 { 629 ptp_print_port_id(ndo, bp, len); 630 print_field(ndo, ", start boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE); 631 print_field(ndo, ", boundary hops ", PTP_UCHAR_LEN, bp, len, PTP_FALSE); 632 print_field(ndo, ", flags ", PTP_UCHAR_LEN, bp, len, PTP_TRUE); 633 print_field(ndo, ", reserved ", PTP_UCHAR_LEN, bp, len, PTP_TRUE); 634 } 635