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