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 Andy Heffernan (ahh@juniper.net) 14 */ 15 16 #define NETDISSECT_REWORKED 17 #ifdef HAVE_CONFIG_H 18 #include "config.h" 19 #endif 20 21 #include <tcpdump-stdinc.h> 22 23 #include "interface.h" 24 #include "extract.h" 25 #include "addrtoname.h" 26 27 #include "ip.h" 28 #ifdef INET6 29 #include "ip6.h" 30 #endif 31 #include "ipproto.h" 32 #include "af.h" 33 34 /* 35 * PGM header (RFC 3208) 36 */ 37 struct pgm_header { 38 uint16_t pgm_sport; 39 uint16_t pgm_dport; 40 uint8_t pgm_type; 41 uint8_t pgm_options; 42 uint16_t pgm_sum; 43 uint8_t pgm_gsid[6]; 44 uint16_t pgm_length; 45 }; 46 47 struct pgm_spm { 48 uint32_t pgms_seq; 49 uint32_t pgms_trailseq; 50 uint32_t pgms_leadseq; 51 uint16_t pgms_nla_afi; 52 uint16_t pgms_reserved; 53 /* ... uint8_t pgms_nla[0]; */ 54 /* ... options */ 55 }; 56 57 struct pgm_nak { 58 uint32_t pgmn_seq; 59 uint16_t pgmn_source_afi; 60 uint16_t pgmn_reserved; 61 /* ... uint8_t pgmn_source[0]; */ 62 /* ... uint16_t pgmn_group_afi */ 63 /* ... uint16_t pgmn_reserved2; */ 64 /* ... uint8_t pgmn_group[0]; */ 65 /* ... options */ 66 }; 67 68 struct pgm_ack { 69 uint32_t pgma_rx_max_seq; 70 uint32_t pgma_bitmap; 71 /* ... options */ 72 }; 73 74 struct pgm_poll { 75 uint32_t pgmp_seq; 76 uint16_t pgmp_round; 77 uint16_t pgmp_reserved; 78 /* ... options */ 79 }; 80 81 struct pgm_polr { 82 uint32_t pgmp_seq; 83 uint16_t pgmp_round; 84 uint16_t pgmp_subtype; 85 uint16_t pgmp_nla_afi; 86 uint16_t pgmp_reserved; 87 /* ... uint8_t pgmp_nla[0]; */ 88 /* ... options */ 89 }; 90 91 struct pgm_data { 92 uint32_t pgmd_seq; 93 uint32_t pgmd_trailseq; 94 /* ... options */ 95 }; 96 97 typedef enum _pgm_type { 98 PGM_SPM = 0, /* source path message */ 99 PGM_POLL = 1, /* POLL Request */ 100 PGM_POLR = 2, /* POLL Response */ 101 PGM_ODATA = 4, /* original data */ 102 PGM_RDATA = 5, /* repair data */ 103 PGM_NAK = 8, /* NAK */ 104 PGM_NULLNAK = 9, /* Null NAK */ 105 PGM_NCF = 10, /* NAK Confirmation */ 106 PGM_ACK = 11, /* ACK for congestion control */ 107 PGM_SPMR = 12, /* SPM request */ 108 PGM_MAX = 255 109 } pgm_type; 110 111 #define PGM_OPT_BIT_PRESENT 0x01 112 #define PGM_OPT_BIT_NETWORK 0x02 113 #define PGM_OPT_BIT_VAR_PKTLEN 0x40 114 #define PGM_OPT_BIT_PARITY 0x80 115 116 #define PGM_OPT_LENGTH 0x00 117 #define PGM_OPT_FRAGMENT 0x01 118 #define PGM_OPT_NAK_LIST 0x02 119 #define PGM_OPT_JOIN 0x03 120 #define PGM_OPT_NAK_BO_IVL 0x04 121 #define PGM_OPT_NAK_BO_RNG 0x05 122 123 #define PGM_OPT_REDIRECT 0x07 124 #define PGM_OPT_PARITY_PRM 0x08 125 #define PGM_OPT_PARITY_GRP 0x09 126 #define PGM_OPT_CURR_TGSIZE 0x0A 127 #define PGM_OPT_NBR_UNREACH 0x0B 128 #define PGM_OPT_PATH_NLA 0x0C 129 130 #define PGM_OPT_SYN 0x0D 131 #define PGM_OPT_FIN 0x0E 132 #define PGM_OPT_RST 0x0F 133 #define PGM_OPT_CR 0x10 134 #define PGM_OPT_CRQST 0x11 135 136 #define PGM_OPT_PGMCC_DATA 0x12 137 #define PGM_OPT_PGMCC_FEEDBACK 0x13 138 139 #define PGM_OPT_MASK 0x7f 140 141 #define PGM_OPT_END 0x80 /* end of options marker */ 142 143 #define PGM_MIN_OPT_LEN 4 144 145 void 146 pgm_print(netdissect_options *ndo, 147 register const u_char *bp, register u_int length, 148 register const u_char *bp2) 149 { 150 register const struct pgm_header *pgm; 151 register const struct ip *ip; 152 register char ch; 153 uint16_t sport, dport; 154 int addr_size; 155 const void *nla; 156 int nla_af; 157 #ifdef INET6 158 char nla_buf[INET6_ADDRSTRLEN]; 159 register const struct ip6_hdr *ip6; 160 #else 161 char nla_buf[INET_ADDRSTRLEN]; 162 #endif 163 uint8_t opt_type, opt_len; 164 uint32_t seq, opts_len, len, offset; 165 166 pgm = (struct pgm_header *)bp; 167 ip = (struct ip *)bp2; 168 #ifdef INET6 169 if (IP_V(ip) == 6) 170 ip6 = (struct ip6_hdr *)bp2; 171 else 172 ip6 = NULL; 173 #else /* INET6 */ 174 if (IP_V(ip) == 6) { 175 ND_PRINT((ndo, "Can't handle IPv6")); 176 return; 177 } 178 #endif /* INET6 */ 179 ch = '\0'; 180 if (!ND_TTEST(pgm->pgm_dport)) { 181 #ifdef INET6 182 if (ip6) { 183 ND_PRINT((ndo, "%s > %s: [|pgm]", 184 ip6addr_string(ndo, &ip6->ip6_src), 185 ip6addr_string(ndo, &ip6->ip6_dst))); 186 return; 187 } else 188 #endif /* INET6 */ 189 { 190 ND_PRINT((ndo, "%s > %s: [|pgm]", 191 ipaddr_string(ndo, &ip->ip_src), 192 ipaddr_string(ndo, &ip->ip_dst))); 193 return; 194 } 195 } 196 197 sport = EXTRACT_16BITS(&pgm->pgm_sport); 198 dport = EXTRACT_16BITS(&pgm->pgm_dport); 199 200 #ifdef INET6 201 if (ip6) { 202 if (ip6->ip6_nxt == IPPROTO_PGM) { 203 ND_PRINT((ndo, "%s.%s > %s.%s: ", 204 ip6addr_string(ndo, &ip6->ip6_src), 205 tcpport_string(sport), 206 ip6addr_string(ndo, &ip6->ip6_dst), 207 tcpport_string(dport))); 208 } else { 209 ND_PRINT((ndo, "%s > %s: ", 210 tcpport_string(sport), tcpport_string(dport))); 211 } 212 } else 213 #endif /*INET6*/ 214 { 215 if (ip->ip_p == IPPROTO_PGM) { 216 ND_PRINT((ndo, "%s.%s > %s.%s: ", 217 ipaddr_string(ndo, &ip->ip_src), 218 tcpport_string(sport), 219 ipaddr_string(ndo, &ip->ip_dst), 220 tcpport_string(dport))); 221 } else { 222 ND_PRINT((ndo, "%s > %s: ", 223 tcpport_string(sport), tcpport_string(dport))); 224 } 225 } 226 227 ND_TCHECK(*pgm); 228 229 ND_PRINT((ndo, "PGM, length %u", EXTRACT_16BITS(&pgm->pgm_length))); 230 231 if (!ndo->ndo_vflag) 232 return; 233 234 ND_PRINT((ndo, " 0x%02x%02x%02x%02x%02x%02x ", 235 pgm->pgm_gsid[0], 236 pgm->pgm_gsid[1], 237 pgm->pgm_gsid[2], 238 pgm->pgm_gsid[3], 239 pgm->pgm_gsid[4], 240 pgm->pgm_gsid[5])); 241 switch (pgm->pgm_type) { 242 case PGM_SPM: { 243 struct pgm_spm *spm; 244 245 spm = (struct pgm_spm *)(pgm + 1); 246 ND_TCHECK(*spm); 247 248 switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) { 249 case AFNUM_INET: 250 addr_size = sizeof(struct in_addr); 251 nla_af = AF_INET; 252 break; 253 #ifdef INET6 254 case AFNUM_INET6: 255 addr_size = sizeof(struct in6_addr); 256 nla_af = AF_INET6; 257 break; 258 #endif 259 default: 260 goto trunc; 261 break; 262 } 263 bp = (u_char *) (spm + 1); 264 ND_TCHECK2(*bp, addr_size); 265 nla = bp; 266 bp += addr_size; 267 268 inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); 269 ND_PRINT((ndo, "SPM seq %u trail %u lead %u nla %s", 270 EXTRACT_32BITS(&spm->pgms_seq), 271 EXTRACT_32BITS(&spm->pgms_trailseq), 272 EXTRACT_32BITS(&spm->pgms_leadseq), 273 nla_buf)); 274 break; 275 } 276 277 case PGM_POLL: { 278 struct pgm_poll *poll; 279 280 poll = (struct pgm_poll *)(pgm + 1); 281 ND_TCHECK(*poll); 282 ND_PRINT((ndo, "POLL seq %u round %u", 283 EXTRACT_32BITS(&poll->pgmp_seq), 284 EXTRACT_16BITS(&poll->pgmp_round))); 285 bp = (u_char *) (poll + 1); 286 break; 287 } 288 case PGM_POLR: { 289 struct pgm_polr *polr; 290 uint32_t ivl, rnd, mask; 291 292 polr = (struct pgm_polr *)(pgm + 1); 293 ND_TCHECK(*polr); 294 295 switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) { 296 case AFNUM_INET: 297 addr_size = sizeof(struct in_addr); 298 nla_af = AF_INET; 299 break; 300 #ifdef INET6 301 case AFNUM_INET6: 302 addr_size = sizeof(struct in6_addr); 303 nla_af = AF_INET6; 304 break; 305 #endif 306 default: 307 goto trunc; 308 break; 309 } 310 bp = (u_char *) (polr + 1); 311 ND_TCHECK2(*bp, addr_size); 312 nla = bp; 313 bp += addr_size; 314 315 inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); 316 317 ND_TCHECK2(*bp, sizeof(uint32_t)); 318 ivl = EXTRACT_32BITS(bp); 319 bp += sizeof(uint32_t); 320 321 ND_TCHECK2(*bp, sizeof(uint32_t)); 322 rnd = EXTRACT_32BITS(bp); 323 bp += sizeof(uint32_t); 324 325 ND_TCHECK2(*bp, sizeof(uint32_t)); 326 mask = EXTRACT_32BITS(bp); 327 bp += sizeof(uint32_t); 328 329 ND_PRINT((ndo, "POLR seq %u round %u nla %s ivl %u rnd 0x%08x " 330 "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq), 331 EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask)); 332 break; 333 } 334 case PGM_ODATA: { 335 struct pgm_data *odata; 336 337 odata = (struct pgm_data *)(pgm + 1); 338 ND_TCHECK(*odata); 339 ND_PRINT((ndo, "ODATA trail %u seq %u", 340 EXTRACT_32BITS(&odata->pgmd_trailseq), 341 EXTRACT_32BITS(&odata->pgmd_seq))); 342 bp = (u_char *) (odata + 1); 343 break; 344 } 345 346 case PGM_RDATA: { 347 struct pgm_data *rdata; 348 349 rdata = (struct pgm_data *)(pgm + 1); 350 ND_TCHECK(*rdata); 351 ND_PRINT((ndo, "RDATA trail %u seq %u", 352 EXTRACT_32BITS(&rdata->pgmd_trailseq), 353 EXTRACT_32BITS(&rdata->pgmd_seq))); 354 bp = (u_char *) (rdata + 1); 355 break; 356 } 357 358 case PGM_NAK: 359 case PGM_NULLNAK: 360 case PGM_NCF: { 361 struct pgm_nak *nak; 362 const void *source, *group; 363 int source_af, group_af; 364 #ifdef INET6 365 char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN]; 366 #else 367 char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN]; 368 #endif 369 370 nak = (struct pgm_nak *)(pgm + 1); 371 ND_TCHECK(*nak); 372 373 /* 374 * Skip past the source, saving info along the way 375 * and stopping if we don't have enough. 376 */ 377 switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) { 378 case AFNUM_INET: 379 addr_size = sizeof(struct in_addr); 380 source_af = AF_INET; 381 break; 382 #ifdef INET6 383 case AFNUM_INET6: 384 addr_size = sizeof(struct in6_addr); 385 source_af = AF_INET6; 386 break; 387 #endif 388 default: 389 goto trunc; 390 break; 391 } 392 bp = (u_char *) (nak + 1); 393 ND_TCHECK2(*bp, addr_size); 394 source = bp; 395 bp += addr_size; 396 397 /* 398 * Skip past the group, saving info along the way 399 * and stopping if we don't have enough. 400 */ 401 switch (EXTRACT_16BITS(bp)) { 402 case AFNUM_INET: 403 addr_size = sizeof(struct in_addr); 404 group_af = AF_INET; 405 break; 406 #ifdef INET6 407 case AFNUM_INET6: 408 addr_size = sizeof(struct in6_addr); 409 group_af = AF_INET6; 410 break; 411 #endif 412 default: 413 goto trunc; 414 break; 415 } 416 bp += (2 * sizeof(uint16_t)); 417 ND_TCHECK2(*bp, addr_size); 418 group = bp; 419 bp += addr_size; 420 421 /* 422 * Options decoding can go here. 423 */ 424 inet_ntop(source_af, source, source_buf, sizeof(source_buf)); 425 inet_ntop(group_af, group, group_buf, sizeof(group_buf)); 426 switch (pgm->pgm_type) { 427 case PGM_NAK: 428 ND_PRINT((ndo, "NAK ")); 429 break; 430 case PGM_NULLNAK: 431 ND_PRINT((ndo, "NNAK ")); 432 break; 433 case PGM_NCF: 434 ND_PRINT((ndo, "NCF ")); 435 break; 436 default: 437 break; 438 } 439 ND_PRINT((ndo, "(%s -> %s), seq %u", 440 source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq))); 441 break; 442 } 443 444 case PGM_ACK: { 445 struct pgm_ack *ack; 446 447 ack = (struct pgm_ack *)(pgm + 1); 448 ND_TCHECK(*ack); 449 ND_PRINT((ndo, "ACK seq %u", 450 EXTRACT_32BITS(&ack->pgma_rx_max_seq))); 451 bp = (u_char *) (ack + 1); 452 break; 453 } 454 455 case PGM_SPMR: 456 ND_PRINT((ndo, "SPMR")); 457 break; 458 459 default: 460 ND_PRINT((ndo, "UNKNOWN type 0x%02x", pgm->pgm_type)); 461 break; 462 463 } 464 if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) { 465 466 /* 467 * make sure there's enough for the first option header 468 */ 469 if (!ND_TTEST2(*bp, PGM_MIN_OPT_LEN)) { 470 ND_PRINT((ndo, "[|OPT]")); 471 return; 472 } 473 474 /* 475 * That option header MUST be an OPT_LENGTH option 476 * (see the first paragraph of section 9.1 in RFC 3208). 477 */ 478 opt_type = *bp++; 479 if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) { 480 ND_PRINT((ndo, "[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK)); 481 return; 482 } 483 opt_len = *bp++; 484 if (opt_len != 4) { 485 ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len)); 486 return; 487 } 488 opts_len = EXTRACT_16BITS(bp); 489 if (opts_len < 4) { 490 ND_PRINT((ndo, "[Bad total option length %u < 4]", opts_len)); 491 return; 492 } 493 bp += sizeof(uint16_t); 494 ND_PRINT((ndo, " OPTS LEN %d", opts_len)); 495 opts_len -= 4; 496 497 while (opts_len) { 498 if (opts_len < PGM_MIN_OPT_LEN) { 499 ND_PRINT((ndo, "[Total option length leaves no room for final option]")); 500 return; 501 } 502 opt_type = *bp++; 503 opt_len = *bp++; 504 if (opt_len < PGM_MIN_OPT_LEN) { 505 ND_PRINT((ndo, "[Bad option, length %u < %u]", opt_len, 506 PGM_MIN_OPT_LEN)); 507 break; 508 } 509 if (opts_len < opt_len) { 510 ND_PRINT((ndo, "[Total option length leaves no room for final option]")); 511 return; 512 } 513 if (!ND_TTEST2(*bp, opt_len - 2)) { 514 ND_PRINT((ndo, " [|OPT]")); 515 return; 516 } 517 518 switch (opt_type & PGM_OPT_MASK) { 519 case PGM_OPT_LENGTH: 520 if (opt_len != 4) { 521 ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len)); 522 return; 523 } 524 ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp))); 525 bp += sizeof(uint16_t); 526 opts_len -= 4; 527 break; 528 529 case PGM_OPT_FRAGMENT: 530 if (opt_len != 16) { 531 ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != 16]", opt_len)); 532 return; 533 } 534 bp += 2; 535 seq = EXTRACT_32BITS(bp); 536 bp += sizeof(uint32_t); 537 offset = EXTRACT_32BITS(bp); 538 bp += sizeof(uint32_t); 539 len = EXTRACT_32BITS(bp); 540 bp += sizeof(uint32_t); 541 ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len)); 542 opts_len -= 16; 543 break; 544 545 case PGM_OPT_NAK_LIST: 546 bp += 2; 547 opt_len -= sizeof(uint32_t); /* option header */ 548 ND_PRINT((ndo, " NAK LIST")); 549 while (opt_len) { 550 if (opt_len < sizeof(uint32_t)) { 551 ND_PRINT((ndo, "[Option length not a multiple of 4]")); 552 return; 553 } 554 ND_TCHECK2(*bp, sizeof(uint32_t)); 555 ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp))); 556 bp += sizeof(uint32_t); 557 opt_len -= sizeof(uint32_t); 558 opts_len -= sizeof(uint32_t); 559 } 560 break; 561 562 case PGM_OPT_JOIN: 563 if (opt_len != 8) { 564 ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != 8]", opt_len)); 565 return; 566 } 567 bp += 2; 568 seq = EXTRACT_32BITS(bp); 569 bp += sizeof(uint32_t); 570 ND_PRINT((ndo, " JOIN %u", seq)); 571 opts_len -= 8; 572 break; 573 574 case PGM_OPT_NAK_BO_IVL: 575 if (opt_len != 12) { 576 ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len)); 577 return; 578 } 579 bp += 2; 580 offset = EXTRACT_32BITS(bp); 581 bp += sizeof(uint32_t); 582 seq = EXTRACT_32BITS(bp); 583 bp += sizeof(uint32_t); 584 ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq)); 585 opts_len -= 12; 586 break; 587 588 case PGM_OPT_NAK_BO_RNG: 589 if (opt_len != 12) { 590 ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len)); 591 return; 592 } 593 bp += 2; 594 offset = EXTRACT_32BITS(bp); 595 bp += sizeof(uint32_t); 596 seq = EXTRACT_32BITS(bp); 597 bp += sizeof(uint32_t); 598 ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq)); 599 opts_len -= 12; 600 break; 601 602 case PGM_OPT_REDIRECT: 603 bp += 2; 604 switch (EXTRACT_16BITS(bp)) { 605 case AFNUM_INET: 606 addr_size = sizeof(struct in_addr); 607 nla_af = AF_INET; 608 break; 609 #ifdef INET6 610 case AFNUM_INET6: 611 addr_size = sizeof(struct in6_addr); 612 nla_af = AF_INET6; 613 break; 614 #endif 615 default: 616 goto trunc; 617 break; 618 } 619 bp += (2 * sizeof(uint16_t)); 620 if (opt_len != 4 + addr_size) { 621 ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len)); 622 return; 623 } 624 ND_TCHECK2(*bp, addr_size); 625 nla = bp; 626 bp += addr_size; 627 628 inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); 629 ND_PRINT((ndo, " REDIRECT %s", (char *)nla)); 630 opts_len -= 4 + addr_size; 631 break; 632 633 case PGM_OPT_PARITY_PRM: 634 if (opt_len != 8) { 635 ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len)); 636 return; 637 } 638 bp += 2; 639 len = EXTRACT_32BITS(bp); 640 bp += sizeof(uint32_t); 641 ND_PRINT((ndo, " PARITY MAXTGS %u", len)); 642 opts_len -= 8; 643 break; 644 645 case PGM_OPT_PARITY_GRP: 646 if (opt_len != 8) { 647 ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len)); 648 return; 649 } 650 bp += 2; 651 seq = EXTRACT_32BITS(bp); 652 bp += sizeof(uint32_t); 653 ND_PRINT((ndo, " PARITY GROUP %u", seq)); 654 opts_len -= 8; 655 break; 656 657 case PGM_OPT_CURR_TGSIZE: 658 if (opt_len != 8) { 659 ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len)); 660 return; 661 } 662 bp += 2; 663 len = EXTRACT_32BITS(bp); 664 bp += sizeof(uint32_t); 665 ND_PRINT((ndo, " PARITY ATGS %u", len)); 666 opts_len -= 8; 667 break; 668 669 case PGM_OPT_NBR_UNREACH: 670 if (opt_len != 4) { 671 ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len)); 672 return; 673 } 674 bp += 2; 675 ND_PRINT((ndo, " NBR_UNREACH")); 676 opts_len -= 4; 677 break; 678 679 case PGM_OPT_PATH_NLA: 680 ND_PRINT((ndo, " PATH_NLA [%d]", opt_len)); 681 bp += opt_len; 682 opts_len -= opt_len; 683 break; 684 685 case PGM_OPT_SYN: 686 if (opt_len != 4) { 687 ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != 4]", opt_len)); 688 return; 689 } 690 bp += 2; 691 ND_PRINT((ndo, " SYN")); 692 opts_len -= 4; 693 break; 694 695 case PGM_OPT_FIN: 696 if (opt_len != 4) { 697 ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != 4]", opt_len)); 698 return; 699 } 700 bp += 2; 701 ND_PRINT((ndo, " FIN")); 702 opts_len -= 4; 703 break; 704 705 case PGM_OPT_RST: 706 if (opt_len != 4) { 707 ND_PRINT((ndo, "[Bad OPT_RST option, length %u != 4]", opt_len)); 708 return; 709 } 710 bp += 2; 711 ND_PRINT((ndo, " RST")); 712 opts_len -= 4; 713 break; 714 715 case PGM_OPT_CR: 716 ND_PRINT((ndo, " CR")); 717 bp += opt_len; 718 opts_len -= opt_len; 719 break; 720 721 case PGM_OPT_CRQST: 722 if (opt_len != 4) { 723 ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != 4]", opt_len)); 724 return; 725 } 726 bp += 2; 727 ND_PRINT((ndo, " CRQST")); 728 opts_len -= 4; 729 break; 730 731 case PGM_OPT_PGMCC_DATA: 732 bp += 2; 733 offset = EXTRACT_32BITS(bp); 734 bp += sizeof(uint32_t); 735 switch (EXTRACT_16BITS(bp)) { 736 case AFNUM_INET: 737 addr_size = sizeof(struct in_addr); 738 nla_af = AF_INET; 739 break; 740 #ifdef INET6 741 case AFNUM_INET6: 742 addr_size = sizeof(struct in6_addr); 743 nla_af = AF_INET6; 744 break; 745 #endif 746 default: 747 goto trunc; 748 break; 749 } 750 bp += (2 * sizeof(uint16_t)); 751 if (opt_len != 12 + addr_size) { 752 ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); 753 return; 754 } 755 ND_TCHECK2(*bp, addr_size); 756 nla = bp; 757 bp += addr_size; 758 759 inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); 760 ND_PRINT((ndo, " PGMCC DATA %u %s", offset, (char*)nla)); 761 opts_len -= 16; 762 break; 763 764 case PGM_OPT_PGMCC_FEEDBACK: 765 bp += 2; 766 offset = EXTRACT_32BITS(bp); 767 bp += sizeof(uint32_t); 768 switch (EXTRACT_16BITS(bp)) { 769 case AFNUM_INET: 770 addr_size = sizeof(struct in_addr); 771 nla_af = AF_INET; 772 break; 773 #ifdef INET6 774 case AFNUM_INET6: 775 addr_size = sizeof(struct in6_addr); 776 nla_af = AF_INET6; 777 break; 778 #endif 779 default: 780 goto trunc; 781 break; 782 } 783 bp += (2 * sizeof(uint16_t)); 784 if (opt_len != 12 + addr_size) { 785 ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != 12 + address size]", opt_len)); 786 return; 787 } 788 ND_TCHECK2(*bp, addr_size); 789 nla = bp; 790 bp += addr_size; 791 792 inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); 793 ND_PRINT((ndo, " PGMCC FEEDBACK %u %s", offset, (char*)nla)); 794 opts_len -= 16; 795 break; 796 797 default: 798 ND_PRINT((ndo, " OPT_%02X [%d] ", opt_type, opt_len)); 799 bp += opt_len; 800 opts_len -= opt_len; 801 break; 802 } 803 804 if (opt_type & PGM_OPT_END) 805 break; 806 } 807 } 808 809 ND_PRINT((ndo, " [%u]", length)); 810 if (ndo->ndo_packettype == PT_PGM_ZMTP1 && 811 (pgm->pgm_type == PGM_ODATA || pgm->pgm_type == PGM_RDATA)) 812 zmtp1_print_datagram(ndo, bp, EXTRACT_16BITS(&pgm->pgm_length)); 813 814 return; 815 816 trunc: 817 ND_PRINT((ndo, "[|pgm]")); 818 if (ch != '\0') 819 ND_PRINT((ndo, ">")); 820 } 821