1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <stdio.h> 28 #include <ctype.h> 29 #include <string.h> 30 #include <fcntl.h> 31 #include <string.h> 32 #include <sys/types.h> 33 #include <sys/time.h> 34 #include <sys/socket.h> 35 #include <sys/sockio.h> 36 #include <net/if.h> 37 #include <netinet/in_systm.h> 38 #include <netinet/in.h> 39 #include <netinet/ip.h> 40 #include <netinet/if_ether.h> 41 #include <arpa/inet.h> 42 #include "snoop.h" 43 #include "snoop_ospf.h" 44 #include "snoop_ospf6.h" 45 46 extern char *dlc_header; 47 static char *sum_line; 48 extern const struct bits ospf_db_flags_bits[]; 49 extern const struct bits ospf_rla_flag_bits[]; 50 extern const struct bits ospf_option_bits[]; 51 52 const struct bits ospf6_option_bits[] = { 53 { OSPF_OPTION_V6, "V6" }, 54 { OSPF_OPTION_E, "E" }, 55 { OSPF_OPTION_MC, "MC" }, 56 { OSPF_OPTION_N, "N" }, 57 { OSPF_OPTION_R, "R" }, 58 { OSPF_OPTION_DC, "DC" }, 59 { 0, NULL } 60 }; 61 62 /* 63 * return a printable string in dotted-decimal notation 64 * for id. 65 */ 66 static char * 67 print_ipaddr(uint32_t id) 68 { 69 struct in_addr tmp; 70 71 tmp.s_addr = id; 72 return (inet_ntoa(tmp)); 73 } 74 75 static int 76 interpret_ospf6_hello(int flags, struct ospf6hdr *op, int fraglen) 77 { 78 uint32_t *nbr; 79 int j; 80 81 if (fraglen < OSPF6_MIN_HEADER_SIZE + OSPF_MIN_HELLO_HEADER_SIZE) 82 return (-1); /* truncated packet */ 83 84 if (flags & F_SUM) { 85 if (op->ospf6_hello.hello_dr != 0) { 86 (void) sprintf(sum_line, "DR=%s ", 87 print_ipaddr(op->ospf6_hello.hello_dr)); 88 } 89 sum_line += strlen(sum_line); 90 if (op->ospf6_hello.hello_bdr != 0) { 91 (void) sprintf(sum_line, "BDR=%s ", 92 print_ipaddr(op->ospf6_hello.hello_bdr)); 93 } 94 sum_line += strlen(sum_line); 95 j = 0; 96 nbr = op->ospf6_hello.hello_neighbor; 97 while ((uchar_t *)nbr < ((uchar_t *)op + fraglen)) { 98 if ((uchar_t *)nbr + sizeof (struct in_addr) > 99 ((uchar_t *)op + fraglen)) 100 return (-1); /* truncated */ 101 ++nbr; 102 j++; 103 } 104 (void) sprintf(sum_line, "%d nbrs", j); 105 sum_line += strlen(sum_line); 106 107 } 108 if (flags & F_DTAIL) { 109 show_header("OSPF HELLO: ", "Hello Packet", 110 ntohs(op->ospf6_len)); 111 show_space(); 112 (void) snprintf(get_line(0, 0), get_line_remain(), 113 "Options = %s", ospf_print_bits(ospf6_option_bits, 114 op->ospf6_hello.hello6_options)); 115 (void) snprintf(get_line(0, 0), get_line_remain(), 116 "Interface ID = %s", 117 print_ipaddr(op->ospf6_hello.hello_ifid)); 118 (void) snprintf(get_line(0, 0), get_line_remain(), 119 "Hello interval = %d", 120 ntohs(op->ospf6_hello.hello_helloint)); 121 (void) snprintf(get_line(0, 0), get_line_remain(), 122 "Priority = %d", op->ospf6_hello.hello6_priority); 123 (void) snprintf(get_line(0, 0), get_line_remain(), 124 "Dead interval = %u", ntohl(op->ospf6_hello.hello_deadint)); 125 if (op->ospf6_hello.hello_dr != 0) { 126 (void) snprintf(get_line(0, 0), get_line_remain(), 127 "Designated Router = %s", 128 print_ipaddr(op->ospf6_hello.hello_dr)); 129 } 130 if (op->ospf6_hello.hello_bdr != 0) { 131 (void) snprintf(get_line(0, 0), get_line_remain(), 132 "Backup Designated Router = %s", 133 print_ipaddr(op->ospf6_hello.hello_bdr)); 134 } 135 nbr = op->ospf6_hello.hello_neighbor; 136 while ((uchar_t *)nbr < ((uchar_t *)op + fraglen)) { 137 if ((uchar_t *)nbr + sizeof (struct in_addr) > 138 ((uchar_t *)op + fraglen)) 139 return (-1); /* truncated */ 140 (void) snprintf(get_line(0, 0), get_line_remain(), 141 "Neigbor: %s", print_ipaddr(*nbr)); 142 ++nbr; 143 } 144 } 145 return (fraglen); 146 } 147 148 static void 149 ospf6_print_ls_type(int flags, uint_t ls6_type, uint32_t ls6_stateid, 150 uint32_t ls6_router) 151 { 152 char scope[15]; 153 154 if (flags & F_SUM) 155 return; 156 157 switch (ls6_type & LS6_SCOPE_MASK) { 158 case LS6_SCOPE_LINKLOCAL: 159 snprintf(scope, sizeof (scope), "linklocal"); 160 break; 161 case LS6_SCOPE_AREA: 162 snprintf(scope, sizeof (scope), "area"); 163 break; 164 case LS6_SCOPE_AS: 165 snprintf(scope, sizeof (scope), "AS"); 166 break; 167 default: 168 snprintf(scope, sizeof (scope), ""); 169 break; 170 } 171 switch (ls6_type & LS_TYPE_MASK) { 172 case LS_TYPE_ROUTER: 173 if (flags & F_DTAIL) { 174 (void) snprintf(get_line(0, 0), get_line_remain(), 175 "%s Router = %s", scope, print_ipaddr(ls6_router)); 176 } 177 break; 178 case LS_TYPE_NETWORK: 179 if (flags & F_DTAIL) { 180 (void) snprintf(get_line(0, 0), get_line_remain(), 181 "%s Net DR %s IF %s", scope, 182 print_ipaddr(ls6_router), 183 print_ipaddr(ls6_stateid)); 184 } 185 break; 186 case LS_TYPE_INTER_AP: 187 if (flags & F_DTAIL) { 188 (void) snprintf(get_line(0, 0), get_line_remain(), 189 "%s Inter-area-prefix = %s ABR %s", scope, 190 print_ipaddr(ls6_stateid), 191 print_ipaddr(ls6_router)); 192 } 193 break; 194 case LS_TYPE_INTER_AR: 195 if (flags & F_DTAIL) { 196 (void) snprintf(get_line(0, 0), get_line_remain(), 197 "%s Inter-area-router = %s Router %s", scope, 198 print_ipaddr(ls6_router), 199 print_ipaddr(ls6_stateid)); 200 } 201 break; 202 case LS_TYPE_ASE: 203 if (flags & F_DTAIL) { 204 (void) snprintf(get_line(0, 0), get_line_remain(), 205 "%s ASE = %s ASBR %s", scope, 206 print_ipaddr(ls6_stateid), 207 print_ipaddr(ls6_router)); 208 } 209 break; 210 case LS_TYPE_GROUP: 211 if (flags & F_DTAIL) { 212 (void) snprintf(get_line(0, 0), get_line_remain(), 213 "%s group = %s Router %s", scope, 214 print_ipaddr(ls6_stateid), 215 print_ipaddr(ls6_router)); 216 } 217 break; 218 case LS_TYPE_TYPE7: 219 if (flags & F_DTAIL) { 220 (void) snprintf(get_line(0, 0), get_line_remain(), 221 "%s Type 7 = %s Router %s", scope, 222 print_ipaddr(ls6_stateid), 223 print_ipaddr(ls6_router)); 224 } 225 break; 226 case LS_TYPE_LINK: 227 if (flags & F_DTAIL) { 228 (void) snprintf(get_line(0, 0), get_line_remain(), 229 "%s link = %s Router %s", scope, 230 print_ipaddr(ls6_stateid), 231 print_ipaddr(ls6_router)); 232 } 233 break; 234 case LS_TYPE_INTRA_AP: 235 if (flags & F_DTAIL) { 236 (void) snprintf(get_line(0, 0), get_line_remain(), 237 "%s Inter-area-prefix = %s Router %s", scope, 238 print_ipaddr(ls6_stateid), 239 print_ipaddr(ls6_router)); 240 } 241 break; 242 default: 243 if (flags & F_DTAIL) { 244 (void) snprintf(get_line(0, 0), get_line_remain(), 245 "%s Unknown type = 0x%x", ls6_type); 246 } 247 break; 248 } 249 } 250 251 static int 252 ospf6_print_lsaprefix(int flags, struct lsa6_prefix *lpfx) 253 { 254 int k; 255 struct in6_addr prefix; 256 char prefixstr[INET6_ADDRSTRLEN]; 257 258 k = (lpfx->lsa6_plen + 31)/32; 259 if (k * 4 > sizeof (struct in6_addr)) { 260 if (flags & F_SUM) { 261 sprintf(sum_line, "Unknown prefix len %d", 262 lpfx->lsa6_plen); 263 sum_line += strlen(sum_line); 264 } 265 if (flags & F_DTAIL) { 266 (void) snprintf(get_line(0, 0), get_line_remain(), 267 "Unknown prefix len %d", lpfx->lsa6_plen); 268 } 269 } 270 memset((void *)&prefix, 0, sizeof (prefix)); 271 memcpy((void *)&prefix, lpfx->lsa6_pfx, k * 4); 272 (void) inet_ntop(AF_INET6, (char *)&prefix, prefixstr, 273 INET6_ADDRSTRLEN); 274 if (flags & F_SUM) { 275 sprintf(sum_line, "%s/%d", prefixstr, lpfx->lsa6_plen); 276 sum_line += strlen(sum_line); 277 } 278 if (flags & F_DTAIL) { 279 (void) snprintf(get_line(0, 0), get_line_remain(), 280 "%s/%d", prefixstr, lpfx->lsa6_plen); 281 } 282 if (lpfx->lsa6_popt != 0) { 283 if (flags & F_SUM) { 284 sprintf(sum_line, "(opt = %x)", lpfx->lsa6_popt); 285 sum_line += strlen(sum_line); 286 } 287 if (flags & F_DTAIL) { 288 (void) snprintf(get_line(0, 0), get_line_remain(), 289 "(opt = %x)", lpfx->lsa6_popt); 290 } 291 } 292 return (sizeof (*lpfx) - 4 + k * 4); 293 } 294 295 static void 296 interpret_ospf6_lsa_hdr(int flags, struct lsa6_hdr *lsah) 297 { 298 if (flags & F_SUM) 299 return; 300 301 if (flags & F_DTAIL) { 302 (void) snprintf(get_line(0, 0), get_line_remain(), 303 "Sequence = %X ", ntohl(lsah->ls6_seq)); 304 (void) snprintf(get_line(0, 0), get_line_remain(), 305 "Age = %X ", ospf_print_lsa_age(ntohl(lsah->ls6_age))); 306 } 307 308 ospf6_print_ls_type(flags, lsah->ls6_type, lsah->ls6_stateid, 309 lsah->ls6_router); 310 311 } 312 313 #define TRUNC(addr) ((uchar_t *)(addr) > fragend) 314 static int 315 interpret_ospf6_lsa(int flags, struct lsa6 *lsa, uchar_t *fragend) 316 { 317 uchar_t *ls_end; 318 int k, j; 319 struct rla6link *rl; 320 uint32_t *addr; 321 struct lsa6_prefix *lpfx; 322 struct llsa *llsa; 323 char addrstr[INET6_ADDRSTRLEN]; 324 325 interpret_ospf6_lsa_hdr(flags, &lsa->ls6_hdr); 326 327 ls_end = (uchar_t *)lsa + ntohs(lsa->ls6_hdr.ls6_length); 328 329 if (TRUNC(ls_end)) 330 return (-1); 331 332 switch (ntohs(lsa->ls6_hdr.ls6_type)) { 333 334 case LS_TYPE_ROUTER|LS6_SCOPE_AREA: 335 if (TRUNC(&lsa->lsa_un.un_rla.rla6_flags)) 336 return (-1); 337 338 (void) ospf_print_bits(ospf_rla_flag_bits, 339 lsa->lsa_un.un_rla.rla6_flags); 340 341 if (TRUNC(&lsa->lsa_un.un_rla.rla6_options)) 342 return (-1); 343 (void) ospf_print_bits(ospf_option_bits, 344 ntohl(lsa->lsa_un.un_rla.rla6_options)); 345 346 rl = lsa->lsa_un.un_rla.rla_link; 347 if (TRUNC(rl)) 348 return (-1); 349 350 while (rl + sizeof (*rl) <= (struct rla6link *)ls_end) { 351 if (TRUNC((uchar_t *)rl + sizeof (*rl))) 352 return (-1); 353 if (flags & F_SUM) { 354 sprintf(sum_line, "{"); /* } (ctags) */ 355 sum_line += strlen(sum_line); 356 } 357 switch (rl->link_type) { 358 case RLA_TYPE_VIRTUAL: 359 if (flags & F_SUM) { 360 sprintf(sum_line, "virt "); 361 sum_line += strlen(sum_line); 362 } 363 if (flags & F_DTAIL) { 364 (void) snprintf(get_line(0, 0), 365 get_line_remain(), "Virtual Link"); 366 } 367 /* FALLTHROUGH */ 368 case RLA_TYPE_ROUTER: 369 if (flags & F_SUM) { 370 sprintf(sum_line, "nbrid %s", 371 print_ipaddr(rl->link_nrtid)); 372 sum_line += strlen(sum_line); 373 sprintf(sum_line, " nbrif %s", 374 print_ipaddr(rl->link_nifid)); 375 sum_line += strlen(sum_line); 376 sprintf(sum_line, " if %s", 377 print_ipaddr(rl->link_ifid)); 378 sum_line += strlen(sum_line); 379 } 380 if (flags & F_DTAIL) { 381 (void) snprintf(get_line(0, 0), 382 get_line_remain(), "Neighbor = %s", 383 print_ipaddr(rl->link_nrtid)); 384 (void) snprintf(get_line(0, 0), 385 get_line_remain(), 386 "Interface = %s id %s", 387 print_ipaddr(rl->link_nifid), 388 print_ipaddr(rl->link_ifid)); 389 } 390 break; 391 case RLA_TYPE_TRANSIT: 392 if (flags & F_SUM) { 393 sprintf(sum_line, "dr %s", 394 print_ipaddr(rl->link_nrtid)); 395 sum_line += strlen(sum_line); 396 sprintf(sum_line, " drif %s", 397 print_ipaddr(rl->link_nifid)); 398 sum_line += strlen(sum_line); 399 sprintf(sum_line, " if %s", 400 print_ipaddr(rl->link_ifid)); 401 sum_line += strlen(sum_line); 402 } 403 if (flags & F_DTAIL) { 404 (void) snprintf(get_line(0, 0), 405 get_line_remain(), 406 "Designated Router = %s", 407 print_ipaddr(rl->link_nrtid)); 408 (void) snprintf(get_line(0, 0), 409 get_line_remain(), 410 "DR Interface = %s id %s", 411 print_ipaddr(rl->link_nifid), 412 print_ipaddr(rl->link_ifid)); 413 } 414 break; 415 default: 416 if (flags & F_SUM) { 417 sprintf(sum_line, 418 "Unknown link type %d", 419 rl->link_type); 420 sum_line += strlen(sum_line); 421 } 422 if (flags & F_DTAIL) { 423 (void) snprintf(get_line(0, 0), 424 get_line_remain(), 425 "Unknown link type %d", 426 rl->link_type); 427 } 428 429 } 430 if (flags & F_SUM) { 431 sprintf(sum_line, " metric %d", 432 ntohs(rl->link_metric)); 433 sum_line += strlen(sum_line); 434 } 435 if (flags & F_DTAIL) { 436 (void) snprintf(get_line(0, 0), 437 get_line_remain(), " metric = %d", 438 ntohs(rl->link_metric)); 439 } 440 if (flags & F_SUM) { /* { (ctags) */ 441 sprintf(sum_line, " }"); 442 sum_line += strlen(sum_line); 443 } 444 rl++; 445 if ((uchar_t *)rl > fragend) 446 return (-1); /* truncated */ 447 } 448 break; 449 case LS_TYPE_NETWORK | LS6_SCOPE_AREA: 450 451 if (TRUNC(&lsa->lsa_un.un_nla.nla_options)) 452 return (-1); 453 454 (void) ospf_print_bits(ospf6_option_bits, 455 ntohl(lsa->lsa_un.un_nla.nla_options)); 456 457 if (flags & F_SUM) { 458 sprintf(sum_line, " rtrs"); 459 sum_line += strlen(sum_line); 460 } 461 if (flags & F_DTAIL) { 462 snprintf(get_line(0, 0), get_line_remain(), 463 "Routers:"); 464 } 465 addr = lsa->lsa_un.un_nla.nla_router; 466 while ((uchar_t *)addr < ls_end) { 467 if ((uchar_t *)addr + sizeof (struct in_addr) > ls_end) 468 return (-1); /* truncated */ 469 if (flags & F_SUM) { 470 sprintf(sum_line, " %s", print_ipaddr(*addr)); 471 sum_line += strlen(sum_line); 472 } 473 if (flags & F_DTAIL) { 474 snprintf(get_line(0, 0), get_line_remain(), 475 "\t%s", print_ipaddr(*addr)); 476 } 477 ++addr; 478 } 479 break; 480 case LS_TYPE_INTER_AP | LS6_SCOPE_AREA: 481 482 if (TRUNC(&lsa->lsa_un.un_inter_ap.inter_ap_metric)) 483 return (-1); 484 485 if (flags & F_SUM) { 486 sprintf(sum_line, " metric %s", 487 ntohl(lsa->lsa_un.un_inter_ap.inter_ap_metric) & 488 SLA_MASK_METRIC); 489 sum_line += strlen(sum_line); 490 } 491 if (flags & F_DTAIL) { 492 snprintf(get_line(0, 0), get_line_remain(), 493 "Metric = %s", 494 ntohl(lsa->lsa_un.un_inter_ap.inter_ap_metric) & 495 SLA_MASK_METRIC); 496 } 497 lpfx = lsa->lsa_un.un_inter_ap.inter_ap_prefix; 498 if (lpfx > (struct lsa6_prefix *)ls_end) 499 return (-1); 500 while (lpfx + sizeof (*lpfx) <= (struct lsa6_prefix *)ls_end) { 501 k = ospf6_print_lsaprefix(flags, lpfx); 502 lpfx = (struct lsa6_prefix *)(((uchar_t *)lpfx) + k); 503 if (lpfx > (struct lsa6_prefix *)ls_end) 504 return (-1); 505 } 506 break; 507 case LS_TYPE_LINK: 508 llsa = &lsa->lsa_un.un_llsa; 509 if (TRUNC(llsa->llsa_options)) 510 return (-1); 511 ospf_print_bits(ospf6_option_bits, ntohl(llsa->llsa_options)); 512 if (TRUNC(llsa->llsa_nprefix)) 513 return (-1); 514 (void) inet_ntop(AF_INET6, &llsa->llsa_lladdr, 515 addrstr, INET6_ADDRSTRLEN); 516 if (flags & F_SUM) { 517 sprintf(sum_line, " pri %d lladdr %s npref %d", 518 ntohl(llsa->llsa_priority), addrstr, 519 ntohl(llsa->llsa_nprefix)); 520 sum_line += strlen(sum_line); 521 } 522 if (flags & F_DTAIL) { 523 snprintf(get_line(0, 0), get_line_remain(), 524 "Priority %d", ntohl(llsa->llsa_priority)); 525 snprintf(get_line(0, 0), get_line_remain(), 526 "Link Local addr %d", addrstr); 527 snprintf(get_line(0, 0), get_line_remain(), 528 "npref %d", ntohl(llsa->llsa_nprefix)); 529 } 530 lpfx = llsa->llsa_prefix; 531 for (j = 0; j < ntohl(llsa->llsa_nprefix); j++) { 532 if (TRUNC(lpfx)) 533 return (-1); 534 k = ospf6_print_lsaprefix(flags, lpfx); 535 lpfx = (struct lsa6_prefix *)(((uchar_t *)lpfx) + k); 536 } 537 break; 538 539 case LS_TYPE_INTRA_AP | LS6_SCOPE_AREA: 540 if (TRUNC(&lsa->lsa_un.un_intra_ap.intra_ap_rtid)) 541 return (-1); 542 ospf6_print_ls_type(flags, 543 ntohs(lsa->lsa_un.un_intra_ap.intra_ap_lstype), 544 lsa->lsa_un.un_intra_ap.intra_ap_lsid, 545 lsa->lsa_un.un_intra_ap.intra_ap_rtid); 546 if (TRUNC(&lsa->lsa_un.un_intra_ap.intra_ap_nprefix)) 547 return (-1); 548 if (flags & F_SUM) { 549 sprintf(sum_line, " npref %d", 550 ntohs(lsa->lsa_un.un_intra_ap.intra_ap_nprefix)); 551 sum_line += strlen(sum_line); 552 } 553 if (flags & F_DTAIL) { 554 snprintf(get_line(0, 0), get_line_remain(), "NPref %d", 555 ntohs(lsa->lsa_un.un_intra_ap.intra_ap_nprefix)); 556 } 557 558 lpfx = lsa->lsa_un.un_intra_ap.intra_ap_prefix; 559 for (j = 0; 560 j < ntohs(lsa->lsa_un.un_intra_ap.intra_ap_nprefix); j++) { 561 if (TRUNC(lpfx)) 562 return (-1); 563 k = ospf6_print_lsaprefix(flags, lpfx); 564 lpfx = (struct lsa6_prefix *)(((uchar_t *)lpfx) + k); 565 } 566 break; 567 568 default: 569 if (flags & F_SUM) { 570 sprintf(sum_line, " Unknown LSA type (%d)", 571 lsa->ls6_hdr.ls6_type); 572 sum_line += strlen(sum_line); 573 } 574 if (flags & F_DTAIL) { 575 snprintf(get_line(0, 0), get_line_remain(), 576 " Unknown LSA type %d", lsa->ls6_hdr.ls6_type); 577 578 } 579 break; 580 } 581 return (0); 582 } 583 #undef TRUNC 584 int 585 interpret_ospf6(int flags, struct ospf6hdr *ospf, int iplen, int fraglen) 586 { 587 boolean_t trunc = B_FALSE; 588 struct lsa6_hdr *lsah; 589 struct lsr6 *lsr; 590 struct lsa6 *lsa; 591 int nlsa, nlsah; 592 593 if ((fraglen < OSPF6_MIN_HEADER_SIZE) || 594 (fraglen < ntohs(ospf->ospf6_len))) 595 return (fraglen); /* incomplete header */ 596 597 if (ospf->ospf6_version != 3) { 598 if (ospf->ospf6_version == 2) { 599 if (flags & F_DTAIL) 600 snprintf(get_line(0, 0), get_line_remain(), 601 "ospfv2 packet in ipv6 header"); 602 return (interpret_ospf(flags, ospf, iplen, fraglen)); 603 } else { 604 return (fraglen); 605 } 606 } 607 608 if (fraglen > ntohs(ospf->ospf6_len)) 609 fraglen = ntohs(ospf->ospf6_len); 610 611 if (ospf->ospf6_type > OSPF_TYPE_MAX) { 612 if (flags & F_SUM) { 613 (void) sprintf(sum_line, "Unknown OSPF TYPE %d \n", 614 ospf->ospf6_type); 615 sum_line += strlen(sum_line); 616 } 617 if (flags & F_SUM) { 618 show_header("OSPFv3: ", "OSPFv3 Header", fraglen); 619 show_space(); 620 (void) snprintf(get_line(0, 0), get_line_remain(), 621 "Unknown OSPF Type = %d", ospf->ospf6_type); 622 } 623 return (fraglen); 624 } 625 626 if (flags & F_SUM) { 627 sum_line = (char *)get_sum_line(); 628 (void) sprintf(sum_line, "OSPFv3 %s RTRID=%s ", 629 ospf_types[ospf->ospf6_type], 630 print_ipaddr(ospf->ospf6_routerid)); 631 sum_line += strlen(sum_line); 632 (void) sprintf(sum_line, "AREA=%s LEN=%d instance %u ", 633 print_ipaddr(ospf->ospf6_areaid), 634 ntohs((ushort_t)ospf->ospf6_len), ospf->ospf6_instanceid); 635 sum_line += strlen(sum_line); 636 } 637 638 if (flags & F_DTAIL) { 639 show_header("OSPFv3: ", "OSPF Header", fraglen); 640 show_space(); 641 (void) snprintf(get_line(0, 0), get_line_remain(), 642 "Version = %d", ospf->ospf6_version); 643 (void) snprintf(get_line(0, 0), get_line_remain(), 644 "Type = %s", ospf_types[ospf->ospf6_type]); 645 (void) snprintf(get_line(0, 0), get_line_remain(), 646 "Router ID = %s", print_ipaddr(ospf->ospf6_routerid)); 647 (void) snprintf(get_line(0, 0), get_line_remain(), 648 "Area ID = %s", print_ipaddr(ospf->ospf6_areaid)); 649 (void) snprintf(get_line(0, 0), get_line_remain(), 650 "Checksum = 0x%x", ospf->ospf6_chksum); 651 (void) snprintf(get_line(0, 0), get_line_remain(), 652 "Instance = %u", ospf->ospf6_instanceid); 653 } 654 655 switch (ospf->ospf6_type) { 656 case OSPF_TYPE_HELLO: 657 if (interpret_ospf6_hello(flags, ospf, fraglen) < 0) 658 trunc = B_TRUE; 659 break; 660 661 case OSPF_TYPE_DB: 662 if (fraglen < OSPF6_MIN_HEADER_SIZE + 663 OSPF6_MIN_DB_HEADER_SIZE) { 664 trunc = B_TRUE; 665 break; 666 } 667 if (flags & F_SUM) { 668 sprintf(sum_line, " %s %s mtu %u S %X", ospf_print_bits( 669 ospf6_option_bits, 670 ntohl(ospf->ospf6_db.db_options)), 671 ospf_print_bits(ospf_db_flags_bits, 672 ospf->ospf6_db.db_flags), 673 ntohs(ospf->ospf6_db.db_mtu), 674 ntohl(ospf->ospf6_db.db_seq)); 675 sum_line += strlen(sum_line); 676 } 677 if (flags & F_DTAIL) { 678 show_header("OSPF DB: ", "Database Description Packet", 679 fraglen); 680 show_space(); 681 snprintf(get_line(0, 0), get_line_remain(), 682 "Options = %s", ospf_print_bits( 683 ospf6_option_bits, ospf->ospf6_db.db_options)); 684 snprintf(get_line(0, 0), get_line_remain(), 685 "Flags = %s", ospf_print_bits( 686 ospf_db_flags_bits, ospf->ospf6_db.db_flags)); 687 snprintf(get_line(0, 0), get_line_remain(), 688 "MTU = %u", ntohl(ospf->ospf6_db.db_seq)); 689 snprintf(get_line(0, 0), get_line_remain(), 690 "Sequence = 0x%X", ntohl(ospf->ospf6_db.db_seq)); 691 /* Print all the LS advs */ 692 lsah = ospf->ospf6_db.db_lshdr; 693 while ((uchar_t *)lsah < ((uchar_t *)ospf + fraglen)) { 694 if ((uchar_t *)lsah + sizeof (struct lsa6_hdr) > 695 ((uchar_t *)ospf + fraglen)) { 696 trunc = B_TRUE; 697 break; 698 } 699 interpret_ospf6_lsa_hdr(flags, lsah); 700 ++lsah; 701 } 702 } 703 break; 704 705 case OSPF_TYPE_LSR: 706 if (fraglen < OSPF6_MIN_HEADER_SIZE + 707 OSPF_MIN_LSR_HEADER_SIZE) { 708 trunc = B_TRUE; 709 break; 710 } 711 if (flags & F_DTAIL) { 712 show_header("OSPF LSR: ", "Link State Request Packet", 713 fraglen); 714 show_space(); 715 } 716 lsr = ospf->ospf6_lsr; 717 nlsah = 0; 718 while ((uchar_t *)lsr < ((uchar_t *)ospf + fraglen)) { 719 if ((uchar_t *)lsr + sizeof (struct lsr6) > 720 ((uchar_t *)ospf + fraglen)) { 721 trunc = B_TRUE; 722 break; 723 } 724 nlsah++; 725 if (flags & F_DTAIL) { 726 ospf6_print_ls_type(flags, ntohl(lsr->ls_type), 727 lsr->ls_stateid, lsr->ls_router); 728 } 729 ++lsr; 730 } 731 if (flags & F_SUM) { 732 sprintf(sum_line, "%d LSAs", nlsah); 733 sum_line += strlen(sum_line); 734 } 735 break; 736 737 case OSPF_TYPE_LSU: 738 if (fraglen < OSPF6_MIN_HEADER_SIZE + 739 OSPF_MIN_LSU_HEADER_SIZE) { 740 trunc = B_TRUE; 741 break; 742 } 743 if (flags & F_DTAIL) { 744 show_header("OSPF LSU: ", "Link State Update Packet", 745 fraglen); 746 show_space(); 747 } 748 lsa = ospf->ospf6_lsu.lsu_lsa; 749 nlsa = ntohl(ospf->ospf6_lsu.lsu_count); 750 if (flags & F_SUM) { 751 sprintf(sum_line, "%d LSAs", nlsa); 752 sum_line += strlen(sum_line); 753 break; 754 } 755 while (nlsa-- != 0) { 756 uchar_t *fragend = (uchar_t *)ospf + fraglen; 757 if (((uchar_t *)lsa >= fragend) || 758 ((uchar_t *)lsa + sizeof (struct lsa_hdr) > 759 fragend) || 760 ((uchar_t *)lsa + ntohs(lsa->ls6_hdr.ls6_length) > 761 fragend)) { 762 trunc = B_TRUE; 763 break; 764 } 765 766 if (interpret_ospf6_lsa(flags, lsa, fragend) < 0) { 767 trunc = B_TRUE; 768 break; 769 } 770 lsa = (struct lsa6 *)((uchar_t *)lsa + 771 ntohs(lsa->ls6_hdr.ls6_length)); 772 } 773 break; 774 775 case OSPF_TYPE_LSA: 776 if (flags & F_DTAIL) { 777 show_header("OSPF LSA: ", "Link State Ack Packet", 778 fraglen); 779 show_space(); 780 } 781 lsah = ospf->ospf6_lsa.lsa_lshdr; 782 nlsah = 0; 783 while ((uchar_t *)lsah < ((uchar_t *)ospf + fraglen)) { 784 if ((uchar_t *)lsah + sizeof (struct lsa6_hdr) > 785 ((uchar_t *)ospf + fraglen)) { 786 trunc = B_TRUE; 787 break; 788 } 789 nlsah++; 790 if (flags & F_DTAIL) 791 interpret_ospf6_lsa_hdr(flags, lsah); 792 ++lsah; 793 } 794 if (flags & F_SUM) { 795 sprintf(sum_line, "%d LSAs", nlsah); 796 sum_line += strlen(sum_line); 797 } 798 break; 799 800 default: 801 /* NOTREACHED */ 802 break; 803 } 804 if (trunc) { 805 if (flags & F_SUM) 806 sprintf(sum_line, "--truncated"); 807 if (flags & F_DTAIL) 808 snprintf(get_line(0, 0), get_line_remain(), 809 "--truncated"); 810 } 811 812 return (fraglen); 813 } 814