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