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