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 #define NETDISSECT_REWORKED 25 #ifdef HAVE_CONFIG_H 26 #include "config.h" 27 #endif 28 29 #include <tcpdump-stdinc.h> 30 31 #include <string.h> 32 33 #include "interface.h" 34 #include "addrtoname.h" 35 #include "extract.h" 36 37 #include "ospf.h" 38 39 #define OSPF_TYPE_HELLO 1 /* Hello */ 40 #define OSPF_TYPE_DD 2 /* Database Description */ 41 #define OSPF_TYPE_LS_REQ 3 /* Link State Request */ 42 #define OSPF_TYPE_LS_UPDATE 4 /* Link State Update */ 43 #define OSPF_TYPE_LS_ACK 5 /* Link State Ack */ 44 45 /* Options *_options */ 46 #define OSPF6_OPTION_V6 0x01 /* V6 bit: A bit for peeping tom */ 47 #define OSPF6_OPTION_E 0x02 /* E bit: External routes advertised */ 48 #define OSPF6_OPTION_MC 0x04 /* MC bit: Multicast capable */ 49 #define OSPF6_OPTION_N 0x08 /* N bit: For type-7 LSA */ 50 #define OSPF6_OPTION_R 0x10 /* R bit: Router bit */ 51 #define OSPF6_OPTION_DC 0x20 /* DC bit: Demand circuits */ 52 /* The field is actually 24-bit (RFC5340 Section A.2). */ 53 #define OSPF6_OPTION_AF 0x0100 /* AF bit: Multiple address families */ 54 #define OSPF6_OPTION_L 0x0200 /* L bit: Link-local signaling (LLS) */ 55 #define OSPF6_OPTION_AT 0x0400 /* AT bit: Authentication trailer */ 56 57 58 /* db_flags */ 59 #define OSPF6_DB_INIT 0x04 /* */ 60 #define OSPF6_DB_MORE 0x02 61 #define OSPF6_DB_MASTER 0x01 62 #define OSPF6_DB_M6 0x10 /* IPv6 MTU */ 63 64 /* ls_type */ 65 #define LS_TYPE_ROUTER 1 /* router link */ 66 #define LS_TYPE_NETWORK 2 /* network link */ 67 #define LS_TYPE_INTER_AP 3 /* Inter-Area-Prefix */ 68 #define LS_TYPE_INTER_AR 4 /* Inter-Area-Router */ 69 #define LS_TYPE_ASE 5 /* ASE */ 70 #define LS_TYPE_GROUP 6 /* Group membership */ 71 #define LS_TYPE_NSSA 7 /* NSSA */ 72 #define LS_TYPE_LINK 8 /* Link LSA */ 73 #define LS_TYPE_INTRA_AP 9 /* Intra-Area-Prefix */ 74 #define LS_TYPE_INTRA_ATE 10 /* Intra-Area-TE */ 75 #define LS_TYPE_GRACE 11 /* Grace LSA */ 76 #define LS_TYPE_RI 12 /* Router information */ 77 #define LS_TYPE_INTER_ASTE 13 /* Inter-AS-TE */ 78 #define LS_TYPE_L1VPN 14 /* L1VPN */ 79 #define LS_TYPE_MASK 0x1fff 80 81 #define LS_SCOPE_LINKLOCAL 0x0000 82 #define LS_SCOPE_AREA 0x2000 83 #define LS_SCOPE_AS 0x4000 84 #define LS_SCOPE_MASK 0x6000 85 #define LS_SCOPE_U 0x8000 86 87 /* rla_link.link_type */ 88 #define RLA_TYPE_ROUTER 1 /* point-to-point to another router */ 89 #define RLA_TYPE_TRANSIT 2 /* connection to transit network */ 90 #define RLA_TYPE_VIRTUAL 4 /* virtual link */ 91 92 /* rla_flags */ 93 #define RLA_FLAG_B 0x01 94 #define RLA_FLAG_E 0x02 95 #define RLA_FLAG_V 0x04 96 #define RLA_FLAG_W 0x08 97 #define RLA_FLAG_N 0x10 98 99 /* lsa_prefix options */ 100 #define LSA_PREFIX_OPT_NU 0x01 101 #define LSA_PREFIX_OPT_LA 0x02 102 #define LSA_PREFIX_OPT_MC 0x04 103 #define LSA_PREFIX_OPT_P 0x08 104 #define LSA_PREFIX_OPT_DN 0x10 105 106 /* sla_tosmetric breakdown */ 107 #define SLA_MASK_TOS 0x7f000000 108 #define SLA_MASK_METRIC 0x00ffffff 109 #define SLA_SHIFT_TOS 24 110 111 /* asla_metric */ 112 #define ASLA_FLAG_FWDADDR 0x02000000 113 #define ASLA_FLAG_ROUTETAG 0x01000000 114 #define ASLA_MASK_METRIC 0x00ffffff 115 116 /* RFC6506 Section 4.1 */ 117 #define OSPF6_AT_HDRLEN 16U 118 #define OSPF6_AUTH_TYPE_HMAC 0x0001 119 120 typedef uint32_t rtrid_t; 121 122 /* link state advertisement header */ 123 struct lsa6_hdr { 124 uint16_t ls_age; 125 uint16_t ls_type; 126 rtrid_t ls_stateid; 127 rtrid_t ls_router; 128 uint32_t ls_seq; 129 uint16_t ls_chksum; 130 uint16_t ls_length; 131 }; 132 133 /* Length of an IPv6 address, in bytes. */ 134 #define IPV6_ADDR_LEN_BYTES (128/8) 135 136 struct lsa6_prefix { 137 uint8_t lsa_p_len; 138 uint8_t lsa_p_opt; 139 uint16_t lsa_p_metric; 140 uint8_t lsa_p_prefix[IPV6_ADDR_LEN_BYTES]; /* maximum length */ 141 }; 142 143 /* link state advertisement */ 144 struct lsa6 { 145 struct lsa6_hdr ls_hdr; 146 147 /* Link state types */ 148 union { 149 /* Router links advertisements */ 150 struct { 151 union { 152 uint8_t flg; 153 uint32_t opt; 154 } rla_flgandopt; 155 #define rla_flags rla_flgandopt.flg 156 #define rla_options rla_flgandopt.opt 157 struct rlalink6 { 158 uint8_t link_type; 159 uint8_t link_zero[1]; 160 uint16_t link_metric; 161 uint32_t link_ifid; 162 uint32_t link_nifid; 163 rtrid_t link_nrtid; 164 } rla_link[1]; /* may repeat */ 165 } un_rla; 166 167 /* Network links advertisements */ 168 struct { 169 uint32_t nla_options; 170 rtrid_t nla_router[1]; /* may repeat */ 171 } un_nla; 172 173 /* Inter Area Prefix LSA */ 174 struct { 175 uint32_t inter_ap_metric; 176 struct lsa6_prefix inter_ap_prefix[1]; 177 } un_inter_ap; 178 179 /* AS external links advertisements */ 180 struct { 181 uint32_t asla_metric; 182 struct lsa6_prefix asla_prefix[1]; 183 /* some optional fields follow */ 184 } un_asla; 185 186 #if 0 187 /* Summary links advertisements */ 188 struct { 189 struct in_addr sla_mask; 190 uint32_t sla_tosmetric[1]; /* may repeat */ 191 } un_sla; 192 193 /* Multicast group membership */ 194 struct mcla { 195 uint32_t mcla_vtype; 196 struct in_addr mcla_vid; 197 } un_mcla[1]; 198 #endif 199 200 /* Type 7 LSA */ 201 202 /* Link LSA */ 203 struct llsa { 204 union { 205 uint8_t pri; 206 uint32_t opt; 207 } llsa_priandopt; 208 #define llsa_priority llsa_priandopt.pri 209 #define llsa_options llsa_priandopt.opt 210 struct in6_addr llsa_lladdr; 211 uint32_t llsa_nprefix; 212 struct lsa6_prefix llsa_prefix[1]; 213 } un_llsa; 214 215 /* Intra-Area-Prefix */ 216 struct { 217 uint16_t intra_ap_nprefix; 218 uint16_t intra_ap_lstype; 219 rtrid_t intra_ap_lsid; 220 rtrid_t intra_ap_rtid; 221 struct lsa6_prefix intra_ap_prefix[1]; 222 } un_intra_ap; 223 } lsa_un; 224 }; 225 226 /* 227 * the main header 228 */ 229 struct ospf6hdr { 230 uint8_t ospf6_version; 231 uint8_t ospf6_type; 232 uint16_t ospf6_len; 233 rtrid_t ospf6_routerid; 234 rtrid_t ospf6_areaid; 235 uint16_t ospf6_chksum; 236 uint8_t ospf6_instanceid; 237 uint8_t ospf6_rsvd; 238 }; 239 240 /* 241 * The OSPF6 header length is 16 bytes, regardless of how your compiler 242 * might choose to pad the above structure. 243 */ 244 #define OSPF6HDR_LEN 16 245 246 /* Hello packet */ 247 struct hello6 { 248 uint32_t hello_ifid; 249 union { 250 uint8_t pri; 251 uint32_t opt; 252 } hello_priandopt; 253 #define hello_priority hello_priandopt.pri 254 #define hello_options hello_priandopt.opt 255 uint16_t hello_helloint; 256 uint16_t hello_deadint; 257 rtrid_t hello_dr; 258 rtrid_t hello_bdr; 259 rtrid_t hello_neighbor[1]; /* may repeat */ 260 }; 261 262 /* Database Description packet */ 263 struct dd6 { 264 uint32_t db_options; 265 uint16_t db_mtu; 266 uint8_t db_mbz; 267 uint8_t db_flags; 268 uint32_t db_seq; 269 struct lsa6_hdr db_lshdr[1]; /* may repeat */ 270 }; 271 272 /* Link State Request */ 273 struct lsr6 { 274 uint16_t ls_mbz; 275 uint16_t ls_type; 276 rtrid_t ls_stateid; 277 rtrid_t ls_router; 278 }; 279 280 /* Link State Update */ 281 struct lsu6 { 282 uint32_t lsu_count; 283 struct lsa6 lsu_lsa[1]; /* may repeat */ 284 }; 285 286 static const char tstr[] = " [|ospf3]"; 287 288 static const struct tok ospf6_option_values[] = { 289 { OSPF6_OPTION_V6, "V6" }, 290 { OSPF6_OPTION_E, "External" }, 291 { OSPF6_OPTION_MC, "Deprecated" }, 292 { OSPF6_OPTION_N, "NSSA" }, 293 { OSPF6_OPTION_R, "Router" }, 294 { OSPF6_OPTION_DC, "Demand Circuit" }, 295 { OSPF6_OPTION_AF, "AFs Support" }, 296 { OSPF6_OPTION_L, "LLS" }, 297 { OSPF6_OPTION_AT, "Authentication Trailer" }, 298 { 0, NULL } 299 }; 300 301 static const struct tok ospf6_rla_flag_values[] = { 302 { RLA_FLAG_B, "ABR" }, 303 { RLA_FLAG_E, "External" }, 304 { RLA_FLAG_V, "Virtual-Link Endpoint" }, 305 { RLA_FLAG_W, "Wildcard Receiver" }, 306 { RLA_FLAG_N, "NSSA Translator" }, 307 { 0, NULL } 308 }; 309 310 static const struct tok ospf6_asla_flag_values[] = { 311 { ASLA_FLAG_EXTERNAL, "External Type 2" }, 312 { ASLA_FLAG_FWDADDR, "Forwarding" }, 313 { ASLA_FLAG_ROUTETAG, "Tag" }, 314 { 0, NULL } 315 }; 316 317 static const struct tok ospf6_type_values[] = { 318 { OSPF_TYPE_HELLO, "Hello" }, 319 { OSPF_TYPE_DD, "Database Description" }, 320 { OSPF_TYPE_LS_REQ, "LS-Request" }, 321 { OSPF_TYPE_LS_UPDATE, "LS-Update" }, 322 { OSPF_TYPE_LS_ACK, "LS-Ack" }, 323 { 0, NULL } 324 }; 325 326 static const struct tok ospf6_lsa_values[] = { 327 { LS_TYPE_ROUTER, "Router" }, 328 { LS_TYPE_NETWORK, "Network" }, 329 { LS_TYPE_INTER_AP, "Inter-Area Prefix" }, 330 { LS_TYPE_INTER_AR, "Inter-Area Router" }, 331 { LS_TYPE_ASE, "External" }, 332 { LS_TYPE_GROUP, "Deprecated" }, 333 { LS_TYPE_NSSA, "NSSA" }, 334 { LS_TYPE_LINK, "Link" }, 335 { LS_TYPE_INTRA_AP, "Intra-Area Prefix" }, 336 { LS_TYPE_INTRA_ATE, "Intra-Area TE" }, 337 { LS_TYPE_GRACE, "Grace" }, 338 { LS_TYPE_RI, "Router Information" }, 339 { LS_TYPE_INTER_ASTE, "Inter-AS-TE" }, 340 { LS_TYPE_L1VPN, "Layer 1 VPN" }, 341 { 0, NULL } 342 }; 343 344 static const struct tok ospf6_ls_scope_values[] = { 345 { LS_SCOPE_LINKLOCAL, "Link Local" }, 346 { LS_SCOPE_AREA, "Area Local" }, 347 { LS_SCOPE_AS, "Domain Wide" }, 348 { 0, NULL } 349 }; 350 351 static const struct tok ospf6_dd_flag_values[] = { 352 { OSPF6_DB_INIT, "Init" }, 353 { OSPF6_DB_MORE, "More" }, 354 { OSPF6_DB_MASTER, "Master" }, 355 { OSPF6_DB_M6, "IPv6 MTU" }, 356 { 0, NULL } 357 }; 358 359 static const struct tok ospf6_lsa_prefix_option_values[] = { 360 { LSA_PREFIX_OPT_NU, "No Unicast" }, 361 { LSA_PREFIX_OPT_LA, "Local address" }, 362 { LSA_PREFIX_OPT_MC, "Deprecated" }, 363 { LSA_PREFIX_OPT_P, "Propagate" }, 364 { LSA_PREFIX_OPT_DN, "Down" }, 365 { 0, NULL } 366 }; 367 368 static const struct tok ospf6_auth_type_str[] = { 369 { OSPF6_AUTH_TYPE_HMAC, "HMAC" }, 370 { 0, NULL } 371 }; 372 373 static void 374 ospf6_print_ls_type(netdissect_options *ndo, 375 register u_int ls_type, register const rtrid_t *ls_stateid) 376 { 377 ND_PRINT((ndo, "\n\t %s LSA (%d), %s Scope%s, LSA-ID %s", 378 tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK), 379 ls_type & LS_TYPE_MASK, 380 tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK), 381 ls_type &0x8000 ? ", transitive" : "", /* U-bit */ 382 ipaddr_string(ndo, ls_stateid))); 383 } 384 385 static int 386 ospf6_print_lshdr(netdissect_options *ndo, 387 register const struct lsa6_hdr *lshp, const u_char *dataend) 388 { 389 if ((u_char *)(lshp + 1) > dataend) 390 goto trunc; 391 ND_TCHECK(lshp->ls_type); 392 ND_TCHECK(lshp->ls_seq); 393 394 ND_PRINT((ndo, "\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", 395 ipaddr_string(ndo, &lshp->ls_router), 396 EXTRACT_32BITS(&lshp->ls_seq), 397 EXTRACT_16BITS(&lshp->ls_age), 398 EXTRACT_16BITS(&lshp->ls_length)-(u_int)sizeof(struct lsa6_hdr))); 399 400 ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lshp->ls_type), &lshp->ls_stateid); 401 402 return (0); 403 trunc: 404 return (1); 405 } 406 407 static int 408 ospf6_print_lsaprefix(netdissect_options *ndo, 409 const uint8_t *tptr, u_int lsa_length) 410 { 411 const struct lsa6_prefix *lsapp = (struct lsa6_prefix *)tptr; 412 u_int wordlen; 413 struct in6_addr prefix; 414 415 if (lsa_length < sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES) 416 goto trunc; 417 lsa_length -= sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES; 418 ND_TCHECK2(*lsapp, sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES); 419 wordlen = (lsapp->lsa_p_len + 31) / 32; 420 if (wordlen * 4 > sizeof(struct in6_addr)) { 421 ND_PRINT((ndo, " bogus prefixlen /%d", lsapp->lsa_p_len)); 422 goto trunc; 423 } 424 if (lsa_length < wordlen * 4) 425 goto trunc; 426 lsa_length -= wordlen * 4; 427 ND_TCHECK2(lsapp->lsa_p_prefix, wordlen * 4); 428 memset(&prefix, 0, sizeof(prefix)); 429 memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4); 430 ND_PRINT((ndo, "\n\t\t%s/%d", ip6addr_string(ndo, &prefix), 431 lsapp->lsa_p_len)); 432 if (lsapp->lsa_p_opt) { 433 ND_PRINT((ndo, ", Options [%s]", 434 bittok2str(ospf6_lsa_prefix_option_values, 435 "none", lsapp->lsa_p_opt))); 436 } 437 ND_PRINT((ndo, ", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric))); 438 return sizeof(*lsapp) - IPV6_ADDR_LEN_BYTES + wordlen * 4; 439 440 trunc: 441 return -1; 442 } 443 444 445 /* 446 * Print a single link state advertisement. If truncated return 1, else 0. 447 */ 448 static int 449 ospf6_print_lsa(netdissect_options *ndo, 450 register const struct lsa6 *lsap, const u_char *dataend) 451 { 452 register const struct rlalink6 *rlp; 453 #if 0 454 register const struct tos_metric *tosp; 455 #endif 456 register const rtrid_t *ap; 457 #if 0 458 register const struct aslametric *almp; 459 register const struct mcla *mcp; 460 #endif 461 register const struct llsa *llsap; 462 register const struct lsa6_prefix *lsapp; 463 #if 0 464 register const uint32_t *lp; 465 #endif 466 register u_int prefixes; 467 register int bytelen; 468 register u_int length, lsa_length; 469 uint32_t flags32; 470 const uint8_t *tptr; 471 472 if (ospf6_print_lshdr(ndo, &lsap->ls_hdr, dataend)) 473 return (1); 474 ND_TCHECK(lsap->ls_hdr.ls_length); 475 length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length); 476 477 /* 478 * The LSA length includes the length of the header; 479 * it must have a value that's at least that length. 480 * If it does, find the length of what follows the 481 * header. 482 */ 483 if (length < sizeof(struct lsa6_hdr) || (u_char *)lsap + length > dataend) 484 return (1); 485 lsa_length = length - sizeof(struct lsa6_hdr); 486 tptr = (uint8_t *)lsap+sizeof(struct lsa6_hdr); 487 488 switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { 489 case LS_TYPE_ROUTER | LS_SCOPE_AREA: 490 if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options)) 491 return (1); 492 lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options); 493 ND_TCHECK(lsap->lsa_un.un_rla.rla_options); 494 ND_PRINT((ndo, "\n\t Options [%s]", 495 bittok2str(ospf6_option_values, "none", 496 EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options)))); 497 ND_PRINT((ndo, ", RLA-Flags [%s]", 498 bittok2str(ospf6_rla_flag_values, "none", 499 lsap->lsa_un.un_rla.rla_flags))); 500 501 rlp = lsap->lsa_un.un_rla.rla_link; 502 while (lsa_length != 0) { 503 if (lsa_length < sizeof (*rlp)) 504 return (1); 505 lsa_length -= sizeof (*rlp); 506 ND_TCHECK(*rlp); 507 switch (rlp->link_type) { 508 509 case RLA_TYPE_VIRTUAL: 510 ND_PRINT((ndo, "\n\t Virtual Link: Neighbor Router-ID %s" 511 "\n\t Neighbor Interface-ID %s, Interface %s", 512 ipaddr_string(ndo, &rlp->link_nrtid), 513 ipaddr_string(ndo, &rlp->link_nifid), 514 ipaddr_string(ndo, &rlp->link_ifid))); 515 break; 516 517 case RLA_TYPE_ROUTER: 518 ND_PRINT((ndo, "\n\t Neighbor Router-ID %s" 519 "\n\t Neighbor Interface-ID %s, Interface %s", 520 ipaddr_string(ndo, &rlp->link_nrtid), 521 ipaddr_string(ndo, &rlp->link_nifid), 522 ipaddr_string(ndo, &rlp->link_ifid))); 523 break; 524 525 case RLA_TYPE_TRANSIT: 526 ND_PRINT((ndo, "\n\t Neighbor Network-ID %s" 527 "\n\t Neighbor Interface-ID %s, Interface %s", 528 ipaddr_string(ndo, &rlp->link_nrtid), 529 ipaddr_string(ndo, &rlp->link_nifid), 530 ipaddr_string(ndo, &rlp->link_ifid))); 531 break; 532 533 default: 534 ND_PRINT((ndo, "\n\t Unknown Router Links Type 0x%02x", 535 rlp->link_type)); 536 return (0); 537 } 538 ND_PRINT((ndo, ", metric %d", EXTRACT_16BITS(&rlp->link_metric))); 539 rlp++; 540 } 541 break; 542 543 case LS_TYPE_NETWORK | LS_SCOPE_AREA: 544 if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options)) 545 return (1); 546 lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options); 547 ND_TCHECK(lsap->lsa_un.un_nla.nla_options); 548 ND_PRINT((ndo, "\n\t Options [%s]", 549 bittok2str(ospf6_option_values, "none", 550 EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options)))); 551 552 ND_PRINT((ndo, "\n\t Connected Routers:")); 553 ap = lsap->lsa_un.un_nla.nla_router; 554 while (lsa_length != 0) { 555 if (lsa_length < sizeof (*ap)) 556 return (1); 557 lsa_length -= sizeof (*ap); 558 ND_TCHECK(*ap); 559 ND_PRINT((ndo, "\n\t\t%s", ipaddr_string(ndo, ap))); 560 ++ap; 561 } 562 break; 563 564 case LS_TYPE_INTER_AP | LS_SCOPE_AREA: 565 if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric)) 566 return (1); 567 lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric); 568 ND_TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); 569 ND_PRINT((ndo, ", metric %u", 570 EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC)); 571 572 tptr = (uint8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix; 573 while (lsa_length != 0) { 574 bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); 575 if (bytelen < 0) 576 goto trunc; 577 lsa_length -= bytelen; 578 tptr += bytelen; 579 } 580 break; 581 582 case LS_TYPE_ASE | LS_SCOPE_AS: 583 if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric)) 584 return (1); 585 lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric); 586 ND_TCHECK(lsap->lsa_un.un_asla.asla_metric); 587 flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric); 588 ND_PRINT((ndo, "\n\t Flags [%s]", 589 bittok2str(ospf6_asla_flag_values, "none", flags32))); 590 ND_PRINT((ndo, " metric %u", 591 EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & 592 ASLA_MASK_METRIC)); 593 594 tptr = (uint8_t *)lsap->lsa_un.un_asla.asla_prefix; 595 lsapp = (struct lsa6_prefix *)tptr; 596 bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); 597 if (bytelen < 0) 598 goto trunc; 599 lsa_length -= bytelen; 600 tptr += bytelen; 601 602 if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { 603 struct in6_addr *fwdaddr6; 604 605 fwdaddr6 = (struct in6_addr *)tptr; 606 if (lsa_length < sizeof (*fwdaddr6)) 607 return (1); 608 lsa_length -= sizeof (*fwdaddr6); 609 ND_TCHECK(*fwdaddr6); 610 ND_PRINT((ndo, " forward %s", 611 ip6addr_string(ndo, fwdaddr6))); 612 tptr += sizeof(*fwdaddr6); 613 } 614 615 if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { 616 if (lsa_length < sizeof (uint32_t)) 617 return (1); 618 lsa_length -= sizeof (uint32_t); 619 ND_TCHECK(*(uint32_t *)tptr); 620 ND_PRINT((ndo, " tag %s", 621 ipaddr_string(ndo, (uint32_t *)tptr))); 622 tptr += sizeof(uint32_t); 623 } 624 625 if (lsapp->lsa_p_metric) { 626 if (lsa_length < sizeof (uint32_t)) 627 return (1); 628 lsa_length -= sizeof (uint32_t); 629 ND_TCHECK(*(uint32_t *)tptr); 630 ND_PRINT((ndo, " RefLSID: %s", 631 ipaddr_string(ndo, (uint32_t *)tptr))); 632 tptr += sizeof(uint32_t); 633 } 634 break; 635 636 case LS_TYPE_LINK: 637 /* Link LSA */ 638 llsap = &lsap->lsa_un.un_llsa; 639 if (lsa_length < sizeof (llsap->llsa_priandopt)) 640 return (1); 641 lsa_length -= sizeof (llsap->llsa_priandopt); 642 ND_TCHECK(llsap->llsa_priandopt); 643 ND_PRINT((ndo, "\n\t Options [%s]", 644 bittok2str(ospf6_option_values, "none", 645 EXTRACT_32BITS(&llsap->llsa_options)))); 646 647 if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix)) 648 return (1); 649 lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix); 650 prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); 651 ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:", 652 llsap->llsa_priority, 653 ip6addr_string(ndo, &llsap->llsa_lladdr), 654 prefixes)); 655 656 tptr = (uint8_t *)llsap->llsa_prefix; 657 while (prefixes > 0) { 658 bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); 659 if (bytelen < 0) 660 goto trunc; 661 prefixes--; 662 lsa_length -= bytelen; 663 tptr += bytelen; 664 } 665 break; 666 667 case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: 668 /* Intra-Area-Prefix LSA */ 669 if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid)) 670 return (1); 671 lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid); 672 ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); 673 ospf6_print_ls_type(ndo, 674 EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype), 675 &lsap->lsa_un.un_intra_ap.intra_ap_lsid); 676 677 if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix)) 678 return (1); 679 lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 680 ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 681 prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 682 ND_PRINT((ndo, "\n\t Prefixes %d:", prefixes)); 683 684 tptr = (uint8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; 685 while (prefixes > 0) { 686 bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); 687 if (bytelen < 0) 688 goto trunc; 689 prefixes--; 690 lsa_length -= bytelen; 691 tptr += bytelen; 692 } 693 break; 694 695 case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL: 696 if (ospf_print_grace_lsa(ndo, tptr, lsa_length) == -1) { 697 return 1; 698 } 699 break; 700 701 case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL: 702 if (ospf_print_te_lsa(ndo, tptr, lsa_length) == -1) { 703 return 1; 704 } 705 break; 706 707 default: 708 if(!print_unknown_data(ndo,tptr, 709 "\n\t ", 710 lsa_length)) { 711 return (1); 712 } 713 break; 714 } 715 716 return (0); 717 trunc: 718 return (1); 719 } 720 721 static int 722 ospf6_decode_v3(netdissect_options *ndo, 723 register const struct ospf6hdr *op, 724 register const u_char *dataend) 725 { 726 register const rtrid_t *ap; 727 register const struct lsr6 *lsrp; 728 register const struct lsa6_hdr *lshp; 729 register const struct lsa6 *lsap; 730 register int i; 731 732 switch (op->ospf6_type) { 733 734 case OSPF_TYPE_HELLO: { 735 register const struct hello6 *hellop = (const struct hello6 *)((uint8_t *)op + OSPF6HDR_LEN); 736 737 ND_PRINT((ndo, "\n\tOptions [%s]", 738 bittok2str(ospf6_option_values, "none", 739 EXTRACT_32BITS(&hellop->hello_options)))); 740 741 ND_TCHECK(hellop->hello_deadint); 742 ND_PRINT((ndo, "\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u", 743 EXTRACT_16BITS(&hellop->hello_helloint), 744 EXTRACT_16BITS(&hellop->hello_deadint), 745 ipaddr_string(ndo, &hellop->hello_ifid), 746 hellop->hello_priority)); 747 748 ND_TCHECK(hellop->hello_dr); 749 if (EXTRACT_32BITS(&hellop->hello_dr) != 0) 750 ND_PRINT((ndo, "\n\t Designated Router %s", 751 ipaddr_string(ndo, &hellop->hello_dr))); 752 ND_TCHECK(hellop->hello_bdr); 753 if (EXTRACT_32BITS(&hellop->hello_bdr) != 0) 754 ND_PRINT((ndo, ", Backup Designated Router %s", 755 ipaddr_string(ndo, &hellop->hello_bdr))); 756 if (ndo->ndo_vflag > 1) { 757 ND_PRINT((ndo, "\n\t Neighbor List:")); 758 ap = hellop->hello_neighbor; 759 while ((u_char *)ap < dataend) { 760 ND_TCHECK(*ap); 761 ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); 762 ++ap; 763 } 764 } 765 break; /* HELLO */ 766 } 767 768 case OSPF_TYPE_DD: { 769 register const struct dd6 *ddp = (const struct dd6 *)((uint8_t *)op + OSPF6HDR_LEN); 770 771 ND_TCHECK(ddp->db_options); 772 ND_PRINT((ndo, "\n\tOptions [%s]", 773 bittok2str(ospf6_option_values, "none", 774 EXTRACT_32BITS(&ddp->db_options)))); 775 ND_TCHECK(ddp->db_flags); 776 ND_PRINT((ndo, ", DD Flags [%s]", 777 bittok2str(ospf6_dd_flag_values,"none",ddp->db_flags))); 778 779 ND_TCHECK(ddp->db_seq); 780 ND_PRINT((ndo, ", MTU %u, DD-Sequence 0x%08x", 781 EXTRACT_16BITS(&ddp->db_mtu), 782 EXTRACT_32BITS(&ddp->db_seq))); 783 if (ndo->ndo_vflag > 1) { 784 /* Print all the LS adv's */ 785 lshp = ddp->db_lshdr; 786 while ((u_char *)lshp < dataend) { 787 if (ospf6_print_lshdr(ndo, lshp++, dataend)) 788 goto trunc; 789 } 790 } 791 break; 792 } 793 794 case OSPF_TYPE_LS_REQ: 795 if (ndo->ndo_vflag > 1) { 796 lsrp = (const struct lsr6 *)((uint8_t *)op + OSPF6HDR_LEN); 797 while ((u_char *)lsrp < dataend) { 798 ND_TCHECK(*lsrp); 799 ND_PRINT((ndo, "\n\t Advertising Router %s", 800 ipaddr_string(ndo, &lsrp->ls_router))); 801 ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lsrp->ls_type), 802 &lsrp->ls_stateid); 803 ++lsrp; 804 } 805 } 806 break; 807 808 case OSPF_TYPE_LS_UPDATE: 809 if (ndo->ndo_vflag > 1) { 810 register const struct lsu6 *lsup = (const struct lsu6 *)((uint8_t *)op + OSPF6HDR_LEN); 811 812 ND_TCHECK(lsup->lsu_count); 813 i = EXTRACT_32BITS(&lsup->lsu_count); 814 lsap = lsup->lsu_lsa; 815 while ((u_char *)lsap < dataend && i--) { 816 if (ospf6_print_lsa(ndo, lsap, dataend)) 817 goto trunc; 818 lsap = (struct lsa6 *)((u_char *)lsap + 819 EXTRACT_16BITS(&lsap->ls_hdr.ls_length)); 820 } 821 } 822 break; 823 824 case OSPF_TYPE_LS_ACK: 825 if (ndo->ndo_vflag > 1) { 826 lshp = (const struct lsa6_hdr *)((uint8_t *)op + OSPF6HDR_LEN); 827 while ((u_char *)lshp < dataend) { 828 if (ospf6_print_lshdr(ndo, lshp++, dataend)) 829 goto trunc; 830 } 831 } 832 break; 833 834 default: 835 break; 836 } 837 return (0); 838 trunc: 839 return (1); 840 } 841 842 /* RFC5613 Section 2.2 (w/o the TLVs) */ 843 static int 844 ospf6_print_lls(netdissect_options *ndo, 845 const u_char *cp, const u_int len) 846 { 847 uint16_t llsdatalen; 848 849 if (len == 0) 850 return 0; 851 if (len < OSPF_LLS_HDRLEN) 852 goto trunc; 853 /* Checksum */ 854 ND_TCHECK2(*cp, 2); 855 ND_PRINT((ndo, "\n\tLLS Checksum 0x%04x", EXTRACT_16BITS(cp))); 856 cp += 2; 857 /* LLS Data Length */ 858 ND_TCHECK2(*cp, 2); 859 llsdatalen = EXTRACT_16BITS(cp); 860 ND_PRINT((ndo, ", Data Length %u", llsdatalen)); 861 if (llsdatalen < OSPF_LLS_HDRLEN || llsdatalen > len) 862 goto trunc; 863 cp += 2; 864 /* LLS TLVs */ 865 ND_TCHECK2(*cp, llsdatalen - OSPF_LLS_HDRLEN); 866 /* FIXME: code in print-ospf.c can be reused to decode the TLVs */ 867 868 return llsdatalen; 869 trunc: 870 return -1; 871 } 872 873 /* RFC6506 Section 4.1 */ 874 static int 875 ospf6_decode_at(netdissect_options *ndo, 876 const u_char *cp, const u_int len) 877 { 878 uint16_t authdatalen; 879 880 if (len == 0) 881 return 0; 882 if (len < OSPF6_AT_HDRLEN) 883 goto trunc; 884 /* Authentication Type */ 885 ND_TCHECK2(*cp, 2); 886 ND_PRINT((ndo, "\n\tAuthentication Type %s", tok2str(ospf6_auth_type_str, "unknown (0x%04x)", EXTRACT_16BITS(cp)))); 887 cp += 2; 888 /* Auth Data Len */ 889 ND_TCHECK2(*cp, 2); 890 authdatalen = EXTRACT_16BITS(cp); 891 ND_PRINT((ndo, ", Length %u", authdatalen)); 892 if (authdatalen < OSPF6_AT_HDRLEN || authdatalen > len) 893 goto trunc; 894 cp += 2; 895 /* Reserved */ 896 ND_TCHECK2(*cp, 2); 897 cp += 2; 898 /* Security Association ID */ 899 ND_TCHECK2(*cp, 2); 900 ND_PRINT((ndo, ", SAID %u", EXTRACT_16BITS(cp))); 901 cp += 2; 902 /* Cryptographic Sequence Number (High-Order 32 Bits) */ 903 ND_TCHECK2(*cp, 4); 904 ND_PRINT((ndo, ", CSN 0x%08x", EXTRACT_32BITS(cp))); 905 cp += 4; 906 /* Cryptographic Sequence Number (Low-Order 32 Bits) */ 907 ND_TCHECK2(*cp, 4); 908 ND_PRINT((ndo, ":%08x", EXTRACT_32BITS(cp))); 909 cp += 4; 910 /* Authentication Data */ 911 ND_TCHECK2(*cp, authdatalen - OSPF6_AT_HDRLEN); 912 if (ndo->ndo_vflag > 1) 913 print_unknown_data(ndo,cp, "\n\tAuthentication Data ", authdatalen - OSPF6_AT_HDRLEN); 914 return 0; 915 916 trunc: 917 return 1; 918 } 919 920 /* The trailing data may include LLS and/or AT data (in this specific order). 921 * LLS data may be present only in Hello and DBDesc packets with the L-bit set. 922 * AT data may be present in Hello and DBDesc packets with the AT-bit set or in 923 * any other packet type, thus decode the AT data regardless of the AT-bit. 924 */ 925 static int 926 ospf6_decode_v3_trailer(netdissect_options *ndo, 927 const struct ospf6hdr *op, const u_char *cp, const unsigned len) 928 { 929 int llslen = 0; 930 int lls_hello = 0; 931 int lls_dd = 0; 932 933 if (op->ospf6_type == OSPF_TYPE_HELLO) { 934 const struct hello6 *hellop = (const struct hello6 *)((uint8_t *)op + OSPF6HDR_LEN); 935 if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L) 936 lls_hello = 1; 937 } else if (op->ospf6_type == OSPF_TYPE_DD) { 938 const struct dd6 *ddp = (const struct dd6 *)((uint8_t *)op + OSPF6HDR_LEN); 939 if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L) 940 lls_dd = 1; 941 } 942 if ((lls_hello || lls_dd) && (llslen = ospf6_print_lls(ndo, cp, len)) < 0) 943 goto trunc; 944 return ospf6_decode_at(ndo, cp + llslen, len - llslen); 945 946 trunc: 947 return 1; 948 } 949 950 void 951 ospf6_print(netdissect_options *ndo, 952 register const u_char *bp, register u_int length) 953 { 954 register const struct ospf6hdr *op; 955 register const u_char *dataend; 956 register const char *cp; 957 uint16_t datalen; 958 959 op = (struct ospf6hdr *)bp; 960 961 /* If the type is valid translate it, or just print the type */ 962 /* value. If it's not valid, say so and return */ 963 ND_TCHECK(op->ospf6_type); 964 cp = tok2str(ospf6_type_values, "unknown packet type (%u)", op->ospf6_type); 965 ND_PRINT((ndo, "OSPFv%u, %s, length %d", op->ospf6_version, cp, length)); 966 if (*cp == 'u') { 967 return; 968 } 969 970 if(!ndo->ndo_vflag) { /* non verbose - so lets bail out here */ 971 return; 972 } 973 974 /* OSPFv3 data always comes first and optional trailing data may follow. */ 975 ND_TCHECK(op->ospf6_len); 976 datalen = EXTRACT_16BITS(&op->ospf6_len); 977 if (datalen > length) { 978 ND_PRINT((ndo, " [len %d]", datalen)); 979 return; 980 } 981 dataend = bp + datalen; 982 983 ND_TCHECK(op->ospf6_routerid); 984 ND_PRINT((ndo, "\n\tRouter-ID %s", ipaddr_string(ndo, &op->ospf6_routerid))); 985 986 ND_TCHECK(op->ospf6_areaid); 987 if (EXTRACT_32BITS(&op->ospf6_areaid) != 0) 988 ND_PRINT((ndo, ", Area %s", ipaddr_string(ndo, &op->ospf6_areaid))); 989 else 990 ND_PRINT((ndo, ", Backbone Area")); 991 ND_TCHECK(op->ospf6_instanceid); 992 if (op->ospf6_instanceid) 993 ND_PRINT((ndo, ", Instance %u", op->ospf6_instanceid)); 994 995 /* Do rest according to version. */ 996 switch (op->ospf6_version) { 997 998 case 3: 999 /* ospf version 3 */ 1000 if (ospf6_decode_v3(ndo, op, dataend) || 1001 ospf6_decode_v3_trailer(ndo, op, dataend, length - datalen)) 1002 goto trunc; 1003 break; 1004 } /* end switch on version */ 1005 1006 return; 1007 trunc: 1008 ND_PRINT((ndo, "%s", tstr)); 1009 } 1010