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-ospf.c,v 1.66 2007-10-08 07:53:21 hannes 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 37 #include "interface.h" 38 #include "addrtoname.h" 39 #include "extract.h" 40 #include "gmpls.h" 41 42 #include "ospf.h" 43 44 #include "ip.h" 45 46 static struct tok ospf_option_values[] = { 47 { OSPF_OPTION_T, "MultiTopology" }, /* draft-ietf-ospf-mt-09 */ 48 { OSPF_OPTION_E, "External" }, 49 { OSPF_OPTION_MC, "Multicast" }, 50 { OSPF_OPTION_NP, "NSSA" }, 51 { OSPF_OPTION_L, "LLS" }, 52 { OSPF_OPTION_DC, "Demand Circuit" }, 53 { OSPF_OPTION_O, "Opaque" }, 54 { OSPF_OPTION_DN, "Up/Down" }, 55 { 0, NULL } 56 }; 57 58 static struct tok ospf_authtype_values[] = { 59 { OSPF_AUTH_NONE, "none" }, 60 { OSPF_AUTH_SIMPLE, "simple" }, 61 { OSPF_AUTH_MD5, "MD5" }, 62 { 0, NULL } 63 }; 64 65 static struct tok ospf_rla_flag_values[] = { 66 { RLA_FLAG_B, "ABR" }, 67 { RLA_FLAG_E, "ASBR" }, 68 { RLA_FLAG_W1, "Virtual" }, 69 { RLA_FLAG_W2, "W2" }, 70 { 0, NULL } 71 }; 72 73 static struct tok type2str[] = { 74 { OSPF_TYPE_UMD, "UMD" }, 75 { OSPF_TYPE_HELLO, "Hello" }, 76 { OSPF_TYPE_DD, "Database Description" }, 77 { OSPF_TYPE_LS_REQ, "LS-Request" }, 78 { OSPF_TYPE_LS_UPDATE, "LS-Update" }, 79 { OSPF_TYPE_LS_ACK, "LS-Ack" }, 80 { 0, NULL } 81 }; 82 83 static struct tok lsa_values[] = { 84 { LS_TYPE_ROUTER, "Router" }, 85 { LS_TYPE_NETWORK, "Network" }, 86 { LS_TYPE_SUM_IP, "Summary" }, 87 { LS_TYPE_SUM_ABR, "ASBR Summary" }, 88 { LS_TYPE_ASE, "External" }, 89 { LS_TYPE_GROUP, "Multicast Group" }, 90 { LS_TYPE_NSSA, "NSSA" }, 91 { LS_TYPE_OPAQUE_LL, "Link Local Opaque" }, 92 { LS_TYPE_OPAQUE_AL, "Area Local Opaque" }, 93 { LS_TYPE_OPAQUE_DW, "Domain Wide Opaque" }, 94 { 0, NULL } 95 }; 96 97 static struct tok ospf_dd_flag_values[] = { 98 { OSPF_DB_INIT, "Init" }, 99 { OSPF_DB_MORE, "More" }, 100 { OSPF_DB_MASTER, "Master" }, 101 { OSPF_DB_RESYNC, "OOBResync" }, 102 { 0, NULL } 103 }; 104 105 static struct tok lsa_opaque_values[] = { 106 { LS_OPAQUE_TYPE_TE, "Traffic Engineering" }, 107 { LS_OPAQUE_TYPE_GRACE, "Graceful restart" }, 108 { LS_OPAQUE_TYPE_RI, "Router Information" }, 109 { 0, NULL } 110 }; 111 112 static struct tok lsa_opaque_te_tlv_values[] = { 113 { LS_OPAQUE_TE_TLV_ROUTER, "Router Address" }, 114 { LS_OPAQUE_TE_TLV_LINK, "Link" }, 115 { 0, NULL } 116 }; 117 118 static struct tok lsa_opaque_te_link_tlv_subtlv_values[] = { 119 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE, "Link Type" }, 120 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID, "Link ID" }, 121 { LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP, "Local Interface IP address" }, 122 { LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP, "Remote Interface IP address" }, 123 { LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC, "Traffic Engineering Metric" }, 124 { LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW, "Maximum Bandwidth" }, 125 { LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW, "Maximum Reservable Bandwidth" }, 126 { LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW, "Unreserved Bandwidth" }, 127 { LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP, "Administrative Group" }, 128 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, 129 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE, "Link Protection Type" }, 130 { LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, 131 { LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP, "Shared Risk Link Group" }, 132 { LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS, "Bandwidth Constraints" }, 133 { 0, NULL } 134 }; 135 136 static struct tok lsa_opaque_grace_tlv_values[] = { 137 { LS_OPAQUE_GRACE_TLV_PERIOD, "Grace Period" }, 138 { LS_OPAQUE_GRACE_TLV_REASON, "Graceful restart Reason" }, 139 { LS_OPAQUE_GRACE_TLV_INT_ADDRESS, "IPv4 interface address" }, 140 { 0, NULL } 141 }; 142 143 static struct tok lsa_opaque_grace_tlv_reason_values[] = { 144 { LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN, "Unknown" }, 145 { LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART, "Software Restart" }, 146 { LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE, "Software Reload/Upgrade" }, 147 { LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH, "Control Processor Switch" }, 148 { 0, NULL } 149 }; 150 151 static struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = { 152 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" }, 153 { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA, "Multi-Access" }, 154 { 0, NULL } 155 }; 156 157 static struct tok lsa_opaque_ri_tlv_values[] = { 158 { LS_OPAQUE_RI_TLV_CAP, "Router Capabilities" }, 159 { 0, NULL } 160 }; 161 162 static struct tok lsa_opaque_ri_tlv_cap_values[] = { 163 { 1, "Reserved" }, 164 { 2, "Reserved" }, 165 { 4, "Reserved" }, 166 { 8, "Reserved" }, 167 { 16, "graceful restart capable" }, 168 { 32, "graceful restart helper" }, 169 { 64, "Stub router support" }, 170 { 128, "Traffic engineering" }, 171 { 256, "p2p over LAN" }, 172 { 512, "path computation server" }, 173 { 0, NULL } 174 }; 175 176 static struct tok ospf_lls_tlv_values[] = { 177 { OSPF_LLS_EO, "Extended Options" }, 178 { OSPF_LLS_MD5, "MD5 Authentication" }, 179 { 0, NULL } 180 }; 181 182 static struct tok ospf_lls_eo_options[] = { 183 { OSPF_LLS_EO_LR, "LSDB resync" }, 184 { OSPF_LLS_EO_RS, "Restart" }, 185 { 0, NULL } 186 }; 187 188 static char tstr[] = " [|ospf2]"; 189 190 #ifdef WIN32 191 #define inline __inline 192 #endif /* WIN32 */ 193 194 static int ospf_print_lshdr(const struct lsa_hdr *); 195 static const u_char *ospf_print_lsa(const struct lsa *); 196 static int ospf_decode_v2(const struct ospfhdr *, const u_char *); 197 static int ospf_decode_lls(const struct ospfhdr *, register u_int); 198 199 int 200 ospf_print_grace_lsa (const u_int8_t *tptr, u_int ls_length) { 201 202 u_int tlv_type, tlv_length; 203 204 205 while (ls_length > 0) { 206 TCHECK2(*tptr, 4); 207 if (ls_length < 4) { 208 printf("\n\t Remaining LS length %u < 4", ls_length); 209 return -1; 210 } 211 tlv_type = EXTRACT_16BITS(tptr); 212 tlv_length = EXTRACT_16BITS(tptr+2); 213 tptr+=4; 214 ls_length-=4; 215 216 printf("\n\t %s TLV (%u), length %u, value: ", 217 tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type), 218 tlv_type, 219 tlv_length); 220 221 if (tlv_length > ls_length) { 222 printf("\n\t Bogus length %u > %u", tlv_length, 223 ls_length); 224 return -1; 225 } 226 227 /* Infinite loop protection. */ 228 if (tlv_type == 0 || tlv_length ==0) { 229 return -1; 230 } 231 232 TCHECK2(*tptr, tlv_length); 233 switch(tlv_type) { 234 235 case LS_OPAQUE_GRACE_TLV_PERIOD: 236 if (tlv_length != 4) { 237 printf("\n\t Bogus length %u != 4", tlv_length); 238 return -1; 239 } 240 printf("%us",EXTRACT_32BITS(tptr)); 241 break; 242 243 case LS_OPAQUE_GRACE_TLV_REASON: 244 if (tlv_length != 1) { 245 printf("\n\t Bogus length %u != 1", tlv_length); 246 return -1; 247 } 248 printf("%s (%u)", 249 tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr), 250 *tptr); 251 break; 252 253 case LS_OPAQUE_GRACE_TLV_INT_ADDRESS: 254 if (tlv_length != 4) { 255 printf("\n\t Bogus length %u != 4", tlv_length); 256 return -1; 257 } 258 printf("%s", ipaddr_string(tptr)); 259 break; 260 261 default: 262 if (vflag <= 1) { 263 if(!print_unknown_data(tptr,"\n\t ",tlv_length)) 264 return -1; 265 } 266 break; 267 268 } 269 /* in OSPF everything has to be 32-bit aligned, including TLVs */ 270 if (tlv_length%4 != 0) 271 tlv_length+=4-(tlv_length%4); 272 ls_length-=tlv_length; 273 tptr+=tlv_length; 274 } 275 276 return 0; 277 trunc: 278 return -1; 279 } 280 281 int 282 ospf_print_te_lsa (const u_int8_t *tptr, u_int ls_length) { 283 284 u_int tlv_type, tlv_length, subtlv_type, subtlv_length; 285 u_int priority_level, te_class, count_srlg; 286 union { /* int to float conversion buffer for several subTLVs */ 287 float f; 288 u_int32_t i; 289 } bw; 290 291 while (ls_length != 0) { 292 TCHECK2(*tptr, 4); 293 if (ls_length < 4) { 294 printf("\n\t Remaining LS length %u < 4", ls_length); 295 return -1; 296 } 297 tlv_type = EXTRACT_16BITS(tptr); 298 tlv_length = EXTRACT_16BITS(tptr+2); 299 tptr+=4; 300 ls_length-=4; 301 302 printf("\n\t %s TLV (%u), length: %u", 303 tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type), 304 tlv_type, 305 tlv_length); 306 307 if (tlv_length > ls_length) { 308 printf("\n\t Bogus length %u > %u", tlv_length, 309 ls_length); 310 return -1; 311 } 312 313 /* Infinite loop protection. */ 314 if (tlv_type == 0 || tlv_length ==0) { 315 return -1; 316 } 317 318 switch(tlv_type) { 319 case LS_OPAQUE_TE_TLV_LINK: 320 while (tlv_length >= sizeof(subtlv_type) + sizeof(subtlv_length)) { 321 if (tlv_length < 4) { 322 printf("\n\t Remaining TLV length %u < 4", 323 tlv_length); 324 return -1; 325 } 326 TCHECK2(*tptr, 4); 327 subtlv_type = EXTRACT_16BITS(tptr); 328 subtlv_length = EXTRACT_16BITS(tptr+2); 329 tptr+=4; 330 tlv_length-=4; 331 332 printf("\n\t %s subTLV (%u), length: %u", 333 tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type), 334 subtlv_type, 335 subtlv_length); 336 337 TCHECK2(*tptr, subtlv_length); 338 switch(subtlv_type) { 339 case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP: 340 printf(", 0x%08x", EXTRACT_32BITS(tptr)); 341 break; 342 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID: 343 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID: 344 printf(", %s (0x%08x)", 345 ipaddr_string(tptr), 346 EXTRACT_32BITS(tptr)); 347 if (subtlv_length == 8) /* rfc4203 */ 348 printf(", %s (0x%08x)", 349 ipaddr_string(tptr+4), 350 EXTRACT_32BITS(tptr+4)); 351 break; 352 case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP: 353 case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP: 354 printf(", %s", ipaddr_string(tptr)); 355 break; 356 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW: 357 case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW: 358 bw.i = EXTRACT_32BITS(tptr); 359 printf(", %.3f Mbps", bw.f*8/1000000 ); 360 break; 361 case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW: 362 for (te_class = 0; te_class < 8; te_class++) { 363 bw.i = EXTRACT_32BITS(tptr+te_class*4); 364 printf("\n\t\tTE-Class %u: %.3f Mbps", 365 te_class, 366 bw.f*8/1000000 ); 367 } 368 break; 369 case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS: 370 printf("\n\t\tBandwidth Constraints Model ID: %s (%u)", 371 tok2str(diffserv_te_bc_values, "unknown", *tptr), 372 *tptr); 373 /* decode BCs until the subTLV ends */ 374 for (te_class = 0; te_class < (subtlv_length-4)/4; te_class++) { 375 bw.i = EXTRACT_32BITS(tptr+4+te_class*4); 376 printf("\n\t\t Bandwidth constraint CT%u: %.3f Mbps", 377 te_class, 378 bw.f*8/1000000 ); 379 } 380 break; 381 case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC: 382 printf(", Metric %u", EXTRACT_32BITS(tptr)); 383 break; 384 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE: 385 printf(", %s, Priority %u", 386 bittok2str(gmpls_link_prot_values, "none", *tptr), 387 *(tptr+1)); 388 break; 389 case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR: 390 printf("\n\t\tInterface Switching Capability: %s", 391 tok2str(gmpls_switch_cap_values, "Unknown", *(tptr))); 392 printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:", 393 tok2str(gmpls_encoding_values, "Unknown", *(tptr+1))); 394 for (priority_level = 0; priority_level < 8; priority_level++) { 395 bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4)); 396 printf("\n\t\t priority level %d: %.3f Mbps", 397 priority_level, 398 bw.f*8/1000000 ); 399 } 400 break; 401 case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE: 402 printf(", %s (%u)", 403 tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr), 404 *tptr); 405 break; 406 407 case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP: 408 count_srlg = subtlv_length / 4; 409 if (count_srlg != 0) 410 printf("\n\t\t Shared risk group: "); 411 while (count_srlg > 0) { 412 bw.i = EXTRACT_32BITS(tptr); 413 printf("%d",bw.i); 414 tptr+=4; 415 count_srlg--; 416 if (count_srlg > 0) 417 printf(", "); 418 } 419 break; 420 421 default: 422 if (vflag <= 1) { 423 if(!print_unknown_data(tptr,"\n\t\t",subtlv_length)) 424 return -1; 425 } 426 break; 427 } 428 /* in OSPF everything has to be 32-bit aligned, including subTLVs */ 429 if (subtlv_length%4 != 0) 430 subtlv_length+=4-(subtlv_length%4); 431 432 tlv_length-=subtlv_length; 433 tptr+=subtlv_length; 434 435 } 436 break; 437 438 case LS_OPAQUE_TE_TLV_ROUTER: 439 if (tlv_length < 4) { 440 printf("\n\t TLV length %u < 4", tlv_length); 441 return -1; 442 } 443 TCHECK2(*tptr, 4); 444 printf(", %s", ipaddr_string(tptr)); 445 break; 446 447 default: 448 if (vflag <= 1) { 449 if(!print_unknown_data(tptr,"\n\t ",tlv_length)) 450 return -1; 451 } 452 break; 453 } 454 /* in OSPF everything has to be 32-bit aligned, including TLVs */ 455 if (tlv_length%4 != 0) 456 tlv_length+=4-(tlv_length%4); 457 ls_length-=tlv_length; 458 tptr+=tlv_length; 459 } 460 return 0; 461 trunc: 462 return -1; 463 } 464 465 466 static int 467 ospf_print_lshdr(register const struct lsa_hdr *lshp) 468 { 469 u_int ls_length; 470 471 TCHECK(lshp->ls_length); 472 ls_length = EXTRACT_16BITS(&lshp->ls_length); 473 if (ls_length < sizeof(struct lsa_hdr)) { 474 printf("\n\t Bogus length %u < header (%lu)", ls_length, 475 (unsigned long)sizeof(struct lsa_hdr)); 476 return(-1); 477 } 478 479 TCHECK(lshp->ls_seq); /* XXX - ls_length check checked this */ 480 printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", 481 ipaddr_string(&lshp->ls_router), 482 EXTRACT_32BITS(&lshp->ls_seq), 483 EXTRACT_16BITS(&lshp->ls_age), 484 ls_length-(u_int)sizeof(struct lsa_hdr)); 485 486 TCHECK(lshp->ls_type); /* XXX - ls_length check checked this */ 487 switch (lshp->ls_type) { 488 /* the LSA header for opaque LSAs was slightly changed */ 489 case LS_TYPE_OPAQUE_LL: 490 case LS_TYPE_OPAQUE_AL: 491 case LS_TYPE_OPAQUE_DW: 492 printf("\n\t %s LSA (%d), Opaque-Type %s LSA (%u), Opaque-ID %u", 493 tok2str(lsa_values,"unknown",lshp->ls_type), 494 lshp->ls_type, 495 496 tok2str(lsa_opaque_values, 497 "unknown", 498 *(&lshp->un_lsa_id.opaque_field.opaque_type)), 499 *(&lshp->un_lsa_id.opaque_field.opaque_type), 500 EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id) 501 502 ); 503 break; 504 505 /* all other LSA types use regular style LSA headers */ 506 default: 507 printf("\n\t %s LSA (%d), LSA-ID: %s", 508 tok2str(lsa_values,"unknown",lshp->ls_type), 509 lshp->ls_type, 510 ipaddr_string(&lshp->un_lsa_id.lsa_id)); 511 break; 512 } 513 514 TCHECK(lshp->ls_options); /* XXX - ls_length check checked this */ 515 printf("\n\t Options: [%s]", bittok2str(ospf_option_values,"none",lshp->ls_options)); 516 517 return (ls_length); 518 trunc: 519 return (-1); 520 } 521 522 /* draft-ietf-ospf-mt-09 */ 523 static struct tok ospf_topology_values[] = { 524 { 0, "default " }, 525 { 1, "multicast " }, 526 { 2, "management " }, 527 { 0, NULL } 528 }; 529 530 /* 531 * Print all the per-topology metrics. 532 */ 533 static void 534 ospf_print_tos_metrics(const union un_tos *tos) 535 { 536 int metric_count; 537 int toscount; 538 539 toscount = tos->link.link_tos_count+1; 540 metric_count = 0; 541 542 /* 543 * All but the first metric contain a valid topology id. 544 */ 545 while (toscount) { 546 printf("\n\t\ttopology %s(%u), metric %u", 547 tok2str(ospf_topology_values, "", 548 metric_count ? tos->metrics.tos_type : 0), 549 metric_count ? tos->metrics.tos_type : 0, 550 EXTRACT_16BITS(&tos->metrics.tos_metric)); 551 metric_count++; 552 tos++; 553 toscount--; 554 } 555 } 556 557 /* 558 * Print a single link state advertisement. If truncated or if LSA length 559 * field is less than the length of the LSA header, return NULl, else 560 * return pointer to data past end of LSA. 561 */ 562 static const u_int8_t * 563 ospf_print_lsa(register const struct lsa *lsap) 564 { 565 register const u_int8_t *ls_end; 566 register const struct rlalink *rlp; 567 register const struct in_addr *ap; 568 register const struct aslametric *almp; 569 register const struct mcla *mcp; 570 register const u_int32_t *lp; 571 register int j, tlv_type, tlv_length, topology; 572 register int ls_length; 573 const u_int8_t *tptr; 574 575 tptr = (u_int8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */ 576 ls_length = ospf_print_lshdr(&lsap->ls_hdr); 577 if (ls_length == -1) 578 return(NULL); 579 ls_end = (u_int8_t *)lsap + ls_length; 580 ls_length -= sizeof(struct lsa_hdr); 581 582 switch (lsap->ls_hdr.ls_type) { 583 584 case LS_TYPE_ROUTER: 585 TCHECK(lsap->lsa_un.un_rla.rla_flags); 586 printf("\n\t Router LSA Options: [%s]", bittok2str(ospf_rla_flag_values,"none",lsap->lsa_un.un_rla.rla_flags)); 587 588 TCHECK(lsap->lsa_un.un_rla.rla_count); 589 j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count); 590 TCHECK(lsap->lsa_un.un_rla.rla_link); 591 rlp = lsap->lsa_un.un_rla.rla_link; 592 while (j--) { 593 TCHECK(*rlp); 594 switch (rlp->un_tos.link.link_type) { 595 596 case RLA_TYPE_VIRTUAL: 597 printf("\n\t Virtual Link: Neighbor Router-ID: %s, Interface Address: %s", 598 ipaddr_string(&rlp->link_id), 599 ipaddr_string(&rlp->link_data)); 600 break; 601 602 case RLA_TYPE_ROUTER: 603 printf("\n\t Neighbor Router-ID: %s, Interface Address: %s", 604 ipaddr_string(&rlp->link_id), 605 ipaddr_string(&rlp->link_data)); 606 break; 607 608 case RLA_TYPE_TRANSIT: 609 printf("\n\t Neighbor Network-ID: %s, Interface Address: %s", 610 ipaddr_string(&rlp->link_id), 611 ipaddr_string(&rlp->link_data)); 612 break; 613 614 case RLA_TYPE_STUB: 615 printf("\n\t Stub Network: %s, Mask: %s", 616 ipaddr_string(&rlp->link_id), 617 ipaddr_string(&rlp->link_data)); 618 break; 619 620 default: 621 printf("\n\t Unknown Router Link Type (%u)", 622 rlp->un_tos.link.link_type); 623 return (ls_end); 624 } 625 626 ospf_print_tos_metrics(&rlp->un_tos); 627 628 rlp = (struct rlalink *)((u_char *)(rlp + 1) + 629 ((rlp->un_tos.link.link_tos_count) * sizeof(union un_tos))); 630 } 631 break; 632 633 case LS_TYPE_NETWORK: 634 TCHECK(lsap->lsa_un.un_nla.nla_mask); 635 printf("\n\t Mask %s\n\t Connected Routers:", 636 ipaddr_string(&lsap->lsa_un.un_nla.nla_mask)); 637 ap = lsap->lsa_un.un_nla.nla_router; 638 while ((u_char *)ap < ls_end) { 639 TCHECK(*ap); 640 printf("\n\t %s", ipaddr_string(ap)); 641 ++ap; 642 } 643 break; 644 645 case LS_TYPE_SUM_IP: 646 TCHECK(lsap->lsa_un.un_nla.nla_mask); 647 printf("\n\t Mask %s", 648 ipaddr_string(&lsap->lsa_un.un_sla.sla_mask)); 649 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); 650 lp = lsap->lsa_un.un_sla.sla_tosmetric; 651 while ((u_char *)lp < ls_end) { 652 register u_int32_t ul; 653 654 TCHECK(*lp); 655 ul = EXTRACT_32BITS(lp); 656 topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; 657 printf("\n\t\ttopology %s(%u) metric %d", 658 tok2str(ospf_topology_values, "", topology), 659 topology, 660 ul & SLA_MASK_METRIC); 661 ++lp; 662 } 663 break; 664 665 case LS_TYPE_SUM_ABR: 666 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); 667 lp = lsap->lsa_un.un_sla.sla_tosmetric; 668 while ((u_char *)lp < ls_end) { 669 register u_int32_t ul; 670 671 TCHECK(*lp); 672 ul = EXTRACT_32BITS(lp); 673 topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; 674 printf("\n\t\ttopology %s(%u) metric %d", 675 tok2str(ospf_topology_values, "", topology), 676 topology, 677 ul & SLA_MASK_METRIC); 678 ++lp; 679 } 680 break; 681 682 case LS_TYPE_ASE: 683 case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */ 684 TCHECK(lsap->lsa_un.un_nla.nla_mask); 685 printf("\n\t Mask %s", 686 ipaddr_string(&lsap->lsa_un.un_asla.asla_mask)); 687 688 TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); 689 almp = lsap->lsa_un.un_asla.asla_metric; 690 while ((u_char *)almp < ls_end) { 691 register u_int32_t ul; 692 693 TCHECK(almp->asla_tosmetric); 694 ul = EXTRACT_32BITS(&almp->asla_tosmetric); 695 topology = ((ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS); 696 printf("\n\t\ttopology %s(%u), type %d, metric", 697 tok2str(ospf_topology_values, "", topology), 698 topology, 699 (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1); 700 if ((ul & ASLA_MASK_METRIC)==0xffffff) 701 printf(" infinite"); 702 else 703 printf(" %d", (ul & ASLA_MASK_METRIC)); 704 705 TCHECK(almp->asla_forward); 706 if (almp->asla_forward.s_addr) { 707 printf(", forward %s", 708 ipaddr_string(&almp->asla_forward)); 709 } 710 TCHECK(almp->asla_tag); 711 if (almp->asla_tag.s_addr) { 712 printf(", tag %s", 713 ipaddr_string(&almp->asla_tag)); 714 } 715 ++almp; 716 } 717 break; 718 719 case LS_TYPE_GROUP: 720 /* Multicast extensions as of 23 July 1991 */ 721 mcp = lsap->lsa_un.un_mcla; 722 while ((u_char *)mcp < ls_end) { 723 TCHECK(mcp->mcla_vid); 724 switch (EXTRACT_32BITS(&mcp->mcla_vtype)) { 725 726 case MCLA_VERTEX_ROUTER: 727 printf("\n\t Router Router-ID %s", 728 ipaddr_string(&mcp->mcla_vid)); 729 break; 730 731 case MCLA_VERTEX_NETWORK: 732 printf("\n\t Network Designated Router %s", 733 ipaddr_string(&mcp->mcla_vid)); 734 break; 735 736 default: 737 printf("\n\t unknown VertexType (%u)", 738 EXTRACT_32BITS(&mcp->mcla_vtype)); 739 break; 740 } 741 ++mcp; 742 } 743 break; 744 745 case LS_TYPE_OPAQUE_LL: /* fall through */ 746 case LS_TYPE_OPAQUE_AL: 747 case LS_TYPE_OPAQUE_DW: 748 749 switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) { 750 case LS_OPAQUE_TYPE_RI: 751 tptr = (u_int8_t *)(&lsap->lsa_un.un_ri_tlv.type); 752 753 while (ls_length != 0) { 754 TCHECK2(*tptr, 4); 755 if (ls_length < 4) { 756 printf("\n\t Remaining LS length %u < 4", ls_length); 757 return(ls_end); 758 } 759 tlv_type = EXTRACT_16BITS(tptr); 760 tlv_length = EXTRACT_16BITS(tptr+2); 761 tptr+=4; 762 ls_length-=4; 763 764 printf("\n\t %s TLV (%u), length: %u, value: ", 765 tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type), 766 tlv_type, 767 tlv_length); 768 769 if (tlv_length > ls_length) { 770 printf("\n\t Bogus length %u > %u", tlv_length, 771 ls_length); 772 return(ls_end); 773 } 774 TCHECK2(*tptr, tlv_length); 775 switch(tlv_type) { 776 777 case LS_OPAQUE_RI_TLV_CAP: 778 if (tlv_length != 4) { 779 printf("\n\t Bogus length %u != 4", tlv_length); 780 return(ls_end); 781 } 782 printf("Capabilities: %s", 783 bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr))); 784 break; 785 default: 786 if (vflag <= 1) { 787 if(!print_unknown_data(tptr,"\n\t ",tlv_length)) 788 return(ls_end); 789 } 790 break; 791 792 } 793 tptr+=tlv_length; 794 ls_length-=tlv_length; 795 } 796 break; 797 798 case LS_OPAQUE_TYPE_GRACE: 799 if (ospf_print_grace_lsa((u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type), 800 ls_length) == -1) { 801 return(ls_end); 802 } 803 break; 804 805 case LS_OPAQUE_TYPE_TE: 806 if (ospf_print_te_lsa((u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type), 807 ls_length) == -1) { 808 return(ls_end); 809 } 810 break; 811 812 default: 813 if (vflag <= 1) { 814 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown, 815 "\n\t ", ls_length)) 816 return(ls_end); 817 } 818 break; 819 } 820 } 821 822 /* do we want to see an additionally hexdump ? */ 823 if (vflag> 1) 824 if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown, 825 "\n\t ", ls_length)) { 826 return(ls_end); 827 } 828 829 return (ls_end); 830 trunc: 831 return (NULL); 832 } 833 834 static int 835 ospf_decode_lls(register const struct ospfhdr *op, 836 register u_int length) 837 { 838 register const u_char *dptr; 839 register const u_char *dataend; 840 register u_int length2; 841 register u_int16_t lls_type, lls_len; 842 register u_int32_t lls_flags; 843 844 switch (op->ospf_type) { 845 846 case OSPF_TYPE_HELLO: 847 if (!(op->ospf_hello.hello_options & OSPF_OPTION_L)) 848 return (0); 849 break; 850 851 case OSPF_TYPE_DD: 852 if (!(op->ospf_db.db_options & OSPF_OPTION_L)) 853 return (0); 854 break; 855 856 default: 857 return (0); 858 } 859 860 /* dig deeper if LLS data is available; see RFC4813 */ 861 length2 = EXTRACT_16BITS(&op->ospf_len); 862 dptr = (u_char *)op + length2; 863 dataend = (u_char *)op + length; 864 865 if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { 866 dptr = dptr + op->ospf_authdata[3]; 867 length2 += op->ospf_authdata[3]; 868 } 869 if (length2 >= length) { 870 printf("\n\t[LLS truncated]"); 871 return (1); 872 } 873 TCHECK2(*dptr, 2); 874 printf("\n\t LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr)); 875 876 dptr += 2; 877 TCHECK2(*dptr, 2); 878 length2 = EXTRACT_16BITS(dptr); 879 printf(", length: %u", length2); 880 881 dptr += 2; 882 TCHECK(*dptr); 883 while (dptr < dataend) { 884 TCHECK2(*dptr, 2); 885 lls_type = EXTRACT_16BITS(dptr); 886 printf("\n\t %s (%u)", 887 tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type), 888 lls_type); 889 dptr += 2; 890 TCHECK2(*dptr, 2); 891 lls_len = EXTRACT_16BITS(dptr); 892 printf(", length: %u", lls_len); 893 dptr += 2; 894 switch (lls_type) { 895 896 case OSPF_LLS_EO: 897 if (lls_len != 4) { 898 printf(" [should be 4]"); 899 lls_len = 4; 900 } 901 TCHECK2(*dptr, 4); 902 lls_flags = EXTRACT_32BITS(dptr); 903 printf("\n\t Options: 0x%08x [%s]", lls_flags, 904 bittok2str(ospf_lls_eo_options,"?",lls_flags)); 905 906 break; 907 908 case OSPF_LLS_MD5: 909 if (lls_len != 20) { 910 printf(" [should be 20]"); 911 lls_len = 20; 912 } 913 TCHECK2(*dptr, 4); 914 printf("\n\t Sequence number: 0x%08x", EXTRACT_32BITS(dptr)); 915 break; 916 } 917 918 dptr += lls_len; 919 } 920 921 return (0); 922 trunc: 923 return (1); 924 } 925 926 static int 927 ospf_decode_v2(register const struct ospfhdr *op, 928 register const u_char *dataend) 929 { 930 register const struct in_addr *ap; 931 register const struct lsr *lsrp; 932 register const struct lsa_hdr *lshp; 933 register const struct lsa *lsap; 934 register u_int32_t lsa_count,lsa_count_max; 935 936 switch (op->ospf_type) { 937 938 case OSPF_TYPE_UMD: 939 /* 940 * Rob Coltun's special monitoring packets; 941 * do nothing 942 */ 943 break; 944 945 case OSPF_TYPE_HELLO: 946 printf("\n\tOptions [%s]", 947 bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options)); 948 949 TCHECK(op->ospf_hello.hello_deadint); 950 printf("\n\t Hello Timer %us, Dead Timer %us, Mask %s, Priority %u", 951 EXTRACT_16BITS(&op->ospf_hello.hello_helloint), 952 EXTRACT_32BITS(&op->ospf_hello.hello_deadint), 953 ipaddr_string(&op->ospf_hello.hello_mask), 954 op->ospf_hello.hello_priority); 955 956 TCHECK(op->ospf_hello.hello_dr); 957 if (op->ospf_hello.hello_dr.s_addr != 0) 958 printf("\n\t Designated Router %s", 959 ipaddr_string(&op->ospf_hello.hello_dr)); 960 961 TCHECK(op->ospf_hello.hello_bdr); 962 if (op->ospf_hello.hello_bdr.s_addr != 0) 963 printf(", Backup Designated Router %s", 964 ipaddr_string(&op->ospf_hello.hello_bdr)); 965 966 ap = op->ospf_hello.hello_neighbor; 967 if ((u_char *)ap < dataend) 968 printf("\n\t Neighbor List:"); 969 while ((u_char *)ap < dataend) { 970 TCHECK(*ap); 971 printf("\n\t %s", ipaddr_string(ap)); 972 ++ap; 973 } 974 break; /* HELLO */ 975 976 case OSPF_TYPE_DD: 977 TCHECK(op->ospf_db.db_options); 978 printf("\n\tOptions [%s]", 979 bittok2str(ospf_option_values,"none",op->ospf_db.db_options)); 980 TCHECK(op->ospf_db.db_flags); 981 printf(", DD Flags [%s]", 982 bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags)); 983 TCHECK(op->ospf_db.db_ifmtu); 984 if (op->ospf_db.db_ifmtu) { 985 printf(", MTU: %u", EXTRACT_16BITS(&op->ospf_db.db_ifmtu)); 986 } 987 TCHECK(op->ospf_db.db_seq); 988 printf(", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq)); 989 990 /* Print all the LS adv's */ 991 lshp = op->ospf_db.db_lshdr; 992 while (((u_char *)lshp < dataend) && ospf_print_lshdr(lshp) != -1) { 993 ++lshp; 994 } 995 break; 996 997 case OSPF_TYPE_LS_REQ: 998 lsrp = op->ospf_lsr; 999 while ((u_char *)lsrp < dataend) { 1000 TCHECK(*lsrp); 1001 1002 printf("\n\t Advertising Router: %s, %s LSA (%u)", 1003 ipaddr_string(&lsrp->ls_router), 1004 tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)), 1005 EXTRACT_32BITS(&lsrp->ls_type)); 1006 1007 switch (EXTRACT_32BITS(lsrp->ls_type)) { 1008 /* the LSA header for opaque LSAs was slightly changed */ 1009 case LS_TYPE_OPAQUE_LL: 1010 case LS_TYPE_OPAQUE_AL: 1011 case LS_TYPE_OPAQUE_DW: 1012 printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u", 1013 tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type), 1014 lsrp->un_ls_stateid.opaque_field.opaque_type, 1015 EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id)); 1016 break; 1017 default: 1018 printf(", LSA-ID: %s", 1019 ipaddr_string(&lsrp->un_ls_stateid.ls_stateid)); 1020 break; 1021 } 1022 1023 ++lsrp; 1024 } 1025 break; 1026 1027 case OSPF_TYPE_LS_UPDATE: 1028 lsap = op->ospf_lsu.lsu_lsa; 1029 TCHECK(op->ospf_lsu.lsu_count); 1030 lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count); 1031 printf(", %d LSA%s",lsa_count_max, PLURAL_SUFFIX(lsa_count_max)); 1032 for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) { 1033 printf("\n\t LSA #%u",lsa_count); 1034 lsap = (const struct lsa *)ospf_print_lsa(lsap); 1035 if (lsap == NULL) 1036 goto trunc; 1037 } 1038 break; 1039 1040 case OSPF_TYPE_LS_ACK: 1041 lshp = op->ospf_lsa.lsa_lshdr; 1042 while (ospf_print_lshdr(lshp) != -1) { 1043 ++lshp; 1044 } 1045 break; 1046 1047 default: 1048 break; 1049 } 1050 return (0); 1051 trunc: 1052 return (1); 1053 } 1054 1055 void 1056 ospf_print(register const u_char *bp, register u_int length, 1057 const u_char *bp2 _U_) 1058 { 1059 register const struct ospfhdr *op; 1060 register const u_char *dataend; 1061 register const char *cp; 1062 1063 op = (struct ospfhdr *)bp; 1064 1065 /* XXX Before we do anything else, strip off the MD5 trailer */ 1066 TCHECK(op->ospf_authtype); 1067 if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { 1068 length -= OSPF_AUTH_MD5_LEN; 1069 snapend -= OSPF_AUTH_MD5_LEN; 1070 } 1071 1072 /* If the type is valid translate it, or just print the type */ 1073 /* value. If it's not valid, say so and return */ 1074 TCHECK(op->ospf_type); 1075 cp = tok2str(type2str, "unknown LS-type", op->ospf_type); 1076 printf("OSPFv%u, %s, length %u", 1077 op->ospf_version, 1078 cp, 1079 length); 1080 if (*cp == 'u') 1081 return; 1082 1083 if(!vflag) { /* non verbose - so lets bail out here */ 1084 return; 1085 } 1086 1087 TCHECK(op->ospf_len); 1088 if (length != EXTRACT_16BITS(&op->ospf_len)) { 1089 printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len)); 1090 } 1091 1092 if (length > EXTRACT_16BITS(&op->ospf_len)) { 1093 dataend = bp + EXTRACT_16BITS(&op->ospf_len); 1094 } else { 1095 dataend = bp + length; 1096 } 1097 1098 TCHECK(op->ospf_routerid); 1099 printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf_routerid)); 1100 1101 TCHECK(op->ospf_areaid); 1102 if (op->ospf_areaid.s_addr != 0) 1103 printf(", Area %s", ipaddr_string(&op->ospf_areaid)); 1104 else 1105 printf(", Backbone Area"); 1106 1107 if (vflag) { 1108 /* Print authentication data (should we really do this?) */ 1109 TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata)); 1110 1111 printf(", Authentication Type: %s (%u)", 1112 tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)), 1113 EXTRACT_16BITS(&op->ospf_authtype)); 1114 1115 switch (EXTRACT_16BITS(&op->ospf_authtype)) { 1116 1117 case OSPF_AUTH_NONE: 1118 break; 1119 1120 case OSPF_AUTH_SIMPLE: 1121 printf("\n\tSimple text password: "); 1122 safeputs((const char *)op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN); 1123 break; 1124 1125 case OSPF_AUTH_MD5: 1126 printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x", 1127 *((op->ospf_authdata)+2), 1128 *((op->ospf_authdata)+3), 1129 EXTRACT_32BITS((op->ospf_authdata)+4)); 1130 break; 1131 1132 default: 1133 return; 1134 } 1135 } 1136 /* Do rest according to version. */ 1137 switch (op->ospf_version) { 1138 1139 case 2: 1140 /* ospf version 2 */ 1141 if (ospf_decode_v2(op, dataend)) 1142 goto trunc; 1143 if (length > EXTRACT_16BITS(&op->ospf_len)) { 1144 if (ospf_decode_lls(op, length)) 1145 goto trunc; 1146 } 1147 break; 1148 1149 default: 1150 printf(" ospf [version %d]", op->ospf_version); 1151 break; 1152 } /* end switch on version */ 1153 1154 return; 1155 trunc: 1156 fputs(tstr, stdout); 1157 } 1158