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 } else { 173 ND_PRINT((ndo, "%s > %s: [|pgm]", 174 ipaddr_string(ndo, &ip->ip_src), 175 ipaddr_string(ndo, &ip->ip_dst))); 176 } 177 return; 178 } 179 180 sport = EXTRACT_16BITS(&pgm->pgm_sport); 181 dport = EXTRACT_16BITS(&pgm->pgm_dport); 182 183 if (ip6) { 184 if (ip6->ip6_nxt == IPPROTO_PGM) { 185 ND_PRINT((ndo, "%s.%s > %s.%s: ", 186 ip6addr_string(ndo, &ip6->ip6_src), 187 tcpport_string(ndo, sport), 188 ip6addr_string(ndo, &ip6->ip6_dst), 189 tcpport_string(ndo, dport))); 190 } else { 191 ND_PRINT((ndo, "%s > %s: ", 192 tcpport_string(ndo, sport), tcpport_string(ndo, dport))); 193 } 194 } else { 195 if (ip->ip_p == IPPROTO_PGM) { 196 ND_PRINT((ndo, "%s.%s > %s.%s: ", 197 ipaddr_string(ndo, &ip->ip_src), 198 tcpport_string(ndo, sport), 199 ipaddr_string(ndo, &ip->ip_dst), 200 tcpport_string(ndo, dport))); 201 } else { 202 ND_PRINT((ndo, "%s > %s: ", 203 tcpport_string(ndo, sport), tcpport_string(ndo, dport))); 204 } 205 } 206 207 ND_TCHECK(*pgm); 208 209 ND_PRINT((ndo, "PGM, length %u", EXTRACT_16BITS(&pgm->pgm_length))); 210 211 if (!ndo->ndo_vflag) 212 return; 213 214 ND_PRINT((ndo, " 0x%02x%02x%02x%02x%02x%02x ", 215 pgm->pgm_gsid[0], 216 pgm->pgm_gsid[1], 217 pgm->pgm_gsid[2], 218 pgm->pgm_gsid[3], 219 pgm->pgm_gsid[4], 220 pgm->pgm_gsid[5])); 221 switch (pgm->pgm_type) { 222 case PGM_SPM: { 223 const struct pgm_spm *spm; 224 225 spm = (const struct pgm_spm *)(pgm + 1); 226 ND_TCHECK(*spm); 227 bp = (const u_char *) (spm + 1); 228 229 switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) { 230 case AFNUM_INET: 231 ND_TCHECK2(*bp, sizeof(struct in_addr)); 232 addrtostr(bp, nla_buf, sizeof(nla_buf)); 233 bp += sizeof(struct in_addr); 234 break; 235 case AFNUM_INET6: 236 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 237 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 238 bp += sizeof(struct in6_addr); 239 break; 240 default: 241 goto trunc; 242 break; 243 } 244 245 ND_PRINT((ndo, "SPM seq %u trail %u lead %u nla %s", 246 EXTRACT_32BITS(&spm->pgms_seq), 247 EXTRACT_32BITS(&spm->pgms_trailseq), 248 EXTRACT_32BITS(&spm->pgms_leadseq), 249 nla_buf)); 250 break; 251 } 252 253 case PGM_POLL: { 254 const struct pgm_poll *poll_msg; 255 256 poll_msg = (const struct pgm_poll *)(pgm + 1); 257 ND_TCHECK(*poll_msg); 258 ND_PRINT((ndo, "POLL seq %u round %u", 259 EXTRACT_32BITS(&poll_msg->pgmp_seq), 260 EXTRACT_16BITS(&poll_msg->pgmp_round))); 261 bp = (const u_char *) (poll_msg + 1); 262 break; 263 } 264 case PGM_POLR: { 265 const struct pgm_polr *polr; 266 uint32_t ivl, rnd, mask; 267 268 polr = (const struct pgm_polr *)(pgm + 1); 269 ND_TCHECK(*polr); 270 bp = (const u_char *) (polr + 1); 271 272 switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) { 273 case AFNUM_INET: 274 ND_TCHECK2(*bp, sizeof(struct in_addr)); 275 addrtostr(bp, nla_buf, sizeof(nla_buf)); 276 bp += sizeof(struct in_addr); 277 break; 278 case AFNUM_INET6: 279 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 280 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 281 bp += sizeof(struct in6_addr); 282 break; 283 default: 284 goto trunc; 285 break; 286 } 287 288 ND_TCHECK2(*bp, sizeof(uint32_t)); 289 ivl = EXTRACT_32BITS(bp); 290 bp += sizeof(uint32_t); 291 292 ND_TCHECK2(*bp, sizeof(uint32_t)); 293 rnd = EXTRACT_32BITS(bp); 294 bp += sizeof(uint32_t); 295 296 ND_TCHECK2(*bp, sizeof(uint32_t)); 297 mask = EXTRACT_32BITS(bp); 298 bp += sizeof(uint32_t); 299 300 ND_PRINT((ndo, "POLR seq %u round %u nla %s ivl %u rnd 0x%08x " 301 "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq), 302 EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask)); 303 break; 304 } 305 case PGM_ODATA: { 306 const struct pgm_data *odata; 307 308 odata = (const struct pgm_data *)(pgm + 1); 309 ND_TCHECK(*odata); 310 ND_PRINT((ndo, "ODATA trail %u seq %u", 311 EXTRACT_32BITS(&odata->pgmd_trailseq), 312 EXTRACT_32BITS(&odata->pgmd_seq))); 313 bp = (const u_char *) (odata + 1); 314 break; 315 } 316 317 case PGM_RDATA: { 318 const struct pgm_data *rdata; 319 320 rdata = (const struct pgm_data *)(pgm + 1); 321 ND_TCHECK(*rdata); 322 ND_PRINT((ndo, "RDATA trail %u seq %u", 323 EXTRACT_32BITS(&rdata->pgmd_trailseq), 324 EXTRACT_32BITS(&rdata->pgmd_seq))); 325 bp = (const u_char *) (rdata + 1); 326 break; 327 } 328 329 case PGM_NAK: 330 case PGM_NULLNAK: 331 case PGM_NCF: { 332 const struct pgm_nak *nak; 333 char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN]; 334 335 nak = (const struct pgm_nak *)(pgm + 1); 336 ND_TCHECK(*nak); 337 bp = (const u_char *) (nak + 1); 338 339 /* 340 * Skip past the source, saving info along the way 341 * and stopping if we don't have enough. 342 */ 343 switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) { 344 case AFNUM_INET: 345 ND_TCHECK2(*bp, sizeof(struct in_addr)); 346 addrtostr(bp, source_buf, sizeof(source_buf)); 347 bp += sizeof(struct in_addr); 348 break; 349 case AFNUM_INET6: 350 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 351 addrtostr6(bp, source_buf, sizeof(source_buf)); 352 bp += sizeof(struct in6_addr); 353 break; 354 default: 355 goto trunc; 356 break; 357 } 358 359 /* 360 * Skip past the group, saving info along the way 361 * and stopping if we don't have enough. 362 */ 363 bp += (2 * sizeof(uint16_t)); 364 ND_TCHECK_16BITS(bp); 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 if (!ND_TTEST2(*bp, 2)) { 461 ND_PRINT((ndo, " [|OPT]")); 462 return; 463 } 464 opt_type = *bp++; 465 opt_len = *bp++; 466 if (opt_len < PGM_MIN_OPT_LEN) { 467 ND_PRINT((ndo, "[Bad option, length %u < %u]", opt_len, 468 PGM_MIN_OPT_LEN)); 469 break; 470 } 471 if (opts_len < opt_len) { 472 ND_PRINT((ndo, "[Total option length leaves no room for final option]")); 473 return; 474 } 475 if (!ND_TTEST2(*bp, opt_len - 2)) { 476 ND_PRINT((ndo, " [|OPT]")); 477 return; 478 } 479 480 switch (opt_type & PGM_OPT_MASK) { 481 case PGM_OPT_LENGTH: 482 #define PGM_OPT_LENGTH_LEN (2+2) 483 if (opt_len != PGM_OPT_LENGTH_LEN) { 484 ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != %u]", 485 opt_len, PGM_OPT_LENGTH_LEN)); 486 return; 487 } 488 ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp))); 489 bp += 2; 490 opts_len -= PGM_OPT_LENGTH_LEN; 491 break; 492 493 case PGM_OPT_FRAGMENT: 494 #define PGM_OPT_FRAGMENT_LEN (2+2+4+4+4) 495 if (opt_len != PGM_OPT_FRAGMENT_LEN) { 496 ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != %u]", 497 opt_len, PGM_OPT_FRAGMENT_LEN)); 498 return; 499 } 500 bp += 2; 501 seq = EXTRACT_32BITS(bp); 502 bp += 4; 503 offset = EXTRACT_32BITS(bp); 504 bp += 4; 505 len = EXTRACT_32BITS(bp); 506 bp += 4; 507 ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len)); 508 opts_len -= PGM_OPT_FRAGMENT_LEN; 509 break; 510 511 case PGM_OPT_NAK_LIST: 512 bp += 2; 513 opt_len -= 4; /* option header */ 514 ND_PRINT((ndo, " NAK LIST")); 515 while (opt_len) { 516 if (opt_len < 4) { 517 ND_PRINT((ndo, "[Option length not a multiple of 4]")); 518 return; 519 } 520 ND_TCHECK2(*bp, 4); 521 ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp))); 522 bp += 4; 523 opt_len -= 4; 524 opts_len -= 4; 525 } 526 break; 527 528 case PGM_OPT_JOIN: 529 #define PGM_OPT_JOIN_LEN (2+2+4) 530 if (opt_len != PGM_OPT_JOIN_LEN) { 531 ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != %u]", 532 opt_len, PGM_OPT_JOIN_LEN)); 533 return; 534 } 535 bp += 2; 536 seq = EXTRACT_32BITS(bp); 537 bp += 4; 538 ND_PRINT((ndo, " JOIN %u", seq)); 539 opts_len -= PGM_OPT_JOIN_LEN; 540 break; 541 542 case PGM_OPT_NAK_BO_IVL: 543 #define PGM_OPT_NAK_BO_IVL_LEN (2+2+4+4) 544 if (opt_len != PGM_OPT_NAK_BO_IVL_LEN) { 545 ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != %u]", 546 opt_len, PGM_OPT_NAK_BO_IVL_LEN)); 547 return; 548 } 549 bp += 2; 550 offset = EXTRACT_32BITS(bp); 551 bp += 4; 552 seq = EXTRACT_32BITS(bp); 553 bp += 4; 554 ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq)); 555 opts_len -= PGM_OPT_NAK_BO_IVL_LEN; 556 break; 557 558 case PGM_OPT_NAK_BO_RNG: 559 #define PGM_OPT_NAK_BO_RNG_LEN (2+2+4+4) 560 if (opt_len != PGM_OPT_NAK_BO_RNG_LEN) { 561 ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != %u]", 562 opt_len, PGM_OPT_NAK_BO_RNG_LEN)); 563 return; 564 } 565 bp += 2; 566 offset = EXTRACT_32BITS(bp); 567 bp += 4; 568 seq = EXTRACT_32BITS(bp); 569 bp += 4; 570 ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq)); 571 opts_len -= PGM_OPT_NAK_BO_RNG_LEN; 572 break; 573 574 case PGM_OPT_REDIRECT: 575 #define PGM_OPT_REDIRECT_FIXED_LEN (2+2+2+2) 576 if (opt_len < PGM_OPT_REDIRECT_FIXED_LEN) { 577 ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u < %u]", 578 opt_len, PGM_OPT_REDIRECT_FIXED_LEN)); 579 return; 580 } 581 bp += 2; 582 nla_afnum = EXTRACT_16BITS(bp); 583 bp += 2+2; 584 switch (nla_afnum) { 585 case AFNUM_INET: 586 if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr)) { 587 ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]", 588 opt_len, PGM_OPT_REDIRECT_FIXED_LEN)); 589 return; 590 } 591 ND_TCHECK2(*bp, sizeof(struct in_addr)); 592 addrtostr(bp, nla_buf, sizeof(nla_buf)); 593 bp += sizeof(struct in_addr); 594 opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr); 595 break; 596 case AFNUM_INET6: 597 if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr)) { 598 ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]", 599 PGM_OPT_REDIRECT_FIXED_LEN, opt_len)); 600 return; 601 } 602 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 603 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 604 bp += sizeof(struct in6_addr); 605 opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr); 606 break; 607 default: 608 goto trunc; 609 break; 610 } 611 612 ND_PRINT((ndo, " REDIRECT %s", nla_buf)); 613 break; 614 615 case PGM_OPT_PARITY_PRM: 616 #define PGM_OPT_PARITY_PRM_LEN (2+2+4) 617 if (opt_len != PGM_OPT_PARITY_PRM_LEN) { 618 ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != %u]", 619 opt_len, PGM_OPT_PARITY_PRM_LEN)); 620 return; 621 } 622 bp += 2; 623 len = EXTRACT_32BITS(bp); 624 bp += 4; 625 ND_PRINT((ndo, " PARITY MAXTGS %u", len)); 626 opts_len -= PGM_OPT_PARITY_PRM_LEN; 627 break; 628 629 case PGM_OPT_PARITY_GRP: 630 #define PGM_OPT_PARITY_GRP_LEN (2+2+4) 631 if (opt_len != PGM_OPT_PARITY_GRP_LEN) { 632 ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != %u]", 633 opt_len, PGM_OPT_PARITY_GRP_LEN)); 634 return; 635 } 636 bp += 2; 637 seq = EXTRACT_32BITS(bp); 638 bp += 4; 639 ND_PRINT((ndo, " PARITY GROUP %u", seq)); 640 opts_len -= PGM_OPT_PARITY_GRP_LEN; 641 break; 642 643 case PGM_OPT_CURR_TGSIZE: 644 #define PGM_OPT_CURR_TGSIZE_LEN (2+2+4) 645 if (opt_len != PGM_OPT_CURR_TGSIZE_LEN) { 646 ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != %u]", 647 opt_len, PGM_OPT_CURR_TGSIZE_LEN)); 648 return; 649 } 650 bp += 2; 651 len = EXTRACT_32BITS(bp); 652 bp += 4; 653 ND_PRINT((ndo, " PARITY ATGS %u", len)); 654 opts_len -= PGM_OPT_CURR_TGSIZE_LEN; 655 break; 656 657 case PGM_OPT_NBR_UNREACH: 658 #define PGM_OPT_NBR_UNREACH_LEN (2+2) 659 if (opt_len != PGM_OPT_NBR_UNREACH_LEN) { 660 ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != %u]", 661 opt_len, PGM_OPT_NBR_UNREACH_LEN)); 662 return; 663 } 664 bp += 2; 665 ND_PRINT((ndo, " NBR_UNREACH")); 666 opts_len -= PGM_OPT_NBR_UNREACH_LEN; 667 break; 668 669 case PGM_OPT_PATH_NLA: 670 ND_PRINT((ndo, " PATH_NLA [%d]", opt_len)); 671 bp += opt_len; 672 opts_len -= opt_len; 673 break; 674 675 case PGM_OPT_SYN: 676 #define PGM_OPT_SYN_LEN (2+2) 677 if (opt_len != PGM_OPT_SYN_LEN) { 678 ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != %u]", 679 opt_len, PGM_OPT_SYN_LEN)); 680 return; 681 } 682 bp += 2; 683 ND_PRINT((ndo, " SYN")); 684 opts_len -= PGM_OPT_SYN_LEN; 685 break; 686 687 case PGM_OPT_FIN: 688 #define PGM_OPT_FIN_LEN (2+2) 689 if (opt_len != PGM_OPT_FIN_LEN) { 690 ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != %u]", 691 opt_len, PGM_OPT_FIN_LEN)); 692 return; 693 } 694 bp += 2; 695 ND_PRINT((ndo, " FIN")); 696 opts_len -= PGM_OPT_FIN_LEN; 697 break; 698 699 case PGM_OPT_RST: 700 #define PGM_OPT_RST_LEN (2+2) 701 if (opt_len != PGM_OPT_RST_LEN) { 702 ND_PRINT((ndo, "[Bad OPT_RST option, length %u != %u]", 703 opt_len, PGM_OPT_RST_LEN)); 704 return; 705 } 706 bp += 2; 707 ND_PRINT((ndo, " RST")); 708 opts_len -= PGM_OPT_RST_LEN; 709 break; 710 711 case PGM_OPT_CR: 712 ND_PRINT((ndo, " CR")); 713 bp += opt_len; 714 opts_len -= opt_len; 715 break; 716 717 case PGM_OPT_CRQST: 718 #define PGM_OPT_CRQST_LEN (2+2) 719 if (opt_len != PGM_OPT_CRQST_LEN) { 720 ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != %u]", 721 opt_len, PGM_OPT_CRQST_LEN)); 722 return; 723 } 724 bp += 2; 725 ND_PRINT((ndo, " CRQST")); 726 opts_len -= PGM_OPT_CRQST_LEN; 727 break; 728 729 case PGM_OPT_PGMCC_DATA: 730 #define PGM_OPT_PGMCC_DATA_FIXED_LEN (2+2+4+2+2) 731 if (opt_len < PGM_OPT_PGMCC_DATA_FIXED_LEN) { 732 ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u < %u]", 733 opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); 734 return; 735 } 736 bp += 2; 737 offset = EXTRACT_32BITS(bp); 738 bp += 4; 739 nla_afnum = EXTRACT_16BITS(bp); 740 bp += 2+2; 741 switch (nla_afnum) { 742 case AFNUM_INET: 743 if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr)) { 744 ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]", 745 opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); 746 return; 747 } 748 ND_TCHECK2(*bp, sizeof(struct in_addr)); 749 addrtostr(bp, nla_buf, sizeof(nla_buf)); 750 bp += sizeof(struct in_addr); 751 opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr); 752 break; 753 case AFNUM_INET6: 754 if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr)) { 755 ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]", 756 opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN)); 757 return; 758 } 759 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 760 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 761 bp += sizeof(struct in6_addr); 762 opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr); 763 break; 764 default: 765 goto trunc; 766 break; 767 } 768 769 ND_PRINT((ndo, " PGMCC DATA %u %s", offset, nla_buf)); 770 break; 771 772 case PGM_OPT_PGMCC_FEEDBACK: 773 #define PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN (2+2+4+2+2) 774 if (opt_len < PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN) { 775 ND_PRINT((ndo, "[Bad PGM_OPT_PGMCC_FEEDBACK option, length %u < %u]", 776 opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); 777 return; 778 } 779 bp += 2; 780 offset = EXTRACT_32BITS(bp); 781 bp += 4; 782 nla_afnum = EXTRACT_16BITS(bp); 783 bp += 2+2; 784 switch (nla_afnum) { 785 case AFNUM_INET: 786 if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr)) { 787 ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]", 788 opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); 789 return; 790 } 791 ND_TCHECK2(*bp, sizeof(struct in_addr)); 792 addrtostr(bp, nla_buf, sizeof(nla_buf)); 793 bp += sizeof(struct in_addr); 794 opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr); 795 break; 796 case AFNUM_INET6: 797 if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr)) { 798 ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]", 799 opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN)); 800 return; 801 } 802 ND_TCHECK2(*bp, sizeof(struct in6_addr)); 803 addrtostr6(bp, nla_buf, sizeof(nla_buf)); 804 bp += sizeof(struct in6_addr); 805 opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr); 806 break; 807 default: 808 goto trunc; 809 break; 810 } 811 812 ND_PRINT((ndo, " PGMCC FEEDBACK %u %s", offset, nla_buf)); 813 break; 814 815 default: 816 ND_PRINT((ndo, " OPT_%02X [%d] ", opt_type, opt_len)); 817 bp += opt_len; 818 opts_len -= opt_len; 819 break; 820 } 821 822 if (opt_type & PGM_OPT_END) 823 break; 824 } 825 } 826 827 ND_PRINT((ndo, " [%u]", length)); 828 if (ndo->ndo_packettype == PT_PGM_ZMTP1 && 829 (pgm->pgm_type == PGM_ODATA || pgm->pgm_type == PGM_RDATA)) 830 zmtp1_print_datagram(ndo, bp, EXTRACT_16BITS(&pgm->pgm_length)); 831 832 return; 833 834 trunc: 835 ND_PRINT((ndo, "[|pgm]")); 836 if (ch != '\0') 837 ND_PRINT((ndo, ">")); 838 } 839