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[] _U_ = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.15 2006-09-13 06:31:11 guy 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 #include "extract.h" 41 42 #include "ospf.h" 43 #include "ospf6.h" 44 45 static const struct tok ospf6_option_values[] = { 46 { OSPF6_OPTION_V6, "V6" }, 47 { OSPF6_OPTION_E, "External" }, 48 { OSPF6_OPTION_MC, "Multicast" }, 49 { OSPF6_OPTION_N, "NSSA" }, 50 { OSPF6_OPTION_R, "Router" }, 51 { OSPF6_OPTION_DC, "Demand Circuit" }, 52 { 0, NULL } 53 }; 54 55 static const struct tok ospf6_rla_flag_values[] = { 56 { RLA_FLAG_B, "ABR" }, 57 { RLA_FLAG_E, "External" }, 58 { RLA_FLAG_V, "Virtual-Link Endpoint" }, 59 { RLA_FLAG_W, "Wildcard Receiver" }, 60 { RLA_FLAG_N, "NSSA Translator" }, 61 { 0, NULL } 62 }; 63 64 static const struct tok ospf6_asla_flag_values[] = { 65 { ASLA_FLAG_EXTERNAL, "External Type 2" }, 66 { ASLA_FLAG_FWDADDR, "Fforwarding" }, 67 { ASLA_FLAG_ROUTETAG, "Tag" }, 68 { 0, NULL } 69 }; 70 71 static struct tok ospf6_type_values[] = { 72 { OSPF_TYPE_HELLO, "Hello" }, 73 { OSPF_TYPE_DD, "Database Description" }, 74 { OSPF_TYPE_LS_REQ, "LS-Request" }, 75 { OSPF_TYPE_LS_UPDATE, "LS-Update" }, 76 { OSPF_TYPE_LS_ACK, "LS-Ack" }, 77 { 0, NULL } 78 }; 79 80 static struct tok ospf6_lsa_values[] = { 81 { LS_TYPE_ROUTER, "Router" }, 82 { LS_TYPE_NETWORK, "Network" }, 83 { LS_TYPE_INTER_AP, "Inter-Area Prefix" }, 84 { LS_TYPE_INTER_AR, "Inter-Area Router" }, 85 { LS_TYPE_ASE, "External" }, 86 { LS_TYPE_GROUP, "Multicast Group" }, 87 { LS_TYPE_NSSA, "NSSA" }, 88 { LS_TYPE_LINK, "Link" }, 89 { LS_TYPE_INTRA_AP, "Intra-Area Prefix" }, 90 { LS_TYPE_INTRA_ATE, "Intra-Area TE" }, 91 { LS_TYPE_GRACE, "Grace" }, 92 { 0, NULL } 93 }; 94 95 static struct tok ospf6_ls_scope_values[] = { 96 { LS_SCOPE_LINKLOCAL, "Link Local" }, 97 { LS_SCOPE_AREA, "Area Local" }, 98 { LS_SCOPE_AS, "Domain Wide" }, 99 { 0, NULL } 100 }; 101 102 static struct tok ospf6_dd_flag_values[] = { 103 { OSPF6_DB_INIT, "Init" }, 104 { OSPF6_DB_MORE, "More" }, 105 { OSPF6_DB_MASTER, "Master" }, 106 { 0, NULL } 107 }; 108 109 static struct tok ospf6_lsa_prefix_option_values[] = { 110 { LSA_PREFIX_OPT_NU, "No Unicast" }, 111 { LSA_PREFIX_OPT_LA, "Local address" }, 112 { LSA_PREFIX_OPT_MC, "Multicast" }, 113 { LSA_PREFIX_OPT_P, "Propagate" }, 114 { LSA_PREFIX_OPT_DN, "Down" }, 115 { 0, NULL } 116 }; 117 118 static char tstr[] = " [|ospf3]"; 119 120 #ifdef WIN32 121 #define inline __inline 122 #endif /* WIN32 */ 123 124 /* Forwards */ 125 static void ospf6_print_ls_type(u_int, const rtrid_t *); 126 static int ospf6_print_lshdr(const struct lsa6_hdr *); 127 static int ospf6_print_lsa(const struct lsa6 *); 128 static int ospf6_decode_v3(const struct ospf6hdr *, const u_char *); 129 130 131 static void 132 ospf6_print_ls_type(register u_int ls_type, register const rtrid_t *ls_stateid) 133 { 134 printf("\n\t %s LSA (%d), %s Scope%s, LSA-ID %s", 135 tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK), 136 ls_type & LS_TYPE_MASK, 137 tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK), 138 ls_type &0x8000 ? ", transitive" : "", /* U-bit */ 139 ipaddr_string(ls_stateid)); 140 } 141 142 static int 143 ospf6_print_lshdr(register const struct lsa6_hdr *lshp) 144 { 145 146 TCHECK(lshp->ls_type); 147 TCHECK(lshp->ls_seq); 148 149 printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", 150 ipaddr_string(&lshp->ls_router), 151 EXTRACT_32BITS(&lshp->ls_seq), 152 EXTRACT_16BITS(&lshp->ls_age), 153 EXTRACT_16BITS(&lshp->ls_length)-(u_int)sizeof(struct lsa6_hdr)); 154 155 ospf6_print_ls_type(EXTRACT_16BITS(&lshp->ls_type), &lshp->ls_stateid); 156 157 return (0); 158 trunc: 159 return (1); 160 } 161 162 static int 163 ospf6_print_lsaprefix(const u_int8_t *tptr, u_int lsa_length) 164 { 165 const struct lsa6_prefix *lsapp = (struct lsa6_prefix *)tptr; 166 u_int wordlen; 167 struct in6_addr prefix; 168 169 if (lsa_length < sizeof (*lsapp) - 4) 170 goto trunc; 171 lsa_length -= sizeof (*lsapp) - 4; 172 TCHECK2(*lsapp, sizeof (*lsapp) - 4); 173 wordlen = (lsapp->lsa_p_len + 31) / 32; 174 if (wordlen * 4 > sizeof(struct in6_addr)) { 175 printf(" bogus prefixlen /%d", lsapp->lsa_p_len); 176 goto trunc; 177 } 178 if (lsa_length < wordlen * 4) 179 goto trunc; 180 lsa_length -= wordlen * 4; 181 TCHECK2(lsapp->lsa_p_prefix, wordlen * 4); 182 memset(&prefix, 0, sizeof(prefix)); 183 memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4); 184 printf("\n\t\t%s/%d", ip6addr_string(&prefix), 185 lsapp->lsa_p_len); 186 if (lsapp->lsa_p_opt) { 187 printf(", Options [%s]", 188 bittok2str(ospf6_lsa_prefix_option_values, 189 "none", lsapp->lsa_p_opt)); 190 } 191 printf(", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric)); 192 return sizeof(*lsapp) - 4 + wordlen * 4; 193 194 trunc: 195 return -1; 196 } 197 198 199 /* 200 * Print a single link state advertisement. If truncated return 1, else 0. 201 */ 202 static int 203 ospf6_print_lsa(register const struct lsa6 *lsap) 204 { 205 register const struct rlalink6 *rlp; 206 #if 0 207 register const struct tos_metric *tosp; 208 #endif 209 register const rtrid_t *ap; 210 #if 0 211 register const struct aslametric *almp; 212 register const struct mcla *mcp; 213 #endif 214 register const struct llsa *llsap; 215 register const struct lsa6_prefix *lsapp; 216 #if 0 217 register const u_int32_t *lp; 218 #endif 219 register u_int prefixes; 220 register int bytelen; 221 register u_int length, lsa_length; 222 u_int32_t flags32; 223 const u_int8_t *tptr; 224 225 if (ospf6_print_lshdr(&lsap->ls_hdr)) 226 return (1); 227 TCHECK(lsap->ls_hdr.ls_length); 228 length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length); 229 230 /* 231 * The LSA length includes the length of the header; 232 * it must have a value that's at least that length. 233 * If it does, find the length of what follows the 234 * header. 235 */ 236 if (length < sizeof(struct lsa6_hdr)) 237 return (1); 238 lsa_length = length - sizeof(struct lsa6_hdr); 239 tptr = (u_int8_t *)lsap+sizeof(struct lsa6_hdr); 240 241 switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { 242 case LS_TYPE_ROUTER | LS_SCOPE_AREA: 243 if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options)) 244 return (1); 245 lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options); 246 TCHECK(lsap->lsa_un.un_rla.rla_options); 247 printf("\n\t Options [%s]", 248 bittok2str(ospf6_option_values, "none", 249 EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options))); 250 printf(", RLA-Flags [%s]", 251 bittok2str(ospf6_rla_flag_values, "none", 252 lsap->lsa_un.un_rla.rla_flags)); 253 254 rlp = lsap->lsa_un.un_rla.rla_link; 255 while (lsa_length != 0) { 256 if (lsa_length < sizeof (*rlp)) 257 return (1); 258 lsa_length -= sizeof (*rlp); 259 TCHECK(*rlp); 260 switch (rlp->link_type) { 261 262 case RLA_TYPE_VIRTUAL: 263 printf("\n\t Virtual Link: Neighbor Router-ID %s" 264 "\n\t Neighbor Interface-ID %s, Interface %s", 265 ipaddr_string(&rlp->link_nrtid), 266 ipaddr_string(&rlp->link_nifid), 267 ipaddr_string(&rlp->link_ifid)); 268 break; 269 270 case RLA_TYPE_ROUTER: 271 printf("\n\t Neighbor Router-ID %s" 272 "\n\t Neighbor Interface-ID %s, Interface %s", 273 ipaddr_string(&rlp->link_nrtid), 274 ipaddr_string(&rlp->link_nifid), 275 ipaddr_string(&rlp->link_ifid)); 276 break; 277 278 case RLA_TYPE_TRANSIT: 279 printf("\n\t Neighbor Network-ID %s" 280 "\n\t Neighbor Interface-ID %s, Interface %s", 281 ipaddr_string(&rlp->link_nrtid), 282 ipaddr_string(&rlp->link_nifid), 283 ipaddr_string(&rlp->link_ifid)); 284 break; 285 286 default: 287 printf("\n\t Unknown Router Links Type 0x%02x", 288 rlp->link_type); 289 return (0); 290 } 291 printf(", metric %d", EXTRACT_16BITS(&rlp->link_metric)); 292 rlp++; 293 } 294 break; 295 296 case LS_TYPE_NETWORK | LS_SCOPE_AREA: 297 if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options)) 298 return (1); 299 lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options); 300 TCHECK(lsap->lsa_un.un_nla.nla_options); 301 printf("\n\t Options [%s]", 302 bittok2str(ospf6_option_values, "none", 303 EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options))); 304 305 printf("\n\t Connected Routers:"); 306 ap = lsap->lsa_un.un_nla.nla_router; 307 while (lsa_length != 0) { 308 if (lsa_length < sizeof (*ap)) 309 return (1); 310 lsa_length -= sizeof (*ap); 311 TCHECK(*ap); 312 printf("\n\t\t%s", ipaddr_string(ap)); 313 ++ap; 314 } 315 break; 316 317 case LS_TYPE_INTER_AP | LS_SCOPE_AREA: 318 if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric)) 319 return (1); 320 lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric); 321 TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); 322 printf(", metric %u", 323 EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC); 324 325 tptr = (u_int8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix; 326 while (lsa_length != 0) { 327 bytelen = ospf6_print_lsaprefix(tptr, lsa_length); 328 if (bytelen < 0) 329 goto trunc; 330 lsa_length -= bytelen; 331 tptr += bytelen; 332 } 333 break; 334 335 case LS_TYPE_ASE | LS_SCOPE_AS: 336 if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric)) 337 return (1); 338 lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric); 339 TCHECK(lsap->lsa_un.un_asla.asla_metric); 340 flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric); 341 printf("\n\t Flags [%s]", 342 bittok2str(ospf6_asla_flag_values, "none", flags32)); 343 printf(" metric %u", 344 EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & 345 ASLA_MASK_METRIC); 346 347 tptr = (u_int8_t *)lsap->lsa_un.un_asla.asla_prefix; 348 lsapp = (struct lsa6_prefix *)tptr; 349 bytelen = ospf6_print_lsaprefix(tptr, lsa_length); 350 if (bytelen < 0) 351 goto trunc; 352 lsa_length -= bytelen; 353 tptr += bytelen; 354 355 if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { 356 struct in6_addr *fwdaddr6; 357 358 fwdaddr6 = (struct in6_addr *)tptr; 359 if (lsa_length < sizeof (*fwdaddr6)) 360 return (1); 361 lsa_length -= sizeof (*fwdaddr6); 362 TCHECK(*fwdaddr6); 363 printf(" forward %s", 364 ip6addr_string(fwdaddr6)); 365 tptr += sizeof(*fwdaddr6); 366 } 367 368 if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { 369 if (lsa_length < sizeof (u_int32_t)) 370 return (1); 371 lsa_length -= sizeof (u_int32_t); 372 TCHECK(*(u_int32_t *)tptr); 373 printf(" tag %s", 374 ipaddr_string((u_int32_t *)tptr)); 375 tptr += sizeof(u_int32_t); 376 } 377 378 if (lsapp->lsa_p_metric) { 379 if (lsa_length < sizeof (u_int32_t)) 380 return (1); 381 lsa_length -= sizeof (u_int32_t); 382 TCHECK(*(u_int32_t *)tptr); 383 printf(" RefLSID: %s", 384 ipaddr_string((u_int32_t *)tptr)); 385 tptr += sizeof(u_int32_t); 386 } 387 break; 388 389 case LS_TYPE_LINK: 390 /* Link LSA */ 391 llsap = &lsap->lsa_un.un_llsa; 392 if (lsa_length < sizeof (llsap->llsa_priandopt)) 393 return (1); 394 lsa_length -= sizeof (llsap->llsa_priandopt); 395 TCHECK(llsap->llsa_priandopt); 396 printf("\n\t Options [%s]", 397 bittok2str(ospf6_option_values, "none", 398 EXTRACT_32BITS(&llsap->llsa_options))); 399 400 if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix)) 401 return (1); 402 lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix); 403 prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); 404 printf("\n\t Priority %d, Link-local address %s, Prefixes %d:", 405 llsap->llsa_priority, 406 ip6addr_string(&llsap->llsa_lladdr), 407 prefixes); 408 409 tptr = (u_int8_t *)llsap->llsa_prefix; 410 while (prefixes > 0) { 411 bytelen = ospf6_print_lsaprefix(tptr, lsa_length); 412 if (bytelen < 0) 413 goto trunc; 414 prefixes--; 415 lsa_length -= bytelen; 416 tptr += bytelen; 417 } 418 break; 419 420 case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: 421 /* Intra-Area-Prefix LSA */ 422 if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid)) 423 return (1); 424 lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid); 425 TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); 426 ospf6_print_ls_type( 427 EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype), 428 &lsap->lsa_un.un_intra_ap.intra_ap_lsid); 429 430 if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix)) 431 return (1); 432 lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 433 TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 434 prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 435 printf("\n\t Prefixes %d:", prefixes); 436 437 tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; 438 while (prefixes > 0) { 439 bytelen = ospf6_print_lsaprefix(tptr, lsa_length); 440 if (bytelen < 0) 441 goto trunc; 442 prefixes--; 443 lsa_length -= bytelen; 444 tptr += bytelen; 445 } 446 break; 447 448 case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL: 449 if (ospf_print_grace_lsa(tptr, lsa_length) == -1) { 450 return 1; 451 } 452 break; 453 454 case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL: 455 if (ospf_print_te_lsa(tptr, lsa_length) == -1) { 456 return 1; 457 } 458 break; 459 460 default: 461 if(!print_unknown_data(tptr, 462 "\n\t ", 463 lsa_length)) { 464 return (1); 465 } 466 break; 467 } 468 469 return (0); 470 trunc: 471 return (1); 472 } 473 474 static int 475 ospf6_decode_v3(register const struct ospf6hdr *op, 476 register const u_char *dataend) 477 { 478 register const rtrid_t *ap; 479 register const struct lsr6 *lsrp; 480 register const struct lsa6_hdr *lshp; 481 register const struct lsa6 *lsap; 482 register int i; 483 484 switch (op->ospf6_type) { 485 486 case OSPF_TYPE_HELLO: 487 printf("\n\tOptions [%s]", 488 bittok2str(ospf6_option_values, "none", 489 EXTRACT_32BITS(&op->ospf6_hello.hello_options))); 490 491 TCHECK(op->ospf6_hello.hello_deadint); 492 printf("\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u", 493 EXTRACT_16BITS(&op->ospf6_hello.hello_helloint), 494 EXTRACT_16BITS(&op->ospf6_hello.hello_deadint), 495 ipaddr_string(&op->ospf6_hello.hello_ifid), 496 op->ospf6_hello.hello_priority); 497 498 TCHECK(op->ospf6_hello.hello_dr); 499 if (op->ospf6_hello.hello_dr != 0) 500 printf("\n\t Designated Router %s", 501 ipaddr_string(&op->ospf6_hello.hello_dr)); 502 TCHECK(op->ospf6_hello.hello_bdr); 503 if (op->ospf6_hello.hello_bdr != 0) 504 printf(", Backup Designated Router %s", 505 ipaddr_string(&op->ospf6_hello.hello_bdr)); 506 if (vflag) { 507 printf("\n\t Neighbor List:"); 508 ap = op->ospf6_hello.hello_neighbor; 509 while ((u_char *)ap < dataend) { 510 TCHECK(*ap); 511 printf("\n\t %s", ipaddr_string(ap)); 512 ++ap; 513 } 514 } 515 break; /* HELLO */ 516 517 case OSPF_TYPE_DD: 518 TCHECK(op->ospf6_db.db_options); 519 printf("\n\tOptions [%s]", 520 bittok2str(ospf6_option_values, "none", 521 EXTRACT_32BITS(&op->ospf6_db.db_options))); 522 TCHECK(op->ospf6_db.db_flags); 523 printf(", DD Flags [%s]", 524 bittok2str(ospf6_dd_flag_values,"none",op->ospf6_db.db_flags)); 525 526 TCHECK(op->ospf6_db.db_seq); 527 printf(", MTU %u, DD-Sequence 0x%08x", 528 EXTRACT_16BITS(&op->ospf6_db.db_mtu), 529 EXTRACT_32BITS(&op->ospf6_db.db_seq)); 530 531 /* Print all the LS adv's */ 532 lshp = op->ospf6_db.db_lshdr; 533 while (!ospf6_print_lshdr(lshp)) { 534 ++lshp; 535 } 536 break; 537 538 case OSPF_TYPE_LS_REQ: 539 if (vflag) { 540 lsrp = op->ospf6_lsr; 541 while ((u_char *)lsrp < dataend) { 542 TCHECK(*lsrp); 543 printf("\n\t Advertising Router %s", 544 ipaddr_string(&lsrp->ls_router)); 545 ospf6_print_ls_type(EXTRACT_16BITS(&lsrp->ls_type), 546 &lsrp->ls_stateid); 547 ++lsrp; 548 } 549 } 550 break; 551 552 case OSPF_TYPE_LS_UPDATE: 553 if (vflag) { 554 lsap = op->ospf6_lsu.lsu_lsa; 555 TCHECK(op->ospf6_lsu.lsu_count); 556 i = EXTRACT_32BITS(&op->ospf6_lsu.lsu_count); 557 while (i--) { 558 if (ospf6_print_lsa(lsap)) 559 goto trunc; 560 lsap = (struct lsa6 *)((u_char *)lsap + 561 EXTRACT_16BITS(&lsap->ls_hdr.ls_length)); 562 } 563 } 564 break; 565 566 567 case OSPF_TYPE_LS_ACK: 568 if (vflag) { 569 lshp = op->ospf6_lsa.lsa_lshdr; 570 571 while (!ospf6_print_lshdr(lshp)) { 572 ++lshp; 573 } 574 } 575 break; 576 577 default: 578 break; 579 } 580 return (0); 581 trunc: 582 return (1); 583 } 584 585 void 586 ospf6_print(register const u_char *bp, register u_int length) 587 { 588 register const struct ospf6hdr *op; 589 register const u_char *dataend; 590 register const char *cp; 591 592 op = (struct ospf6hdr *)bp; 593 594 /* If the type is valid translate it, or just print the type */ 595 /* value. If it's not valid, say so and return */ 596 TCHECK(op->ospf6_type); 597 cp = tok2str(ospf6_type_values, "unknown LS-type", op->ospf6_type); 598 printf("OSPFv%u, %s, length %d", op->ospf6_version, cp, length); 599 if (*cp == 'u') { 600 return; 601 } 602 603 if(!vflag) { /* non verbose - so lets bail out here */ 604 return; 605 } 606 607 TCHECK(op->ospf6_len); 608 if (length != EXTRACT_16BITS(&op->ospf6_len)) { 609 printf(" [len %d]", EXTRACT_16BITS(&op->ospf6_len)); 610 return; 611 } 612 dataend = bp + length; 613 614 /* Print the routerid if it is not the same as the source */ 615 TCHECK(op->ospf6_routerid); 616 printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf6_routerid)); 617 618 TCHECK(op->ospf6_areaid); 619 if (op->ospf6_areaid != 0) 620 printf(", Area %s", ipaddr_string(&op->ospf6_areaid)); 621 else 622 printf(", Backbone Area"); 623 TCHECK(op->ospf6_instanceid); 624 if (op->ospf6_instanceid) 625 printf(", Instance %u", op->ospf6_instanceid); 626 627 /* Do rest according to version. */ 628 switch (op->ospf6_version) { 629 630 case 3: 631 /* ospf version 3 */ 632 if (ospf6_decode_v3(op, dataend)) 633 goto trunc; 634 break; 635 636 default: 637 printf(" ospf [version %d]", op->ospf6_version); 638 break; 639 } /* end switch on version */ 640 641 return; 642 trunc: 643 fputs(tstr, stdout); 644 } 645