Home | History | Annotate | Download | only in tcpdump
      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 (at) 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