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