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