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