]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-pgm.c
Update ena-com HAL to v1.1.4.3 and update driver accordingly
[FreeBSD/FreeBSD.git] / contrib / tcpdump / print-pgm.c
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 }