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