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