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