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