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 /* \summary: Pragmatic General Multicast (PGM) printer */ 17 18 #ifdef HAVE_CONFIG_H 19 #include "config.h" 20 #endif 21 22 #include <netdissect-stdinc.h> 23 24 #include "netdissect.h" 25 #include "extract.h" 26 #include "addrtoname.h" 27 #include "addrtostr.h" 28 29 #include "ip.h" 30 #include "ip6.h" 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 u_int nla_afnum; 155 char nla_buf[INET6_ADDRSTRLEN]; 156 register const struct ip6_hdr *ip6; 157 uint8_t opt_type, opt_len; 158 uint32_t seq, opts_len, len, offset; 159 160 pgm = (const struct pgm_header *)bp; 161 ip = (const struct ip *)bp2; 162 if (IP_V(ip) == 6) 163 ip6 = (const struct ip6_hdr *)bp2; 164 else 165 ip6 = NULL; 166 ch = '\0'; 167 if (!ND_TTEST(pgm->pgm_dport)) { 168 if (ip6) { 169 ND_PRINT((ndo, "%s > %s: [|pgm]", 170 ip6addr_string(ndo, &ip6->ip6_src), 171 ip6addr_string(ndo, &ip6->ip6_dst))); 172 return; 173 } else { 174 ND_PRINT((ndo, "%s > %s: [|pgm]", 175 ipaddr_string(ndo, &ip->ip_src), 176 ipaddr_string(ndo, &ip->ip_dst))); 177 return; 178 } 179 } 180 181 sport = EXTRACT_16BITS(&pgm->pgm_sport); 182 dport = EXTRACT_16BITS(&pgm->pgm_dport); 183 184 if (ip6) { 185 if (ip6->ip6_nxt == IPPROTO_PGM) { 186 ND_PRINT((ndo, "%s.%s > %s.%s: ", 187 ip6addr_string(ndo, &ip6->ip6_src), 188 tcpport_string(ndo, sport), 189 ip6addr_string(ndo, &ip6->ip6_dst), 190 tcpport_string(ndo, dport))); 191 } else { 192 ND_PRINT((ndo, "%s > %s: ", 193 tcpport_string(ndo, sport), tcpport_string(ndo, dport))); 194 } 195 } else { 196 if (ip->ip_p == IPPROTO_PGM) { 197 ND_PRINT((ndo, "%s.%s > %s.%s: ", 198 ipaddr_string(ndo, &ip->ip_src), 199 tcpport_string(ndo, sport), 200 ipaddr_string(ndo, &ip->ip_dst), 201 tcpport_string(ndo, dport))); 202 } else { 203 ND_PRINT((ndo, "%s > %s: ", 204 tcpport_string(ndo, sport), tcpport_string(ndo, dport))); 205 } 206 } 207 208 ND_TCHECK(*pgm); 209 210 ND_PRINT((ndo, "PGM, length %u", EXTRACT_16BITS(&pgm->pgm_length))); 211 212 if (!ndo->ndo_vflag) 213 return; 214 215 ND_PRINT((ndo, " 0x%02x%02x%02x%02x%02x%02x ", 216 pgm->pgm_gsid[0], 217 pgm->pgm_gsid[1], 218 pgm->pgm_gsid[2], 219 pgm->pgm_gsid[3], 220 pgm->pgm_gsid[4], 221 pgm->pgm_gsid[5])); 222 switch (pgm->pgm_type) { 223 case PGM_SPM: { 224 const struct pgm_spm *spm; 225 226 spm = (const struct pgm_spm *)(pgm + 1); 227 ND_TCHECK(*spm); 228 bp = (const u_char *) (spm + 1); 229 230 switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) { 231 case AFNUM_INET: 232 ND_TCHECK2(*bp, sizeof(struct in_addr)); 233 addrtostr(bp, nla_buf, sizeof(nla_buf)); 234 bp += sizeof(struct in_addr); 235 break; 236 case AFNUM_INET6: 237 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 238 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 239 bp += sizeof(struct in6_addr); 240 break; 241 default: 242 goto trunc; 243 break; 244 } 245 246 ND_PRINT((ndo, "SPM seq %u trail %u lead %u nla %s", 247 EXTRACT_32BITS(&spm->pgms_seq), 248 EXTRACT_32BITS(&spm->pgms_trailseq), 249 EXTRACT_32BITS(&spm->pgms_leadseq), 250 nla_buf)); 251 break; 252 } 253 254 case PGM_POLL: { 255 const struct pgm_poll *poll_msg; 256 257 poll_msg = (const struct pgm_poll *)(pgm + 1); 258 ND_TCHECK(*poll_msg); 259 ND_PRINT((ndo, "POLL seq %u round %u", 260 EXTRACT_32BITS(&poll_msg->pgmp_seq), 261 EXTRACT_16BITS(&poll_msg->pgmp_round))); 262 bp = (const u_char *) (poll_msg + 1); 263 break; 264 } 265 case PGM_POLR: { 266 const struct pgm_polr *polr; 267 uint32_t ivl, rnd, mask; 268 269 polr = (const struct pgm_polr *)(pgm + 1); 270 ND_TCHECK(*polr); 271 bp = (const u_char *) (polr + 1); 272 273 switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) { 274 case AFNUM_INET: 275 ND_TCHECK2(*bp, sizeof(struct in_addr)); 276 addrtostr(bp, nla_buf, sizeof(nla_buf)); 277 bp += sizeof(struct in_addr); 278 break; 279 case AFNUM_INET6: 280 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 281 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 282 bp += sizeof(struct in6_addr); 283 break; 284 default: 285 goto trunc; 286 break; 287 } 288 289 ND_TCHECK2(*bp, sizeof(uint32_t)); 290 ivl = EXTRACT_32BITS(bp); 291 bp += sizeof(uint32_t); 292 293 ND_TCHECK2(*bp, sizeof(uint32_t)); 294 rnd = EXTRACT_32BITS(bp); 295 bp += sizeof(uint32_t); 296 297 ND_TCHECK2(*bp, sizeof(uint32_t)); 298 mask = EXTRACT_32BITS(bp); 299 bp += sizeof(uint32_t); 300 301 ND_PRINT((ndo, "POLR seq %u round %u nla %s ivl %u rnd 0x%08x " 302 "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq), 303 EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask)); 304 break; 305 } 306 case PGM_ODATA: { 307 const struct pgm_data *odata; 308 309 odata = (const struct pgm_data *)(pgm + 1); 310 ND_TCHECK(*odata); 311 ND_PRINT((ndo, "ODATA trail %u seq %u", 312 EXTRACT_32BITS(&odata->pgmd_trailseq), 313 EXTRACT_32BITS(&odata->pgmd_seq))); 314 bp = (const u_char *) (odata + 1); 315 break; 316 } 317 318 case PGM_RDATA: { 319 const struct pgm_data *rdata; 320 321 rdata = (const struct pgm_data *)(pgm + 1); 322 ND_TCHECK(*rdata); 323 ND_PRINT((ndo, "RDATA trail %u seq %u", 324 EXTRACT_32BITS(&rdata->pgmd_trailseq), 325 EXTRACT_32BITS(&rdata->pgmd_seq))); 326 bp = (const u_char *) (rdata + 1); 327 break; 328 } 329 330 case PGM_NAK: 331 case PGM_NULLNAK: 332 case PGM_NCF: { 333 const struct pgm_nak *nak; 334 char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN]; 335 336 nak = (const struct pgm_nak *)(pgm + 1); 337 ND_TCHECK(*nak); 338 bp = (const u_char *) (nak + 1); 339 340 /* 341 * Skip past the source, saving info along the way 342 * and stopping if we don't have enough. 343 */ 344 switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) { 345 case AFNUM_INET: 346 ND_TCHECK2(*bp, sizeof(struct in_addr)); 347 addrtostr(bp, source_buf, sizeof(source_buf)); 348 bp += sizeof(struct in_addr); 349 break; 350 case AFNUM_INET6: 351 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 352 addrtostr6(bp, source_buf, sizeof(source_buf)); 353 bp += sizeof(struct in6_addr); 354 break; 355 default: 356 goto trunc; 357 break; 358 } 359 360 /* 361 * Skip past the group, saving info along the way 362 * and stopping if we don't have enough. 363 */ 364 bp += (2 * sizeof(uint16_t)); 365 switch (EXTRACT_16BITS(bp)) { 366 case AFNUM_INET: 367 ND_TCHECK2(*bp, sizeof(struct in_addr)); 368 addrtostr(bp, group_buf, sizeof(group_buf)); 369 bp += sizeof(struct in_addr); 370 break; 371 case AFNUM_INET6: 372 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 373 addrtostr6(bp, group_buf, sizeof(group_buf)); 374 bp += sizeof(struct in6_addr); 375 break; 376 default: 377 goto trunc; 378 break; 379 } 380 381 /* 382 * Options decoding can go here. 383 */ 384 switch (pgm->pgm_type) { 385 case PGM_NAK: 386 ND_PRINT((ndo, "NAK ")); 387 break; 388 case PGM_NULLNAK: 389 ND_PRINT((ndo, "NNAK ")); 390 break; 391 case PGM_NCF: 392 ND_PRINT((ndo, "NCF ")); 393 break; 394 default: 395 break; 396 } 397 ND_PRINT((ndo, "(%s -> %s), seq %u", 398 source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq))); 399 break; 400 } 401 402 case PGM_ACK: { 403 const struct pgm_ack *ack; 404 405 ack = (const struct pgm_ack *)(pgm + 1); 406 ND_TCHECK(*ack); 407 ND_PRINT((ndo, "ACK seq %u", 408 EXTRACT_32BITS(&ack->pgma_rx_max_seq))); 409 bp = (const u_char *) (ack + 1); 410 break; 411 } 412 413 case PGM_SPMR: 414 ND_PRINT((ndo, "SPMR")); 415 break; 416 417 default: 418 ND_PRINT((ndo, "UNKNOWN type 0x%02x", pgm->pgm_type)); 419 break; 420 421 } 422 if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) { 423 424 /* 425 * make sure there's enough for the first option header 426 */ 427 if (!ND_TTEST2(*bp, PGM_MIN_OPT_LEN)) { 428 ND_PRINT((ndo, "[|OPT]")); 429 return; 430 } 431 432 /* 433 * That option header MUST be an OPT_LENGTH option 434 * (see the first paragraph of section 9.1 in RFC 3208). 435 */ 436 opt_type = *bp++; 437 if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) { 438 ND_PRINT((ndo, "[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK)); 439 return; 440 } 441 opt_len = *bp++; 442 if (opt_len != 4) { 443 ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len)); 444 return; 445 } 446 opts_len = EXTRACT_16BITS(bp); 447 if (opts_len < 4) { 448 ND_PRINT((ndo, "[Bad total option length %u < 4]", opts_len)); 449 return; 450 } 451 bp += sizeof(uint16_t); 452 ND_PRINT((ndo, " OPTS LEN %d", opts_len)); 453 opts_len -= 4; 454 455 while (opts_len) { 456 if (opts_len < PGM_MIN_OPT_LEN) { 457 ND_PRINT((ndo, "[Total option length leaves no room for final option]")); 458 return; 459 } 460 opt_type = *bp++; 461 opt_len = *bp++; 462 if (opt_len < PGM_MIN_OPT_LEN) { 463 ND_PRINT((ndo, "[Bad option, length %u < %u]", opt_len, 464 PGM_MIN_OPT_LEN)); 465 break; 466 } 467 if (opts_len < opt_len) { 468 ND_PRINT((ndo, "[Total option length leaves no room for final option]")); 469 return; 470 } 471 if (!ND_TTEST2(*bp, opt_len - 2)) { 472 ND_PRINT((ndo, " [|OPT]")); 473 return; 474 } 475 476 switch (opt_type & PGM_OPT_MASK) { 477 case PGM_OPT_LENGTH: 478 if (opt_len != 4) { 479 ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len)); 480 return; 481 } 482 ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp))); 483 bp += sizeof(uint16_t); 484 opts_len -= 4; 485 break; 486 487 case PGM_OPT_FRAGMENT: 488 if (opt_len != 16) { 489 ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != 16]", opt_len)); 490 return; 491 } 492 bp += 2; 493 seq = EXTRACT_32BITS(bp); 494 bp += sizeof(uint32_t); 495 offset = EXTRACT_32BITS(bp); 496 bp += sizeof(uint32_t); 497 len = EXTRACT_32BITS(bp); 498 bp += sizeof(uint32_t); 499 ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len)); 500 opts_len -= 16; 501 break; 502 503 case PGM_OPT_NAK_LIST: 504 bp += 2; 505 opt_len -= sizeof(uint32_t); /* option header */ 506 ND_PRINT((ndo, " NAK LIST")); 507 while (opt_len) { 508 if (opt_len < sizeof(uint32_t)) { 509 ND_PRINT((ndo, "[Option length not a multiple of 4]")); 510 return; 511 } 512 ND_TCHECK2(*bp, sizeof(uint32_t)); 513 ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp))); 514 bp += sizeof(uint32_t); 515 opt_len -= sizeof(uint32_t); 516 opts_len -= sizeof(uint32_t); 517 } 518 break; 519 520 case PGM_OPT_JOIN: 521 if (opt_len != 8) { 522 ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != 8]", opt_len)); 523 return; 524 } 525 bp += 2; 526 seq = EXTRACT_32BITS(bp); 527 bp += sizeof(uint32_t); 528 ND_PRINT((ndo, " JOIN %u", seq)); 529 opts_len -= 8; 530 break; 531 532 case PGM_OPT_NAK_BO_IVL: 533 if (opt_len != 12) { 534 ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len)); 535 return; 536 } 537 bp += 2; 538 offset = EXTRACT_32BITS(bp); 539 bp += sizeof(uint32_t); 540 seq = EXTRACT_32BITS(bp); 541 bp += sizeof(uint32_t); 542 ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq)); 543 opts_len -= 12; 544 break; 545 546 case PGM_OPT_NAK_BO_RNG: 547 if (opt_len != 12) { 548 ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len)); 549 return; 550 } 551 bp += 2; 552 offset = EXTRACT_32BITS(bp); 553 bp += sizeof(uint32_t); 554 seq = EXTRACT_32BITS(bp); 555 bp += sizeof(uint32_t); 556 ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq)); 557 opts_len -= 12; 558 break; 559 560 case PGM_OPT_REDIRECT: 561 bp += 2; 562 nla_afnum = EXTRACT_16BITS(bp); 563 bp += (2 * sizeof(uint16_t)); 564 switch (nla_afnum) { 565 case AFNUM_INET: 566 if (opt_len != 4 + sizeof(struct in_addr)) { 567 ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len)); 568 return; 569 } 570 ND_TCHECK2(*bp, sizeof(struct in_addr)); 571 addrtostr(bp, nla_buf, sizeof(nla_buf)); 572 bp += sizeof(struct in_addr); 573 opts_len -= 4 + sizeof(struct in_addr); 574 break; 575 case AFNUM_INET6: 576 if (opt_len != 4 + sizeof(struct in6_addr)) { 577 ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len)); 578 return; 579 } 580 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 581 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 582 bp += sizeof(struct in6_addr); 583 opts_len -= 4 + sizeof(struct in6_addr); 584 break; 585 default: 586 goto trunc; 587 break; 588 } 589 590 ND_PRINT((ndo, " REDIRECT %s", nla_buf)); 591 break; 592 593 case PGM_OPT_PARITY_PRM: 594 if (opt_len != 8) { 595 ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len)); 596 return; 597 } 598 bp += 2; 599 len = EXTRACT_32BITS(bp); 600 bp += sizeof(uint32_t); 601 ND_PRINT((ndo, " PARITY MAXTGS %u", len)); 602 opts_len -= 8; 603 break; 604 605 case PGM_OPT_PARITY_GRP: 606 if (opt_len != 8) { 607 ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len)); 608 return; 609 } 610 bp += 2; 611 seq = EXTRACT_32BITS(bp); 612 bp += sizeof(uint32_t); 613 ND_PRINT((ndo, " PARITY GROUP %u", seq)); 614 opts_len -= 8; 615 break; 616 617 case PGM_OPT_CURR_TGSIZE: 618 if (opt_len != 8) { 619 ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len)); 620 return; 621 } 622 bp += 2; 623 len = EXTRACT_32BITS(bp); 624 bp += sizeof(uint32_t); 625 ND_PRINT((ndo, " PARITY ATGS %u", len)); 626 opts_len -= 8; 627 break; 628 629 case PGM_OPT_NBR_UNREACH: 630 if (opt_len != 4) { 631 ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len)); 632 return; 633 } 634 bp += 2; 635 ND_PRINT((ndo, " NBR_UNREACH")); 636 opts_len -= 4; 637 break; 638 639 case PGM_OPT_PATH_NLA: 640 ND_PRINT((ndo, " PATH_NLA [%d]", opt_len)); 641 bp += opt_len; 642 opts_len -= opt_len; 643 break; 644 645 case PGM_OPT_SYN: 646 if (opt_len != 4) { 647 ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != 4]", opt_len)); 648 return; 649 } 650 bp += 2; 651 ND_PRINT((ndo, " SYN")); 652 opts_len -= 4; 653 break; 654 655 case PGM_OPT_FIN: 656 if (opt_len != 4) { 657 ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != 4]", opt_len)); 658 return; 659 } 660 bp += 2; 661 ND_PRINT((ndo, " FIN")); 662 opts_len -= 4; 663 break; 664 665 case PGM_OPT_RST: 666 if (opt_len != 4) { 667 ND_PRINT((ndo, "[Bad OPT_RST option, length %u != 4]", opt_len)); 668 return; 669 } 670 bp += 2; 671 ND_PRINT((ndo, " RST")); 672 opts_len -= 4; 673 break; 674 675 case PGM_OPT_CR: 676 ND_PRINT((ndo, " CR")); 677 bp += opt_len; 678 opts_len -= opt_len; 679 break; 680 681 case PGM_OPT_CRQST: 682 if (opt_len != 4) { 683 ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != 4]", opt_len)); 684 return; 685 } 686 bp += 2; 687 ND_PRINT((ndo, " CRQST")); 688 opts_len -= 4; 689 break; 690 691 case PGM_OPT_PGMCC_DATA: 692 bp += 2; 693 offset = EXTRACT_32BITS(bp); 694 bp += sizeof(uint32_t); 695 nla_afnum = EXTRACT_16BITS(bp); 696 bp += (2 * sizeof(uint16_t)); 697 switch (nla_afnum) { 698 case AFNUM_INET: 699 if (opt_len != 12 + sizeof(struct in_addr)) { 700 ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); 701 return; 702 } 703 ND_TCHECK2(*bp, sizeof(struct in_addr)); 704 addrtostr(bp, nla_buf, sizeof(nla_buf)); 705 bp += sizeof(struct in_addr); 706 opts_len -= 12 + sizeof(struct in_addr); 707 break; 708 case AFNUM_INET6: 709 if (opt_len != 12 + sizeof(struct in6_addr)) { 710 ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); 711 return; 712 } 713 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 714 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 715 bp += sizeof(struct in6_addr); 716 opts_len -= 12 + sizeof(struct in6_addr); 717 break; 718 default: 719 goto trunc; 720 break; 721 } 722 723 ND_PRINT((ndo, " PGMCC DATA %u %s", offset, nla_buf)); 724 break; 725 726 case PGM_OPT_PGMCC_FEEDBACK: 727 bp += 2; 728 offset = EXTRACT_32BITS(bp); 729 bp += sizeof(uint32_t); 730 nla_afnum = EXTRACT_16BITS(bp); 731 bp += (2 * sizeof(uint16_t)); 732 switch (nla_afnum) { 733 case AFNUM_INET: 734 if (opt_len != 12 + sizeof(struct in_addr)) { 735 ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); 736 return; 737 } 738 ND_TCHECK2(*bp, sizeof(struct in_addr)); 739 addrtostr(bp, nla_buf, sizeof(nla_buf)); 740 bp += sizeof(struct in_addr); 741 opts_len -= 12 + sizeof(struct in_addr); 742 break; 743 case AFNUM_INET6: 744 if (opt_len != 12 + sizeof(struct in6_addr)) { 745 ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len)); 746 return; 747 } 748 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 749 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 750 bp += sizeof(struct in6_addr); 751 opts_len -= 12 + sizeof(struct in6_addr); 752 break; 753 default: 754 goto trunc; 755 break; 756 } 757 758 ND_PRINT((ndo, " PGMCC FEEDBACK %u %s", offset, nla_buf)); 759 break; 760 761 default: 762 ND_PRINT((ndo, " OPT_%02X [%d] ", opt_type, opt_len)); 763 bp += opt_len; 764 opts_len -= opt_len; 765 break; 766 } 767 768 if (opt_type & PGM_OPT_END) 769 break; 770 } 771 } 772 773 ND_PRINT((ndo, " [%u]", length)); 774 if (ndo->ndo_packettype == PT_PGM_ZMTP1 && 775 (pgm->pgm_type == PGM_ODATA || pgm->pgm_type == PGM_RDATA)) 776 zmtp1_print_datagram(ndo, bp, EXTRACT_16BITS(&pgm->pgm_length)); 777 778 return; 779 780 trunc: 781 ND_PRINT((ndo, "[|pgm]")); 782 if (ch != '\0') 783 ND_PRINT((ndo, ">")); 784 } 785