xref: /freebsd/contrib/tcpdump/print-pgm.c (revision 2d23488dac42e567e6d4de9ef1b0211c62f7e3e9)
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