print-pgm.c revision 1.8
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#include <sys/cdefs.h>
17#ifndef lint
18__RCSID("$NetBSD: print-pgm.c,v 1.8 2017/02/05 04:05:05 spz Exp $");
19#endif
20
21/* \summary: Pragmatic General Multicast (PGM) printer */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include <netdissect-stdinc.h>
28
29#include "netdissect.h"
30#include "extract.h"
31#include "addrtoname.h"
32#include "addrtostr.h"
33
34#include "ip.h"
35#include "ip6.h"
36#include "ipproto.h"
37#include "af.h"
38
39/*
40 * PGM header (RFC 3208)
41 */
42struct pgm_header {
43    uint16_t	pgm_sport;
44    uint16_t	pgm_dport;
45    uint8_t	pgm_type;
46    uint8_t	pgm_options;
47    uint16_t	pgm_sum;
48    uint8_t	pgm_gsid[6];
49    uint16_t	pgm_length;
50};
51
52struct pgm_spm {
53    uint32_t	pgms_seq;
54    uint32_t	pgms_trailseq;
55    uint32_t	pgms_leadseq;
56    uint16_t	pgms_nla_afi;
57    uint16_t	pgms_reserved;
58    /* ... uint8_t	pgms_nla[0]; */
59    /* ... options */
60};
61
62struct pgm_nak {
63    uint32_t	pgmn_seq;
64    uint16_t	pgmn_source_afi;
65    uint16_t	pgmn_reserved;
66    /* ... uint8_t	pgmn_source[0]; */
67    /* ... uint16_t	pgmn_group_afi */
68    /* ... uint16_t	pgmn_reserved2; */
69    /* ... uint8_t	pgmn_group[0]; */
70    /* ... options */
71};
72
73struct pgm_ack {
74    uint32_t	pgma_rx_max_seq;
75    uint32_t	pgma_bitmap;
76    /* ... options */
77};
78
79struct pgm_poll {
80    uint32_t	pgmp_seq;
81    uint16_t	pgmp_round;
82    uint16_t	pgmp_reserved;
83    /* ... options */
84};
85
86struct pgm_polr {
87    uint32_t	pgmp_seq;
88    uint16_t	pgmp_round;
89    uint16_t	pgmp_subtype;
90    uint16_t	pgmp_nla_afi;
91    uint16_t	pgmp_reserved;
92    /* ... uint8_t	pgmp_nla[0]; */
93    /* ... options */
94};
95
96struct pgm_data {
97    uint32_t	pgmd_seq;
98    uint32_t	pgmd_trailseq;
99    /* ... options */
100};
101
102typedef enum _pgm_type {
103    PGM_SPM = 0,		/* source path message */
104    PGM_POLL = 1,		/* POLL Request */
105    PGM_POLR = 2,		/* POLL Response */
106    PGM_ODATA = 4,		/* original data */
107    PGM_RDATA = 5,		/* repair data */
108    PGM_NAK = 8,		/* NAK */
109    PGM_NULLNAK = 9,		/* Null NAK */
110    PGM_NCF = 10,		/* NAK Confirmation */
111    PGM_ACK = 11,		/* ACK for congestion control */
112    PGM_SPMR = 12,		/* SPM request */
113    PGM_MAX = 255
114} pgm_type;
115
116#define PGM_OPT_BIT_PRESENT	0x01
117#define PGM_OPT_BIT_NETWORK	0x02
118#define PGM_OPT_BIT_VAR_PKTLEN	0x40
119#define PGM_OPT_BIT_PARITY	0x80
120
121#define PGM_OPT_LENGTH		0x00
122#define PGM_OPT_FRAGMENT        0x01
123#define PGM_OPT_NAK_LIST        0x02
124#define PGM_OPT_JOIN            0x03
125#define PGM_OPT_NAK_BO_IVL	0x04
126#define PGM_OPT_NAK_BO_RNG	0x05
127
128#define PGM_OPT_REDIRECT        0x07
129#define PGM_OPT_PARITY_PRM      0x08
130#define PGM_OPT_PARITY_GRP      0x09
131#define PGM_OPT_CURR_TGSIZE     0x0A
132#define PGM_OPT_NBR_UNREACH	0x0B
133#define PGM_OPT_PATH_NLA	0x0C
134
135#define PGM_OPT_SYN             0x0D
136#define PGM_OPT_FIN             0x0E
137#define PGM_OPT_RST             0x0F
138#define PGM_OPT_CR		0x10
139#define PGM_OPT_CRQST		0x11
140
141#define PGM_OPT_PGMCC_DATA	0x12
142#define PGM_OPT_PGMCC_FEEDBACK	0x13
143
144#define PGM_OPT_MASK		0x7f
145
146#define PGM_OPT_END		0x80    /* end of options marker */
147
148#define PGM_MIN_OPT_LEN		4
149
150void
151pgm_print(netdissect_options *ndo,
152          register const u_char *bp, register u_int length,
153          register const u_char *bp2)
154{
155	register const struct pgm_header *pgm;
156	register const struct ip *ip;
157	register char ch;
158	uint16_t sport, dport;
159	u_int nla_afnum;
160	char nla_buf[INET6_ADDRSTRLEN];
161	register const struct ip6_hdr *ip6;
162	uint8_t opt_type, opt_len;
163	uint32_t seq, opts_len, len, offset;
164
165	pgm = (const struct pgm_header *)bp;
166	ip = (const struct ip *)bp2;
167	if (IP_V(ip) == 6)
168		ip6 = (const struct ip6_hdr *)bp2;
169	else
170		ip6 = NULL;
171	ch = '\0';
172	if (!ND_TTEST(pgm->pgm_dport)) {
173		if (ip6) {
174			ND_PRINT((ndo, "%s > %s: [|pgm]",
175				ip6addr_string(ndo, &ip6->ip6_src),
176				ip6addr_string(ndo, &ip6->ip6_dst)));
177			return;
178		} else {
179			ND_PRINT((ndo, "%s > %s: [|pgm]",
180				ipaddr_string(ndo, &ip->ip_src),
181				ipaddr_string(ndo, &ip->ip_dst)));
182			return;
183		}
184	}
185
186	sport = EXTRACT_16BITS(&pgm->pgm_sport);
187	dport = EXTRACT_16BITS(&pgm->pgm_dport);
188
189	if (ip6) {
190		if (ip6->ip6_nxt == IPPROTO_PGM) {
191			ND_PRINT((ndo, "%s.%s > %s.%s: ",
192				ip6addr_string(ndo, &ip6->ip6_src),
193				tcpport_string(ndo, sport),
194				ip6addr_string(ndo, &ip6->ip6_dst),
195				tcpport_string(ndo, dport)));
196		} else {
197			ND_PRINT((ndo, "%s > %s: ",
198				tcpport_string(ndo, sport), tcpport_string(ndo, dport)));
199		}
200	} else {
201		if (ip->ip_p == IPPROTO_PGM) {
202			ND_PRINT((ndo, "%s.%s > %s.%s: ",
203				ipaddr_string(ndo, &ip->ip_src),
204				tcpport_string(ndo, sport),
205				ipaddr_string(ndo, &ip->ip_dst),
206				tcpport_string(ndo, dport)));
207		} else {
208			ND_PRINT((ndo, "%s > %s: ",
209				tcpport_string(ndo, sport), tcpport_string(ndo, dport)));
210		}
211	}
212
213	ND_TCHECK(*pgm);
214
215        ND_PRINT((ndo, "PGM, length %u", EXTRACT_16BITS(&pgm->pgm_length)));
216
217        if (!ndo->ndo_vflag)
218            return;
219
220	ND_PRINT((ndo, " 0x%02x%02x%02x%02x%02x%02x ",
221		     pgm->pgm_gsid[0],
222                     pgm->pgm_gsid[1],
223                     pgm->pgm_gsid[2],
224		     pgm->pgm_gsid[3],
225                     pgm->pgm_gsid[4],
226                     pgm->pgm_gsid[5]));
227	switch (pgm->pgm_type) {
228	case PGM_SPM: {
229	    const struct pgm_spm *spm;
230
231	    spm = (const struct pgm_spm *)(pgm + 1);
232	    ND_TCHECK(*spm);
233	    bp = (const u_char *) (spm + 1);
234
235	    switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) {
236	    case AFNUM_INET:
237		ND_TCHECK2(*bp, sizeof(struct in_addr));
238		addrtostr(bp, nla_buf, sizeof(nla_buf));
239		bp += sizeof(struct in_addr);
240		break;
241	    case AFNUM_INET6:
242		ND_TCHECK2(*bp, sizeof(struct in6_addr));
243		addrtostr6(bp, nla_buf, sizeof(nla_buf));
244		bp += sizeof(struct in6_addr);
245		break;
246	    default:
247		goto trunc;
248		break;
249	    }
250
251	    ND_PRINT((ndo, "SPM seq %u trail %u lead %u nla %s",
252			 EXTRACT_32BITS(&spm->pgms_seq),
253                         EXTRACT_32BITS(&spm->pgms_trailseq),
254			 EXTRACT_32BITS(&spm->pgms_leadseq),
255                         nla_buf));
256	    break;
257	}
258
259	case PGM_POLL: {
260	    const struct pgm_poll *poll_msg;
261
262	    poll_msg = (const struct pgm_poll *)(pgm + 1);
263	    ND_TCHECK(*poll_msg);
264	    ND_PRINT((ndo, "POLL seq %u round %u",
265			 EXTRACT_32BITS(&poll_msg->pgmp_seq),
266                         EXTRACT_16BITS(&poll_msg->pgmp_round)));
267	    bp = (const u_char *) (poll_msg + 1);
268	    break;
269	}
270	case PGM_POLR: {
271	    const struct pgm_polr *polr;
272	    uint32_t ivl, rnd, mask;
273
274	    polr = (const struct pgm_polr *)(pgm + 1);
275	    ND_TCHECK(*polr);
276	    bp = (const u_char *) (polr + 1);
277
278	    switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) {
279	    case AFNUM_INET:
280		ND_TCHECK2(*bp, sizeof(struct in_addr));
281		addrtostr(bp, nla_buf, sizeof(nla_buf));
282		bp += sizeof(struct in_addr);
283		break;
284	    case AFNUM_INET6:
285		ND_TCHECK2(*bp, sizeof(struct in6_addr));
286		addrtostr6(bp, nla_buf, sizeof(nla_buf));
287		bp += sizeof(struct in6_addr);
288		break;
289	    default:
290		goto trunc;
291		break;
292	    }
293
294	    ND_TCHECK2(*bp, sizeof(uint32_t));
295	    ivl = EXTRACT_32BITS(bp);
296	    bp += sizeof(uint32_t);
297
298	    ND_TCHECK2(*bp, sizeof(uint32_t));
299	    rnd = EXTRACT_32BITS(bp);
300	    bp += sizeof(uint32_t);
301
302	    ND_TCHECK2(*bp, sizeof(uint32_t));
303	    mask = EXTRACT_32BITS(bp);
304	    bp += sizeof(uint32_t);
305
306	    ND_PRINT((ndo, "POLR seq %u round %u nla %s ivl %u rnd 0x%08x "
307			 "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq),
308			 EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask));
309	    break;
310	}
311	case PGM_ODATA: {
312	    const struct pgm_data *odata;
313
314	    odata = (const struct pgm_data *)(pgm + 1);
315	    ND_TCHECK(*odata);
316	    ND_PRINT((ndo, "ODATA trail %u seq %u",
317			 EXTRACT_32BITS(&odata->pgmd_trailseq),
318			 EXTRACT_32BITS(&odata->pgmd_seq)));
319	    bp = (const u_char *) (odata + 1);
320	    break;
321	}
322
323	case PGM_RDATA: {
324	    const struct pgm_data *rdata;
325
326	    rdata = (const struct pgm_data *)(pgm + 1);
327	    ND_TCHECK(*rdata);
328	    ND_PRINT((ndo, "RDATA trail %u seq %u",
329			 EXTRACT_32BITS(&rdata->pgmd_trailseq),
330			 EXTRACT_32BITS(&rdata->pgmd_seq)));
331	    bp = (const u_char *) (rdata + 1);
332	    break;
333	}
334
335	case PGM_NAK:
336	case PGM_NULLNAK:
337	case PGM_NCF: {
338	    const struct pgm_nak *nak;
339	    char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN];
340
341	    nak = (const struct pgm_nak *)(pgm + 1);
342	    ND_TCHECK(*nak);
343	    bp = (const u_char *) (nak + 1);
344
345	    /*
346	     * Skip past the source, saving info along the way
347	     * and stopping if we don't have enough.
348	     */
349	    switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) {
350	    case AFNUM_INET:
351		ND_TCHECK2(*bp, sizeof(struct in_addr));
352		addrtostr(bp, source_buf, sizeof(source_buf));
353		bp += sizeof(struct in_addr);
354		break;
355	    case AFNUM_INET6:
356		ND_TCHECK2(*bp, sizeof(struct in6_addr));
357		addrtostr6(bp, source_buf, sizeof(source_buf));
358		bp += sizeof(struct in6_addr);
359		break;
360	    default:
361		goto trunc;
362		break;
363	    }
364
365	    /*
366	     * Skip past the group, saving info along the way
367	     * and stopping if we don't have enough.
368	     */
369	    bp += (2 * sizeof(uint16_t));
370	    switch (EXTRACT_16BITS(bp)) {
371	    case AFNUM_INET:
372		ND_TCHECK2(*bp, sizeof(struct in_addr));
373		addrtostr(bp, group_buf, sizeof(group_buf));
374		bp += sizeof(struct in_addr);
375		break;
376	    case AFNUM_INET6:
377		ND_TCHECK2(*bp, sizeof(struct in6_addr));
378		addrtostr6(bp, group_buf, sizeof(group_buf));
379		bp += sizeof(struct in6_addr);
380		break;
381	    default:
382		goto trunc;
383		break;
384	    }
385
386	    /*
387	     * Options decoding can go here.
388	     */
389	    switch (pgm->pgm_type) {
390		case PGM_NAK:
391		    ND_PRINT((ndo, "NAK "));
392		    break;
393		case PGM_NULLNAK:
394		    ND_PRINT((ndo, "NNAK "));
395		    break;
396		case PGM_NCF:
397		    ND_PRINT((ndo, "NCF "));
398		    break;
399		default:
400                    break;
401	    }
402	    ND_PRINT((ndo, "(%s -> %s), seq %u",
403			 source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq)));
404	    break;
405	}
406
407	case PGM_ACK: {
408	    const struct pgm_ack *ack;
409
410	    ack = (const struct pgm_ack *)(pgm + 1);
411	    ND_TCHECK(*ack);
412	    ND_PRINT((ndo, "ACK seq %u",
413			 EXTRACT_32BITS(&ack->pgma_rx_max_seq)));
414	    bp = (const u_char *) (ack + 1);
415	    break;
416	}
417
418	case PGM_SPMR:
419	    ND_PRINT((ndo, "SPMR"));
420	    break;
421
422	default:
423	    ND_PRINT((ndo, "UNKNOWN type 0x%02x", pgm->pgm_type));
424	    break;
425
426	}
427	if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) {
428
429	    /*
430	     * make sure there's enough for the first option header
431	     */
432	    if (!ND_TTEST2(*bp, PGM_MIN_OPT_LEN)) {
433		ND_PRINT((ndo, "[|OPT]"));
434		return;
435	    }
436
437	    /*
438	     * That option header MUST be an OPT_LENGTH option
439	     * (see the first paragraph of section 9.1 in RFC 3208).
440	     */
441	    opt_type = *bp++;
442	    if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) {
443		ND_PRINT((ndo, "[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK));
444		return;
445	    }
446	    opt_len = *bp++;
447	    if (opt_len != 4) {
448		ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len));
449		return;
450	    }
451	    opts_len = EXTRACT_16BITS(bp);
452	    if (opts_len < 4) {
453		ND_PRINT((ndo, "[Bad total option length %u < 4]", opts_len));
454		return;
455	    }
456	    bp += sizeof(uint16_t);
457	    ND_PRINT((ndo, " OPTS LEN %d", opts_len));
458	    opts_len -= 4;
459
460	    while (opts_len) {
461		if (opts_len < PGM_MIN_OPT_LEN) {
462		    ND_PRINT((ndo, "[Total option length leaves no room for final option]"));
463		    return;
464		}
465		opt_type = *bp++;
466		opt_len = *bp++;
467		if (opt_len < PGM_MIN_OPT_LEN) {
468		    ND_PRINT((ndo, "[Bad option, length %u < %u]", opt_len,
469		        PGM_MIN_OPT_LEN));
470		    break;
471		}
472		if (opts_len < opt_len) {
473		    ND_PRINT((ndo, "[Total option length leaves no room for final option]"));
474		    return;
475		}
476		if (!ND_TTEST2(*bp, opt_len - 2)) {
477		    ND_PRINT((ndo, " [|OPT]"));
478		    return;
479		}
480
481		switch (opt_type & PGM_OPT_MASK) {
482		case PGM_OPT_LENGTH:
483		    if (opt_len != 4) {
484			ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len));
485			return;
486		    }
487		    ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp)));
488		    bp += sizeof(uint16_t);
489		    opts_len -= 4;
490		    break;
491
492		case PGM_OPT_FRAGMENT:
493		    if (opt_len != 16) {
494			ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != 16]", opt_len));
495			return;
496		    }
497		    bp += 2;
498		    seq = EXTRACT_32BITS(bp);
499		    bp += sizeof(uint32_t);
500		    offset = EXTRACT_32BITS(bp);
501		    bp += sizeof(uint32_t);
502		    len = EXTRACT_32BITS(bp);
503		    bp += sizeof(uint32_t);
504		    ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len));
505		    opts_len -= 16;
506		    break;
507
508		case PGM_OPT_NAK_LIST:
509		    bp += 2;
510		    opt_len -= sizeof(uint32_t);	/* option header */
511		    ND_PRINT((ndo, " NAK LIST"));
512		    while (opt_len) {
513			if (opt_len < sizeof(uint32_t)) {
514			    ND_PRINT((ndo, "[Option length not a multiple of 4]"));
515			    return;
516			}
517			ND_TCHECK2(*bp, sizeof(uint32_t));
518			ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp)));
519			bp += sizeof(uint32_t);
520			opt_len -= sizeof(uint32_t);
521			opts_len -= sizeof(uint32_t);
522		    }
523		    break;
524
525		case PGM_OPT_JOIN:
526		    if (opt_len != 8) {
527			ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != 8]", opt_len));
528			return;
529		    }
530		    bp += 2;
531		    seq = EXTRACT_32BITS(bp);
532		    bp += sizeof(uint32_t);
533		    ND_PRINT((ndo, " JOIN %u", seq));
534		    opts_len -= 8;
535		    break;
536
537		case PGM_OPT_NAK_BO_IVL:
538		    if (opt_len != 12) {
539			ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len));
540			return;
541		    }
542		    bp += 2;
543		    offset = EXTRACT_32BITS(bp);
544		    bp += sizeof(uint32_t);
545		    seq = EXTRACT_32BITS(bp);
546		    bp += sizeof(uint32_t);
547		    ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq));
548		    opts_len -= 12;
549		    break;
550
551		case PGM_OPT_NAK_BO_RNG:
552		    if (opt_len != 12) {
553			ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len));
554			return;
555		    }
556		    bp += 2;
557		    offset = EXTRACT_32BITS(bp);
558		    bp += sizeof(uint32_t);
559		    seq = EXTRACT_32BITS(bp);
560		    bp += sizeof(uint32_t);
561		    ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq));
562		    opts_len -= 12;
563		    break;
564
565		case PGM_OPT_REDIRECT:
566		    bp += 2;
567		    nla_afnum = EXTRACT_16BITS(bp);
568		    bp += (2 * sizeof(uint16_t));
569		    switch (nla_afnum) {
570		    case AFNUM_INET:
571			if (opt_len != 4 + sizeof(struct in_addr)) {
572			    ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len));
573			    return;
574			}
575			ND_TCHECK2(*bp, sizeof(struct in_addr));
576			addrtostr(bp, nla_buf, sizeof(nla_buf));
577			bp += sizeof(struct in_addr);
578			opts_len -= 4 + sizeof(struct in_addr);
579			break;
580		    case AFNUM_INET6:
581			if (opt_len != 4 + sizeof(struct in6_addr)) {
582			    ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len));
583			    return;
584			}
585			ND_TCHECK2(*bp, sizeof(struct in6_addr));
586			addrtostr6(bp, nla_buf, sizeof(nla_buf));
587			bp += sizeof(struct in6_addr);
588			opts_len -= 4 + sizeof(struct in6_addr);
589			break;
590		    default:
591			goto trunc;
592			break;
593		    }
594
595		    ND_PRINT((ndo, " REDIRECT %s",  nla_buf));
596		    break;
597
598		case PGM_OPT_PARITY_PRM:
599		    if (opt_len != 8) {
600			ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len));
601			return;
602		    }
603		    bp += 2;
604		    len = EXTRACT_32BITS(bp);
605		    bp += sizeof(uint32_t);
606		    ND_PRINT((ndo, " PARITY MAXTGS %u", len));
607		    opts_len -= 8;
608		    break;
609
610		case PGM_OPT_PARITY_GRP:
611		    if (opt_len != 8) {
612			ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len));
613			return;
614		    }
615		    bp += 2;
616		    seq = EXTRACT_32BITS(bp);
617		    bp += sizeof(uint32_t);
618		    ND_PRINT((ndo, " PARITY GROUP %u", seq));
619		    opts_len -= 8;
620		    break;
621
622		case PGM_OPT_CURR_TGSIZE:
623		    if (opt_len != 8) {
624			ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len));
625			return;
626		    }
627		    bp += 2;
628		    len = EXTRACT_32BITS(bp);
629		    bp += sizeof(uint32_t);
630		    ND_PRINT((ndo, " PARITY ATGS %u", len));
631		    opts_len -= 8;
632		    break;
633
634		case PGM_OPT_NBR_UNREACH:
635		    if (opt_len != 4) {
636			ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len));
637			return;
638		    }
639		    bp += 2;
640		    ND_PRINT((ndo, " NBR_UNREACH"));
641		    opts_len -= 4;
642		    break;
643
644		case PGM_OPT_PATH_NLA:
645		    ND_PRINT((ndo, " PATH_NLA [%d]", opt_len));
646		    bp += opt_len;
647		    opts_len -= opt_len;
648		    break;
649
650		case PGM_OPT_SYN:
651		    if (opt_len != 4) {
652			ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != 4]", opt_len));
653			return;
654		    }
655		    bp += 2;
656		    ND_PRINT((ndo, " SYN"));
657		    opts_len -= 4;
658		    break;
659
660		case PGM_OPT_FIN:
661		    if (opt_len != 4) {
662			ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != 4]", opt_len));
663			return;
664		    }
665		    bp += 2;
666		    ND_PRINT((ndo, " FIN"));
667		    opts_len -= 4;
668		    break;
669
670		case PGM_OPT_RST:
671		    if (opt_len != 4) {
672			ND_PRINT((ndo, "[Bad OPT_RST option, length %u != 4]", opt_len));
673			return;
674		    }
675		    bp += 2;
676		    ND_PRINT((ndo, " RST"));
677		    opts_len -= 4;
678		    break;
679
680		case PGM_OPT_CR:
681		    ND_PRINT((ndo, " CR"));
682		    bp += opt_len;
683		    opts_len -= opt_len;
684		    break;
685
686		case PGM_OPT_CRQST:
687		    if (opt_len != 4) {
688			ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != 4]", opt_len));
689			return;
690		    }
691		    bp += 2;
692		    ND_PRINT((ndo, " CRQST"));
693		    opts_len -= 4;
694		    break;
695
696		case PGM_OPT_PGMCC_DATA:
697		    bp += 2;
698		    offset = EXTRACT_32BITS(bp);
699		    bp += sizeof(uint32_t);
700		    nla_afnum = EXTRACT_16BITS(bp);
701		    bp += (2 * sizeof(uint16_t));
702		    switch (nla_afnum) {
703		    case AFNUM_INET:
704			if (opt_len != 12 + sizeof(struct in_addr)) {
705			    ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
706			    return;
707			}
708			ND_TCHECK2(*bp, sizeof(struct in_addr));
709			addrtostr(bp, nla_buf, sizeof(nla_buf));
710			bp += sizeof(struct in_addr);
711			opts_len -= 12 + sizeof(struct in_addr);
712			break;
713		    case AFNUM_INET6:
714			if (opt_len != 12 + sizeof(struct in6_addr)) {
715			    ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
716			    return;
717			}
718			ND_TCHECK2(*bp, sizeof(struct in6_addr));
719			addrtostr6(bp, nla_buf, sizeof(nla_buf));
720			bp += sizeof(struct in6_addr);
721			opts_len -= 12 + sizeof(struct in6_addr);
722			break;
723		    default:
724			goto trunc;
725			break;
726		    }
727
728		    ND_PRINT((ndo, " PGMCC DATA %u %s", offset, nla_buf));
729		    break;
730
731		case PGM_OPT_PGMCC_FEEDBACK:
732		    bp += 2;
733		    offset = EXTRACT_32BITS(bp);
734		    bp += sizeof(uint32_t);
735		    nla_afnum = EXTRACT_16BITS(bp);
736		    bp += (2 * sizeof(uint16_t));
737		    switch (nla_afnum) {
738		    case AFNUM_INET:
739			if (opt_len != 12 + sizeof(struct in_addr)) {
740			    ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
741			    return;
742			}
743			ND_TCHECK2(*bp, sizeof(struct in_addr));
744			addrtostr(bp, nla_buf, sizeof(nla_buf));
745			bp += sizeof(struct in_addr);
746			opts_len -= 12 + sizeof(struct in_addr);
747			break;
748		    case AFNUM_INET6:
749			if (opt_len != 12 + sizeof(struct in6_addr)) {
750			    ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
751			    return;
752			}
753			ND_TCHECK2(*bp, sizeof(struct in6_addr));
754			addrtostr6(bp, nla_buf, sizeof(nla_buf));
755			bp += sizeof(struct in6_addr);
756			opts_len -= 12 + sizeof(struct in6_addr);
757			break;
758		    default:
759			goto trunc;
760			break;
761		    }
762
763		    ND_PRINT((ndo, " PGMCC FEEDBACK %u %s", offset, nla_buf));
764		    break;
765
766		default:
767		    ND_PRINT((ndo, " OPT_%02X [%d] ", opt_type, opt_len));
768		    bp += opt_len;
769		    opts_len -= opt_len;
770		    break;
771		}
772
773		if (opt_type & PGM_OPT_END)
774		    break;
775	     }
776	}
777
778	ND_PRINT((ndo, " [%u]", length));
779	if (ndo->ndo_packettype == PT_PGM_ZMTP1 &&
780	    (pgm->pgm_type == PGM_ODATA || pgm->pgm_type == PGM_RDATA))
781		zmtp1_print_datagram(ndo, bp, EXTRACT_16BITS(&pgm->pgm_length));
782
783	return;
784
785trunc:
786	ND_PRINT((ndo, "[|pgm]"));
787	if (ch != '\0')
788		ND_PRINT((ndo, ">"));
789}
790