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