]> The Tcpdump Group git mirrors - tcpdump/blob - print-ospf6.c
style pedant. buffer length check cleanup will be next.
[tcpdump] / print-ospf6.c
1 /*
2 * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
22 */
23
24 #ifndef lint
25 static const char rcsid[] =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.4 2000-05-12 13:01:02 itojun Exp $ (LBL)";
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <sys/param.h>
34 #include <sys/time.h>
35 #include <sys/socket.h>
36
37 #include <netinet/in.h>
38 #include <netinet/in_systm.h>
39 #include <netinet/ip.h>
40 #include <netinet/ip_var.h>
41
42 #include <ctype.h>
43 #include <stdio.h>
44 #include <string.h>
45
46 #include "interface.h"
47 #include "addrtoname.h"
48
49 #include "ospf6.h"
50
51 struct bits {
52 u_int32_t bit;
53 const char *str;
54 };
55
56 static const struct bits ospf6_option_bits[] = {
57 { OSPF6_OPTION_V6, "V6" },
58 { OSPF6_OPTION_E, "E" },
59 { OSPF6_OPTION_MC, "MC" },
60 { OSPF6_OPTION_N, "N" },
61 { OSPF6_OPTION_R, "R" },
62 { OSPF6_OPTION_DC, "DC" },
63 { 0, NULL }
64 };
65
66 static const struct bits ospf6_rla_flag_bits[] = {
67 { RLA_FLAG_B, "B" },
68 { RLA_FLAG_E, "E" },
69 { RLA_FLAG_V, "V" },
70 { RLA_FLAG_W, "W" },
71 { 0, NULL }
72 };
73
74 static const struct bits ospf6_asla_flag_bits[] = {
75 { ASLA_FLAG_EXTERNAL, "E" },
76 { ASLA_FLAG_FWDADDR, "F" },
77 { ASLA_FLAG_ROUTETAG, "T" },
78 { 0, NULL }
79 };
80
81 static struct tok type2str[] = {
82 { OSPF_TYPE_UMD, "umd" },
83 { OSPF_TYPE_HELLO, "hello" },
84 { OSPF_TYPE_DB, "dd" },
85 { OSPF_TYPE_LSR, "ls_req" },
86 { OSPF_TYPE_LSU, "ls_upd" },
87 { OSPF_TYPE_LSA, "ls_ack" },
88 { 0, NULL }
89 };
90
91 static char tstr[] = " [|ospf]";
92
93 /* Forwards */
94 static inline void ospf6_print_seqage(u_int32_t, time_t);
95 static inline void ospf6_print_bits(const struct bits *, u_char);
96 static void ospf6_print_ls_type(u_int, const rtrid_t *,
97 const rtrid_t *, const char *);
98 static int ospf6_print_lshdr(const struct lsa_hdr *);
99 static int ospf6_print_lsa(const struct lsa *);
100 static int ospf6_decode_v3(const struct ospf6hdr *, const u_char *);
101
102 static inline void
103 ospf6_print_seqage(register u_int32_t seq, register time_t us)
104 {
105 register time_t sec = us % 60;
106 register time_t mins = (us / 60) % 60;
107 register time_t hour = us / 3600;
108
109 printf(" S %X age ", seq);
110 if (hour)
111 printf("%u:%02u:%02u",
112 (u_int32_t) hour, (u_int32_t) mins, (u_int32_t) sec);
113 else if (mins)
114 printf("%u:%02u", (u_int32_t) mins, (u_int32_t) sec);
115 else
116 printf("%u", (u_int32_t) sec);
117 }
118
119
120 static inline void
121 ospf6_print_bits(register const struct bits *bp, register u_char options)
122 {
123 register char sep = ' ';
124
125 do {
126 if (options & bp->bit) {
127 printf("%c%s", sep, bp->str);
128 sep = '/';
129 }
130 } while ((++bp)->bit);
131 }
132
133 static void
134 ospf6_print_ls_type(register u_int ls_type,
135 register const rtrid_t *ls_stateid,
136 register const rtrid_t *ls_router, register const char *fmt)
137 {
138 char *scope;
139
140 switch (ls_type & LS_SCOPE_MASK) {
141 case LS_SCOPE_LINKLOCAL:
142 scope = "linklocal-";
143 break;
144 case LS_SCOPE_AREA:
145 scope = "area-";
146 break;
147 case LS_SCOPE_AS:
148 scope = "AS-";
149 break;
150 default:
151 scope = "";
152 break;
153 }
154
155 switch (ls_type & LS_TYPE_MASK) {
156 case LS_TYPE_ROUTER:
157 printf(" %srtr %s", scope, ipaddr_string(ls_router));
158 break;
159
160 case LS_TYPE_NETWORK:
161 printf(" %snet dr %s if %s", scope,
162 ipaddr_string(ls_router),
163 ipaddr_string(ls_stateid));
164 break;
165
166 case LS_TYPE_INTER_AP:
167 printf(" %sinter-area-prefix %s abr %s", scope,
168 ipaddr_string(ls_stateid),
169 ipaddr_string(ls_router));
170 break;
171
172 case LS_TYPE_INTER_AR:
173 printf(" %sinter-area-router %s rtr %s", scope,
174 ipaddr_string(ls_router),
175 ipaddr_string(ls_stateid));
176 break;
177
178 case LS_TYPE_ASE:
179 printf(" %sase %s asbr %s", scope,
180 ipaddr_string(ls_stateid),
181 ipaddr_string(ls_router));
182 break;
183
184 case LS_TYPE_GROUP:
185 printf(" %sgroup %s rtr %s", scope,
186 ipaddr_string(ls_stateid),
187 ipaddr_string(ls_router));
188 break;
189
190 case LS_TYPE_TYPE7:
191 printf(" %stype7 %s rtr %s", scope,
192 ipaddr_string(ls_stateid),
193 ipaddr_string(ls_router));
194 break;
195
196 case LS_TYPE_LINK:
197 printf(" %slink %s rtr %s", scope,
198 ipaddr_string(ls_stateid),
199 ipaddr_string(ls_router));
200 break;
201
202 case LS_TYPE_INTRA_AP:
203 printf(" %sintra-area-prefix %s rtr %s", scope,
204 ipaddr_string(ls_stateid),
205 ipaddr_string(ls_router));
206 break;
207
208 default:
209 printf(" %s", scope);
210 printf(fmt, ls_type);
211 break;
212 }
213
214 }
215
216 static int
217 ospf6_print_lshdr(register const struct lsa_hdr *lshp)
218 {
219
220 TCHECK(lshp->ls_type);
221 printf(" {"); /* } (ctags) */
222
223 TCHECK(lshp->ls_seq);
224 ospf6_print_seqage(ntohl(lshp->ls_seq), ntohs(lshp->ls_age));
225 ospf6_print_ls_type(ntohs(lshp->ls_type), &lshp->ls_stateid,
226 &lshp->ls_router, "ls_type %d");
227
228 return (0);
229 trunc:
230 return (1);
231 }
232
233 static int
234 ospf6_print_lsaprefix(register const struct lsa_prefix *lsapp)
235 {
236 int k;
237 struct in6_addr prefix;
238
239 TCHECK(*lsapp);
240 k = (lsapp->lsa_p_len + 31) / 32;
241 if (k * 4 > sizeof(struct in6_addr)) {
242 printf("??prefixlen %d??", lsapp->lsa_p_len);
243 goto trunc;
244 }
245 memset(&prefix, 0, sizeof(prefix));
246 memcpy(&prefix, lsapp->lsa_p_prefix, k * 4);
247 printf(" %s/%d", ip6addr_string(&prefix),
248 lsapp->lsa_p_len);
249 if (lsapp->lsa_p_opt)
250 printf("(opt=%x)", lsapp->lsa_p_opt);
251 if (lsapp->lsa_p_mbz)
252 printf("(mbz=%x)", ntohs(lsapp->lsa_p_mbz)); /* XXX */
253 return sizeof(*lsapp) - 4 + k * 4;
254
255 trunc:
256 return -1;
257 }
258
259
260 /*
261 * Print a single link state advertisement. If truncated return 1, else 0.
262 */
263 static int
264 ospf6_print_lsa(register const struct lsa *lsap)
265 {
266 register const u_char *ls_end, *ls_opt;
267 register const struct rlalink *rlp;
268 #if 0
269 register const struct tos_metric *tosp;
270 #endif
271 register const rtrid_t *ap;
272 #if 0
273 register const struct aslametric *almp;
274 register const struct mcla *mcp;
275 #endif
276 register const struct llsa *llsap;
277 register const struct lsa_prefix *lsapp;
278 #if 0
279 register const u_int32_t *lp;
280 #endif
281 register int j, k;
282 u_int32_t flags32;
283
284 if (ospf6_print_lshdr(&lsap->ls_hdr))
285 return (1);
286 TCHECK(lsap->ls_hdr.ls_length);
287 ls_end = (u_char *)lsap + ntohs(lsap->ls_hdr.ls_length);
288 switch (ntohs(lsap->ls_hdr.ls_type)) {
289 case LS_TYPE_ROUTER | LS_SCOPE_AREA:
290 TCHECK(lsap->lsa_un.un_rla.rla_flags);
291 ospf6_print_bits(ospf6_rla_flag_bits,
292 lsap->lsa_un.un_rla.rla_flags);
293 TCHECK(lsap->lsa_un.un_rla.rla_options);
294 ospf6_print_bits(ospf6_option_bits,
295 ntohl(lsap->lsa_un.un_rla.rla_options));
296
297 TCHECK(lsap->lsa_un.un_rla.rla_link);
298 rlp = lsap->lsa_un.un_rla.rla_link;
299 while (rlp + sizeof(*rlp) <= (struct rlalink *)ls_end) {
300 TCHECK(*rlp);
301 printf(" {"); /* } (ctags) */
302 switch (rlp->link_type) {
303
304 case RLA_TYPE_VIRTUAL:
305 printf(" virt");
306 /* Fall through */
307
308 case RLA_TYPE_ROUTER:
309 printf(" nbrid %s nbrif %s if %s",
310 ipaddr_string(&rlp->link_nrtid),
311 ipaddr_string(&rlp->link_nifid),
312 ipaddr_string(&rlp->link_ifid));
313 break;
314
315 case RLA_TYPE_TRANSIT:
316 printf(" dr %s drif %s if %s",
317 ipaddr_string(&rlp->link_nrtid),
318 ipaddr_string(&rlp->link_nifid),
319 ipaddr_string(&rlp->link_ifid));
320 break;
321
322 default:
323 /* { (ctags) */
324 printf(" ??RouterLinksType 0x%02x?? }",
325 rlp->link_type);
326 return (0);
327 }
328 printf(" metric %d", ntohs(rlp->link_metric));
329 /* { (ctags) */
330 printf(" }");
331 rlp++;
332 }
333 break;
334
335 case LS_TYPE_NETWORK | LS_SCOPE_AREA:
336 TCHECK(lsap->lsa_un.un_nla.nla_options);
337 ospf6_print_bits(ospf6_option_bits,
338 ntohl(lsap->lsa_un.un_nla.nla_options));
339 printf(" rtrs");
340 ap = lsap->lsa_un.un_nla.nla_router;
341 while ((u_char *)ap < ls_end) {
342 TCHECK(*ap);
343 printf(" %s", ipaddr_string(ap));
344 ++ap;
345 }
346 break;
347
348 case LS_TYPE_INTER_AP | LS_SCOPE_AREA:
349 TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric);
350 printf(" metric %u",
351 (u_int32_t)ntohl(lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC);
352 lsapp = lsap->lsa_un.un_inter_ap.inter_ap_prefix;
353 while (lsapp + sizeof(lsapp) <= (struct lsa_prefix *)ls_end) {
354 k = ospf6_print_lsaprefix(lsapp);
355 if (k)
356 goto trunc;
357 lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k);
358 }
359 break;
360 case LS_SCOPE_AS | LS_TYPE_ASE:
361 TCHECK(lsap->lsa_un.un_asla.asla_metric);
362 flags32 = ntohl(lsap->lsa_un.un_asla.asla_metric);
363 ospf6_print_bits(ospf6_asla_flag_bits, flags32);
364 printf(" metric %u",
365 ntohl(lsap->lsa_un.un_asla.asla_metric) &
366 ASLA_MASK_METRIC);
367 lsapp = lsap->lsa_un.un_asla.asla_prefix;
368 k = ospf6_print_lsaprefix(lsapp);
369 if (k < 0)
370 goto trunc;
371 if ((ls_opt = (u_char *)(((u_char *)lsapp) + k)) < ls_end) {
372 struct in6_addr *fwdaddr6;
373
374 if ((flags32 & ASLA_FLAG_FWDADDR) != 0) {
375 fwdaddr6 = (struct in6_addr *)ls_opt;
376 TCHECK(*fwdaddr6);
377 printf(" forward %s",
378 ip6addr_string(fwdaddr6));
379
380 ls_opt += sizeof(struct in6_addr);
381 }
382
383 if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) {
384 TCHECK(*(u_int32_t *)ls_opt);
385 printf(" tag %s",
386 ipaddr_string((u_int32_t *)ls_opt));
387
388 ls_opt += sizeof(u_int32_t);
389 }
390
391 if (lsapp->lsa_p_mbz) {
392 TCHECK(*(u_int32_t *)ls_opt);
393 printf(" RefLSID: %s",
394 ipaddr_string((u_int32_t *)ls_opt));
395
396 ls_opt += sizeof(u_int32_t);
397 }
398 }
399 break;
400 #if 0
401 case LS_TYPE_SUM_ABR:
402 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
403 lp = lsap->lsa_un.un_sla.sla_tosmetric;
404 while ((u_char *)lp < ls_end) {
405 register u_int32_t ul;
406
407 TCHECK(*lp);
408 ul = ntohl(*lp);
409 printf(" tos %d metric %d",
410 (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
411 ul & SLA_MASK_METRIC);
412 ++lp;
413 }
414 break;
415
416 case LS_TYPE_GROUP:
417 /* Multicast extensions as of 23 July 1991 */
418 mcp = lsap->lsa_un.un_mcla;
419 while ((u_char *)mcp < ls_end) {
420 TCHECK(mcp->mcla_vid);
421 switch (ntohl(mcp->mcla_vtype)) {
422
423 case MCLA_VERTEX_ROUTER:
424 printf(" rtr rtrid %s",
425 ipaddr_string(&mcp->mcla_vid));
426 break;
427
428 case MCLA_VERTEX_NETWORK:
429 printf(" net dr %s",
430 ipaddr_string(&mcp->mcla_vid));
431 break;
432
433 default:
434 printf(" ??VertexType %u??",
435 (u_int32_t)ntohl(mcp->mcla_vtype));
436 break;
437 }
438 ++mcp;
439 }
440 #endif
441
442 case LS_TYPE_LINK:
443 /* Link LSA */
444 llsap = &lsap->lsa_un.un_llsa;
445 TCHECK(llsap->llsa_options);
446 ospf6_print_bits(ospf6_option_bits, ntohl(llsap->llsa_options));
447 TCHECK(llsap->llsa_nprefix);
448 printf(" pri %d lladdr %s npref %d", llsap->llsa_priority,
449 ip6addr_string(&llsap->llsa_lladdr),
450 (u_int32_t)ntohl(llsap->llsa_nprefix));
451 lsapp = llsap->llsa_prefix;
452 for (j = 0; j < ntohl(llsap->llsa_nprefix); j++) {
453 k = ospf6_print_lsaprefix(lsapp);
454 if (k)
455 goto trunc;
456 lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k);
457 }
458 break;
459
460 case LS_TYPE_INTRA_AP | LS_SCOPE_AREA:
461 /* Intra-Area-Prefix LSA */
462 TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid);
463 ospf6_print_ls_type(
464 ntohs(lsap->lsa_un.un_intra_ap.intra_ap_lstype),
465 &lsap->lsa_un.un_intra_ap.intra_ap_lsid,
466 &lsap->lsa_un.un_intra_ap.intra_ap_rtid,
467 "LinkStateType %d");
468 TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
469 printf(" npref %d",
470 ntohs(lsap->lsa_un.un_intra_ap.intra_ap_nprefix));
471
472 lsapp = lsap->lsa_un.un_intra_ap.intra_ap_prefix;
473 for (j = 0;
474 j < ntohs(lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
475 j++) {
476 k = ospf6_print_lsaprefix(lsapp);
477 if (k)
478 goto trunc;
479 lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k);
480 }
481 break;
482
483 default:
484 printf(" ??LinkStateType 0x%04x??",
485 ntohs(lsap->ls_hdr.ls_type));
486 }
487
488 /* { (ctags) */
489 fputs(" }", stdout);
490 return (0);
491 trunc:
492 fputs(" }", stdout);
493 return (1);
494 }
495
496 static int
497 ospf6_decode_v3(register const struct ospf6hdr *op,
498 register const u_char *dataend)
499 {
500 register const rtrid_t *ap;
501 register const struct lsr *lsrp;
502 register const struct lsa_hdr *lshp;
503 register const struct lsa *lsap;
504 register char sep;
505 register int i;
506
507 switch (op->ospf6_type) {
508
509 case OSPF_TYPE_UMD:
510 /*
511 * Rob Coltun's special monitoring packets;
512 * do nothing
513 */
514 break;
515
516 case OSPF_TYPE_HELLO:
517 if (vflag) {
518 TCHECK(op->ospf6_hello.hello_deadint);
519 ospf6_print_bits(ospf6_option_bits,
520 ntohl(op->ospf6_hello.hello_options));
521 printf(" ifid %s pri %d int %d dead %u",
522 ipaddr_string(&op->ospf6_hello.hello_ifid),
523 op->ospf6_hello.hello_priority,
524 ntohs(op->ospf6_hello.hello_helloint),
525 ntohs(op->ospf6_hello.hello_deadint));
526 }
527 TCHECK(op->ospf6_hello.hello_dr);
528 if (op->ospf6_hello.hello_dr != 0)
529 printf(" dr %s",
530 ipaddr_string(&op->ospf6_hello.hello_dr));
531 TCHECK(op->ospf6_hello.hello_bdr);
532 if (op->ospf6_hello.hello_bdr != 0)
533 printf(" bdr %s",
534 ipaddr_string(&op->ospf6_hello.hello_bdr));
535 if (vflag) {
536 printf(" nbrs");
537 ap = op->ospf6_hello.hello_neighbor;
538 while ((u_char *)ap < dataend) {
539 TCHECK(*ap);
540 printf(" %s", ipaddr_string(ap));
541 ++ap;
542 }
543 }
544 break; /* HELLO */
545
546 case OSPF_TYPE_DB:
547 TCHECK(op->ospf6_db.db_options);
548 ospf6_print_bits(ospf6_option_bits,
549 ntohl(op->ospf6_db.db_options));
550 sep = ' ';
551 TCHECK(op->ospf6_db.db_flags);
552 if (op->ospf6_db.db_flags & OSPF6_DB_INIT) {
553 printf("%cI", sep);
554 sep = '/';
555 }
556 if (op->ospf6_db.db_flags & OSPF6_DB_MORE) {
557 printf("%cM", sep);
558 sep = '/';
559 }
560 if (op->ospf6_db.db_flags & OSPF6_DB_MASTER) {
561 printf("%cMS", sep);
562 sep = '/';
563 }
564 TCHECK(op->ospf6_db.db_seq);
565 printf(" mtu %u S %X", ntohs(op->ospf6_db.db_mtu),
566 (u_int32_t)ntohl(op->ospf6_db.db_seq));
567
568 if (vflag) {
569 /* Print all the LS adv's */
570 lshp = op->ospf6_db.db_lshdr;
571
572 while (!ospf6_print_lshdr(lshp)) {
573 /* { (ctags) */
574 printf(" }");
575 ++lshp;
576 }
577 }
578 break;
579
580 case OSPF_TYPE_LSR:
581 if (vflag) {
582 lsrp = op->ospf6_lsr;
583 while ((u_char *)lsrp < dataend) {
584 TCHECK(*lsrp);
585 printf(" {"); /* } (ctags) */
586 ospf6_print_ls_type(ntohs(lsrp->ls_type),
587 &lsrp->ls_stateid,
588 &lsrp->ls_router,
589 "LinkStateType %d");
590 /* { (ctags) */
591 printf(" }");
592 ++lsrp;
593 }
594 }
595 break;
596
597 case OSPF_TYPE_LSU:
598 if (vflag) {
599 lsap = op->ospf6_lsu.lsu_lsa;
600 TCHECK(op->ospf6_lsu.lsu_count);
601 i = ntohl(op->ospf6_lsu.lsu_count);
602 while (i--) {
603 if (ospf6_print_lsa(lsap))
604 goto trunc;
605 lsap = (struct lsa *)((u_char *)lsap +
606 ntohs(lsap->ls_hdr.ls_length));
607 }
608 }
609 break;
610
611
612 case OSPF_TYPE_LSA:
613 if (vflag) {
614 lshp = op->ospf6_lsa.lsa_lshdr;
615
616 while (!ospf6_print_lshdr(lshp)) {
617 /* { (ctags) */
618 printf(" }");
619 ++lshp;
620 }
621 }
622 break;
623
624 default:
625 printf("v3 type %d", op->ospf6_type);
626 break;
627 }
628 return (0);
629 trunc:
630 return (1);
631 }
632
633 void
634 ospf6_print(register const u_char *bp, register u_int length)
635 {
636 register const struct ospf6hdr *op;
637 register const u_char *dataend;
638 register const char *cp;
639
640 op = (struct ospf6hdr *)bp;
641
642 /* If the type is valid translate it, or just print the type */
643 /* value. If it's not valid, say so and return */
644 TCHECK(op->ospf6_type);
645 cp = tok2str(type2str, "type%d", op->ospf6_type);
646 printf("OSPFv%d-%s %d:", op->ospf6_version, cp, length);
647 if (*cp == 't')
648 return;
649
650 TCHECK(op->ospf6_len);
651 if (length != ntohs(op->ospf6_len)) {
652 printf(" [len %d]", ntohs(op->ospf6_len));
653 return;
654 }
655 dataend = bp + length;
656
657 /* Print the routerid if it is not the same as the source */
658 TCHECK(op->ospf6_routerid);
659 printf(" rtrid %s", ipaddr_string(&op->ospf6_routerid));
660
661 TCHECK(op->ospf6_areaid);
662 if (op->ospf6_areaid != 0)
663 printf(" area %s", ipaddr_string(&op->ospf6_areaid));
664 else
665 printf(" backbone");
666 TCHECK(op->ospf6_instanceid);
667 if (op->ospf6_instanceid)
668 printf(" instance %u", op->ospf6_instanceid);
669
670 /* Do rest according to version. */
671 switch (op->ospf6_version) {
672
673 case 3:
674 /* ospf version 3 */
675 if (ospf6_decode_v3(op, dataend))
676 goto trunc;
677 break;
678
679 default:
680 printf(" ospf [version %d]", op->ospf6_version);
681 break;
682 } /* end switch on version */
683
684 return;
685 trunc:
686 fputs(tstr, stdout);
687 }