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