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 #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