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 51 char *ospf_types[] = { 52 "umd", /* 0 */ 53 "Hello", /* 1 */ 54 "DD", /* 2 */ 55 "LSReq", /* 3 */ 56 "LSUpd", /* 4 */ 57 "LSAck", /* 5 */ 58 }; 59 60 static char *ospf_authtypes[] = { 61 "None", /* 0 */ 62 "simple", /* 1 */ 63 "md5", /* 2 */ 64 }; 65 66 const struct bits ospf_rla_flag_bits[] = { 67 { RLA_FLAG_B, "B" }, 68 { RLA_FLAG_E, "E" }, 69 { RLA_FLAG_V, "V" }, 70 { RLA_FLAG_W, "W" }, 71 { 0, NULL } 72 }; 73 74 const struct bits ospf_db_flags_bits[] = { 75 { OSPF_DB_INIT, "I" }, 76 { OSPF_DB_MORE, "M" }, 77 { OSPF_DB_MASTER, "MS" }, 78 { 0, NULL } 79 }; 80 81 const struct bits ospf_option_bits[] = { 82 { OSPF_OPTION_T, "T" }, 83 { OSPF_OPTION_E, "E" }, 84 { OSPF_OPTION_MC, "MC" }, 85 { 0, NULL } 86 }; 87 88 static int interpret_ospf_hello(int, struct ospfhdr *, int); 89 static void ospf_print_ls_type(int, uint32_t, struct in_addr, struct in_addr); 90 static void interpret_ospf_lsa_hdr(int, struct lsa_hdr *); 91 static int interpret_ospf_lsa(int flags, struct lsa *lsa, uchar_t *); 92 93 char * 94 ospf_print_bits(const struct bits *bp, uchar_t options) 95 { 96 static char bitstring[32]; 97 98 bitstring[0] = '\0'; 99 do { 100 if (options & bp->bit) { 101 strcat(bitstring, bp->str); 102 strcat(bitstring, "/"); 103 } 104 } while ((++bp)->bit); 105 106 /* wipe out the trailing "/" */ 107 bitstring[strlen(bitstring) - 1] = '\0'; 108 return (bitstring); 109 } 110 111 char * 112 ospf_print_lsa_age(long age) 113 { 114 long sec, mins, hour; 115 static char lsa_age[16]; 116 117 sec = age % 60; 118 mins = (age / 60) % 60; 119 hour = age / 3600; 120 if (hour != 0) 121 snprintf(lsa_age, sizeof (lsa_age), "%u:%02u:%02u", 122 hour, mins, sec); 123 else if (mins != 0) 124 snprintf(lsa_age, sizeof (lsa_age), "%u:%02u", mins, sec); 125 else 126 snprintf(lsa_age, sizeof (lsa_age), "%u", sec); 127 return (lsa_age); 128 } 129 130 static int 131 interpret_ospf_hello(int flags, struct ospfhdr *op, int fraglen) 132 { 133 struct in_addr *nbr; 134 int j; 135 136 if (fraglen < OSPF_MIN_HEADER_SIZE + OSPF_MIN_HELLO_HEADER_SIZE) 137 return (-1); /* truncated packet */ 138 139 if (flags & F_SUM) { 140 if (op->ospf_hello.hello_dr.s_addr != 0) { 141 (void) sprintf(sum_line, "DR=%s ", 142 inet_ntoa(op->ospf_hello.hello_dr)); 143 } 144 sum_line += strlen(sum_line); 145 if (op->ospf_hello.hello_bdr.s_addr != 0) { 146 (void) sprintf(sum_line, "BDR=%s ", 147 inet_ntoa(op->ospf_hello.hello_bdr)); 148 } 149 sum_line += strlen(sum_line); 150 nbr = op->ospf_hello.hello_neighbor; 151 j = 0; 152 while ((uchar_t *)nbr < ((uchar_t *)op + fraglen)) { 153 if ((uchar_t *)nbr + sizeof (struct in_addr) > 154 ((uchar_t *)op + fraglen)) 155 return (-1); /* truncated */ 156 j++; 157 ++nbr; 158 } 159 (void) sprintf(sum_line, "%d nbrs", j); 160 sum_line += strlen(sum_line); 161 162 } 163 if (flags & F_DTAIL) { 164 show_header("OSPF HELLO: ", "Hello Packet", 165 ntohs(op->ospf_len)); 166 show_space(); 167 (void) snprintf(get_line(0, 0), get_line_remain(), 168 "Options = %s", ospf_print_bits(ospf_option_bits, 169 op->ospf_hello.hello_options)); 170 (void) snprintf(get_line(0, 0), get_line_remain(), "Mask = %s", 171 inet_ntoa(op->ospf_hello.hello_mask)); 172 (void) snprintf(get_line(0, 0), get_line_remain(), 173 "Hello interval = %d", 174 ntohs(op->ospf_hello.hello_helloint)); 175 (void) snprintf(get_line(0, 0), get_line_remain(), 176 "Priority = %d", op->ospf_hello.hello_priority); 177 (void) snprintf(get_line(0, 0), get_line_remain(), 178 "Dead interval = %u", ntohl(op->ospf_hello.hello_deadint)); 179 if (op->ospf_hello.hello_dr.s_addr != 0) { 180 (void) snprintf(get_line(0, 0), get_line_remain(), 181 "Designated Router = %s", 182 inet_ntoa(op->ospf_hello.hello_dr)); 183 } 184 if (op->ospf_hello.hello_bdr.s_addr != 0) { 185 (void) snprintf(get_line(0, 0), get_line_remain(), 186 "Backup Designated Router = %s", 187 inet_ntoa(op->ospf_hello.hello_bdr)); 188 } 189 nbr = op->ospf_hello.hello_neighbor; 190 while ((uchar_t *)nbr < ((uchar_t *)op + fraglen)) { 191 if ((uchar_t *)nbr + sizeof (struct in_addr) > 192 ((uchar_t *)op + fraglen)) 193 return (-1); /* truncated */ 194 (void) snprintf(get_line(0, 0), get_line_remain(), 195 "Neighbor: %s", inet_ntoa(*nbr)); 196 ++nbr; 197 } 198 } 199 return (fraglen); 200 } 201 202 static void 203 ospf_print_ls_type(int flags, uint32_t ls_type, struct in_addr ls_stateid, 204 struct in_addr ls_router) 205 { 206 switch (ls_type) { 207 case LS_TYPE_ROUTER: 208 if (flags & F_SUM) { 209 sprintf(sum_line, " rtr %s ", inet_ntoa(ls_router)); 210 sum_line += strlen(sum_line); 211 } 212 if (flags & F_DTAIL) { 213 (void) snprintf(get_line(0, 0), get_line_remain(), 214 "Router LSA; Router = %s ", inet_ntoa(ls_router)); 215 } 216 break; 217 case LS_TYPE_NETWORK: 218 if (flags & F_SUM) { 219 sprintf(sum_line, " net dr %s ", inet_ntoa(ls_router)); 220 sum_line += strlen(sum_line); 221 sprintf(sum_line, "if %s ", inet_ntoa(ls_stateid)); 222 sum_line += strlen(sum_line); 223 } 224 if (flags & F_DTAIL) { 225 (void) snprintf(get_line(0, 0), get_line_remain(), 226 "Network LSA Router = %s ", inet_ntoa(ls_router)); 227 (void) snprintf(get_line(0, 0), get_line_remain(), 228 " Interface = %s ", 229 inet_ntoa(ls_stateid)); 230 } 231 break; 232 case LS_TYPE_SUM_IP: 233 if (flags & F_SUM) { 234 sprintf(sum_line, " sum %s ", inet_ntoa(ls_stateid)); 235 sum_line += strlen(sum_line); 236 sprintf(sum_line, "abr %s ", inet_ntoa(ls_router)); 237 sum_line += strlen(sum_line); 238 } 239 if (flags & F_DTAIL) { 240 (void) snprintf(get_line(0, 0), get_line_remain(), 241 "Summary LSA IP = %s ", inet_ntoa(ls_stateid)); 242 (void) snprintf(get_line(0, 0), get_line_remain(), 243 " Area Border Router = %s ", 244 inet_ntoa(ls_router)); 245 } 246 break; 247 case LS_TYPE_SUM_ABR: 248 if (flags & F_SUM) { 249 sprintf(sum_line, "abr %s ", inet_ntoa(ls_stateid)); 250 sum_line += strlen(sum_line); 251 sprintf(sum_line, "asbr %s ", inet_ntoa(ls_router)); 252 sum_line += strlen(sum_line); 253 } 254 if (flags & F_DTAIL) { 255 (void) snprintf(get_line(0, 0), get_line_remain(), 256 "ASBR Summary abr = %s ", inet_ntoa(ls_stateid)); 257 (void) snprintf(get_line(0, 0), get_line_remain(), 258 " asbr = %s ", inet_ntoa(ls_router)); 259 } 260 break; 261 case LS_TYPE_ASE: 262 if (flags & F_SUM) { 263 sprintf(sum_line, " ase %s", inet_ntoa(ls_stateid)); 264 sum_line += strlen(sum_line); 265 sprintf(sum_line, " asbr %s", inet_ntoa(ls_router)); 266 sum_line += strlen(sum_line); 267 } 268 if (flags & F_DTAIL) { 269 (void) snprintf(get_line(0, 0), get_line_remain(), 270 "AS External LSA ase = %s ", inet_ntoa(ls_stateid)); 271 (void) snprintf(get_line(0, 0), get_line_remain(), 272 " asbr = %s ", inet_ntoa(ls_router)); 273 } 274 275 break; 276 case LS_TYPE_GROUP: 277 if (flags & F_SUM) { 278 sprintf(sum_line, " group %s", inet_ntoa(ls_stateid)); 279 sum_line += strlen(sum_line); 280 sprintf(sum_line, " rtr %s", inet_ntoa(ls_router)); 281 sum_line += strlen(sum_line); 282 } 283 if (flags & F_DTAIL) { 284 (void) snprintf(get_line(0, 0), get_line_remain(), 285 "Group LSA %s ", inet_ntoa(ls_stateid)); 286 (void) snprintf(get_line(0, 0), get_line_remain(), 287 " rtr = %s ", inet_ntoa(ls_router)); 288 } 289 break; 290 default: 291 if (flags & F_SUM) { 292 sprintf(sum_line, " unknown LSA type %d", ls_type); 293 sum_line += strlen(sum_line); 294 } 295 if (flags & F_DTAIL) { 296 (void) snprintf(get_line(0, 0), get_line_remain(), 297 "Unknown LSA type %d", ls_type); 298 } 299 break; 300 } 301 } 302 303 static void 304 interpret_ospf_lsa_hdr(int flags, struct lsa_hdr *lsah) 305 { 306 if (flags & F_SUM) 307 return; 308 309 if (flags & F_DTAIL) { 310 (void) snprintf(get_line(0, 0), get_line_remain(), 311 "Options = %s", 312 ospf_print_bits(ospf_option_bits, lsah->ls_options)); 313 (void) snprintf(get_line(0, 0), get_line_remain(), 314 "Sequence = %X ", ntohl(lsah->ls_seq)); 315 (void) snprintf(get_line(0, 0), get_line_remain(), 316 "Age = %X ", ospf_print_lsa_age(ntohs(lsah->ls_age))); 317 } 318 319 ospf_print_ls_type(flags, lsah->ls_type, lsah->ls_stateid, 320 lsah->ls_router); 321 322 } 323 324 #define TRUNC(addr) ((uchar_t *)(addr) > fragend) 325 static int 326 interpret_ospf_lsa(int flags, struct lsa *lsa, uchar_t *fragend) 327 { 328 uchar_t *ls_end; 329 int rla_count, k; 330 struct rlalink *rl; 331 struct tos_metric *tosp; 332 struct in_addr *addr; 333 uint32_t *tosmetric; 334 struct aslametric *am; 335 uint32_t tm; 336 int tos, metric; 337 338 interpret_ospf_lsa_hdr(flags, &lsa->ls_hdr); 339 340 ls_end = (uchar_t *)lsa + ntohs(lsa->ls_hdr.ls_length); 341 342 if (TRUNC(ls_end)) 343 return (-1); 344 345 switch (lsa->ls_hdr.ls_type) { 346 347 case LS_TYPE_ROUTER: 348 if (TRUNC(&lsa->lsa_un.un_rla.rla_flags)) 349 return (-1); 350 351 if (flags & F_DTAIL) { 352 (void) ospf_print_bits(ospf_rla_flag_bits, 353 lsa->lsa_un.un_rla.rla_flags); 354 } 355 356 if (TRUNC(&lsa->lsa_un.un_rla.rla_count)) 357 return (-1); 358 rla_count = ntohs(lsa->lsa_un.un_rla.rla_count); 359 360 rl = lsa->lsa_un.un_rla.rla_link; 361 if (TRUNC(rl)) 362 return (-1); 363 364 while (rla_count-- != 0) { 365 if (TRUNC((uchar_t *)rl + sizeof (*rl))) 366 return (-1); 367 switch (rl->link_type) { 368 case RLA_TYPE_VIRTUAL: 369 if (flags & F_DTAIL) { 370 (void) snprintf(get_line(0, 0), 371 get_line_remain(), "Virtual Link"); 372 } 373 /* fall through */ 374 case RLA_TYPE_ROUTER: 375 if (flags & F_DTAIL) { 376 (void) snprintf(get_line(0, 0), 377 get_line_remain(), "Neighbor = %s", 378 inet_ntoa(rl->link_id)); 379 (void) snprintf(get_line(0, 0), 380 get_line_remain(), "Interface = %s", 381 inet_ntoa(rl->link_data)); 382 } 383 break; 384 case RLA_TYPE_TRANSIT: 385 if (flags & F_DTAIL) { 386 (void) snprintf(get_line(0, 0), 387 get_line_remain(), 388 "Designated Router = %s", 389 inet_ntoa(rl->link_id)); 390 (void) snprintf(get_line(0, 0), 391 get_line_remain(), "Interface = %s", 392 inet_ntoa(rl->link_data)); 393 } 394 break; 395 case RLA_TYPE_STUB: 396 if (flags & F_DTAIL) { 397 (void) snprintf(get_line(0, 0), 398 get_line_remain(), "Network = %s", 399 inet_ntoa(rl->link_id)); 400 (void) snprintf(get_line(0, 0), 401 get_line_remain(), "Mask = %s", 402 inet_ntoa(rl->link_data)); 403 } 404 break; 405 default: 406 if (flags & F_DTAIL) { 407 (void) snprintf(get_line(0, 0), 408 get_line_remain(), 409 "Unknown link type %d", 410 rl->link_type); 411 } 412 413 } 414 if (flags & F_DTAIL) { 415 (void) snprintf(get_line(0, 0), 416 get_line_remain(), "TOS 0 metric = %d", 417 ntohs(rl->link_tos0metric)); 418 } 419 tosp = (struct tos_metric *)( 420 (uchar_t *)rl + sizeof (rl->link_tos0metric)); 421 for (k = 0; k > (int)rl->link_toscount; ++k, ++tosp) { 422 if (TRUNC(tosp)) 423 return (-1); 424 if (flags & F_DTAIL) { 425 (void) snprintf(get_line(0, 0), 426 get_line_remain(), 427 "TOS %d metric = %d", 428 tosp->tos_type, 429 ntohs(tosp->tos_metric)); 430 } 431 432 } 433 rl = (struct rlalink *)((uchar_t *)(rl + 1) + 434 ((rl->link_toscount) * sizeof (*tosp))); 435 if (TRUNC(rl)) 436 return (-1); /* truncated */ 437 } 438 break; 439 case LS_TYPE_NETWORK: 440 441 if (TRUNC(&lsa->lsa_un.un_nla.nla_mask)) 442 return (-1); 443 444 if (flags & F_DTAIL) { 445 snprintf(get_line(0, 0), get_line_remain(), 446 "Mask = %s", 447 inet_ntoa(lsa->lsa_un.un_nla.nla_mask)); 448 snprintf(get_line(0, 0), get_line_remain(), 449 "Routers:"); 450 } 451 addr = lsa->lsa_un.un_nla.nla_router; 452 while ((uchar_t *)addr < ls_end) { 453 if ((uchar_t *)addr + sizeof (struct in_addr) > ls_end) 454 return (-1); /* truncated */ 455 if (flags & F_DTAIL) { 456 snprintf(get_line(0, 0), get_line_remain(), 457 "\t%s", inet_ntoa(*addr)); 458 } 459 ++addr; 460 } 461 break; 462 case LS_TYPE_SUM_IP: 463 464 if (TRUNC((uchar_t *)&lsa->lsa_un.un_sla.sla_mask + 465 sizeof (struct in_addr))) 466 return (-1); 467 468 if (flags & F_DTAIL) { 469 snprintf(get_line(0, 0), get_line_remain(), "Mask = %s", 470 inet_ntoa(lsa->lsa_un.un_sla.sla_mask)); 471 } 472 /* FALLTHROUGH */ 473 case LS_TYPE_SUM_ABR: 474 if (TRUNC(&lsa->lsa_un.un_sla.sla_tosmetric)) 475 return (-1); 476 tosmetric = lsa->lsa_un.un_sla.sla_tosmetric; 477 while ((uchar_t *)tosmetric < ls_end) { 478 if ((uchar_t *)tosmetric + sizeof (tm) > fragend) 479 return (-1); /* truncated */ 480 tm = ntohl(*tosmetric); 481 tos = (tm & SLA_MASK_TOS) >> SLA_SHIFT_TOS; 482 metric = tm & SLA_MASK_METRIC; 483 if (flags & F_DTAIL) { 484 snprintf(get_line(0, 0), get_line_remain(), 485 " tos %d metric %d", tos, metric); 486 } 487 ++tosmetric; 488 } 489 break; 490 case LS_TYPE_ASE: 491 if (TRUNC(&lsa->lsa_un.un_asla.asla_mask)) 492 return (-1); 493 if (flags & F_DTAIL) { 494 snprintf(get_line(0, 0), get_line_remain(), "Mask = %s", 495 inet_ntoa(lsa->lsa_un.un_asla.asla_mask)); 496 } 497 am = lsa->lsa_un.un_asla.asla_metric; 498 while ((uchar_t *)am < ls_end) { 499 if ((uchar_t *)am + sizeof (tm) > fragend) 500 return (-1); /* truncated */ 501 tm = ntohl(am->asla_tosmetric); 502 tos = (tm & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS; 503 metric = tm & ASLA_MASK_METRIC; 504 if (flags & F_DTAIL) { 505 snprintf(get_line(0, 0), get_line_remain(), 506 " type %d tos %d metric %d", 507 (tm & ASLA_FLAG_EXTERNAL) ? 2 : 1, 508 tos, metric); 509 } 510 if (am->asla_forward.s_addr != 0) { 511 if (flags & F_DTAIL) { 512 snprintf(get_line(0, 0), 513 get_line_remain(), " Forward %s", 514 inet_ntoa(am->asla_forward)); 515 } 516 } 517 if (am->asla_tag.s_addr != 0) { 518 if (flags & F_DTAIL) { 519 snprintf(get_line(0, 0), 520 get_line_remain(), " Tag %s", 521 inet_ntoa(am->asla_tag)); 522 } 523 } 524 ++am; 525 } 526 break; 527 default: 528 if (flags & F_DTAIL) { 529 snprintf(get_line(0, 0), get_line_remain(), 530 " Unknown LSA type %d", lsa->ls_hdr.ls_type); 531 532 } 533 break; 534 } 535 return (0); 536 } 537 #undef TRUNC 538 539 int 540 interpret_ospf(int flags, struct ospfhdr *ospf, int iplen, int fraglen) 541 { 542 int nlsa, nlsah = 0; 543 struct lsa_hdr *lsah; 544 struct lsr *lsr; 545 struct lsa *lsa; 546 boolean_t trunc = B_FALSE; 547 548 if ((fraglen < OSPF_MIN_HEADER_SIZE) || 549 (fraglen < ntohs(ospf->ospf_len))) 550 return (fraglen); /* incomplete header */ 551 552 if (fraglen > ntohs(ospf->ospf_len)) 553 fraglen = ntohs(ospf->ospf_len); 554 555 556 if (ospf->ospf_type > OSPF_TYPE_MAX) { 557 if (flags & F_SUM) { 558 (void) sprintf(sum_line, "Unknown OSPF TYPE %d \n", 559 ospf->ospf_type); 560 sum_line += strlen(sum_line); 561 } 562 if (flags & F_SUM) { 563 show_header("OSPF: ", "OSPF Header", fraglen); 564 show_space(); 565 (void) snprintf(get_line(0, 0), get_line_remain(), 566 "Unknown OSPF Type = %d", ospf->ospf_type); 567 } 568 return (fraglen); 569 } 570 571 if (flags & F_SUM) { 572 sum_line = (char *)get_sum_line(); 573 (void) sprintf(sum_line, "OSPF %s RTRID=%s ", 574 ospf_types[ospf->ospf_type], 575 inet_ntoa(ospf->ospf_routerid)); 576 sum_line += strlen(sum_line); 577 (void) sprintf(sum_line, "AREA=%s LEN=%d ", 578 inet_ntoa(ospf->ospf_areaid), 579 ntohs((ushort_t)ospf->ospf_len)); 580 sum_line += strlen(sum_line); 581 } 582 583 if (flags & F_DTAIL) { 584 show_header("OSPF: ", "OSPF Header", fraglen); 585 show_space(); 586 (void) snprintf(get_line(0, 0), get_line_remain(), 587 "Version = %d", ospf->ospf_version); 588 (void) snprintf(get_line(0, 0), get_line_remain(), 589 "Type = %s", ospf_types[ospf->ospf_type]); 590 (void) snprintf(get_line(0, 0), get_line_remain(), 591 "Router ID = %s", inet_ntoa(ospf->ospf_routerid)); 592 (void) snprintf(get_line(0, 0), get_line_remain(), 593 "Area ID = %s", inet_ntoa(ospf->ospf_areaid)); 594 (void) snprintf(get_line(0, 0), get_line_remain(), 595 "Checksum = 0x%x", ospf->ospf_chksum); 596 597 if (ospf->ospf_authtype > OSPF_AUTH_TYPE_MAX) { 598 (void) snprintf(get_line(0, 0), get_line_remain(), 599 "Auth = %d (unknown auth type)", 600 ospf->ospf_authtype); 601 } else { 602 (void) snprintf(get_line(0, 0), get_line_remain(), 603 "Auth = %s", ospf_authtypes[ospf->ospf_authtype]); 604 } 605 } 606 607 if (ospf->ospf_version != 2) { 608 if (ospf->ospf_version == 3) { 609 if (flags & F_DTAIL) 610 snprintf(get_line(0, 0), get_line_remain(), 611 "ospfv3 packet in ipv4 header"); 612 return (interpret_ospf6(flags, ospf, iplen, fraglen)); 613 } else { 614 return (fraglen); 615 } 616 } 617 618 switch (ospf->ospf_type) { 619 case OSPF_TYPE_HELLO: 620 if (interpret_ospf_hello(flags, ospf, fraglen) < 0) 621 trunc = B_TRUE; 622 break; 623 624 case OSPF_TYPE_DB: 625 if (fraglen < OSPF_MIN_HEADER_SIZE + OSPF_MIN_DB_HEADER_SIZE) { 626 trunc = B_TRUE; 627 break; 628 } 629 if (flags & F_SUM) { 630 sprintf(sum_line, " %s %s S %X", ospf_print_bits( 631 ospf_option_bits, ospf->ospf_db.db_options), 632 ospf_print_bits(ospf_db_flags_bits, 633 ospf->ospf_db.db_flags), 634 ntohl(ospf->ospf_db.db_seq)); 635 sum_line += strlen(sum_line); 636 } 637 if (flags & F_DTAIL) { 638 show_header("OSPF DB: ", "Database Description Packet", 639 fraglen); 640 show_space(); 641 snprintf(get_line(0, 0), get_line_remain(), 642 "Options = %s", ospf_print_bits( 643 ospf_option_bits, ospf->ospf_db.db_options)); 644 snprintf(get_line(0, 0), get_line_remain(), 645 "Flags = %s", ospf_print_bits( 646 ospf_db_flags_bits, ospf->ospf_db.db_flags)); 647 snprintf(get_line(0, 0), get_line_remain(), 648 "Sequence = 0x%X", ntohl(ospf->ospf_db.db_seq)); 649 /* Print all the LS advs */ 650 lsah = ospf->ospf_db.db_lshdr; 651 while ((uchar_t *)lsah < ((uchar_t *)ospf + fraglen)) { 652 if ((uchar_t *)lsah + sizeof (struct lsa_hdr) > 653 ((uchar_t *)ospf + fraglen)) { 654 trunc = B_TRUE; 655 break; 656 } 657 interpret_ospf_lsa_hdr(flags, lsah); 658 ++lsah; 659 } 660 } 661 break; 662 663 case OSPF_TYPE_LSR: 664 if (fraglen < OSPF_MIN_HEADER_SIZE + OSPF_MIN_LSR_HEADER_SIZE) { 665 trunc = B_TRUE; 666 break; 667 } 668 if (flags & F_DTAIL) { 669 snprintf(get_line(0, 0), get_line_remain(), 670 "Link State Request Packet"); 671 } 672 lsr = ospf->ospf_lsr; 673 while ((uchar_t *)lsr < ((uchar_t *)ospf + fraglen)) { 674 if ((uchar_t *)lsr + sizeof (struct lsr) > 675 ((uchar_t *)ospf + fraglen)) { 676 trunc = B_TRUE; 677 break; 678 } 679 if (flags & F_SUM) { 680 nlsah++; 681 } 682 if (flags & F_DTAIL) { 683 ospf_print_ls_type(flags, ntohl(lsr->ls_type), 684 lsr->ls_stateid, lsr->ls_router); 685 } 686 ++lsr; 687 } 688 if (flags & F_SUM) { 689 sprintf(sum_line, " %d LSAs", nlsah); 690 sum_line += strlen(sum_line); 691 } 692 break; 693 694 case OSPF_TYPE_LSU: 695 if (fraglen < OSPF_MIN_HEADER_SIZE + OSPF_MIN_LSU_HEADER_SIZE) { 696 trunc = B_TRUE; 697 break; 698 } 699 if (flags & F_DTAIL) { 700 show_header("OSPF LSU: ", "Link State Update Packet", 701 fraglen); 702 show_space(); 703 } 704 lsa = ospf->ospf_lsu.lsu_lsa; 705 nlsa = ntohl(ospf->ospf_lsu.lsu_count); 706 if (flags & F_SUM) { 707 sprintf(sum_line, "%d LSAs", nlsa); 708 sum_line += strlen(sum_line); 709 break; 710 } 711 while (nlsa-- != 0) { 712 uchar_t *fragend = (uchar_t *)ospf + fraglen; 713 if (((uchar_t *)lsa >= fragend) || 714 ((uchar_t *)lsa + sizeof (struct lsa_hdr) > 715 fragend) || 716 ((uchar_t *)lsa + ntohs(lsa->ls_hdr.ls_length) > 717 fragend)) { 718 trunc = B_TRUE; 719 break; 720 } 721 722 if (interpret_ospf_lsa(flags, lsa, fragend) < 0) { 723 trunc = B_TRUE; 724 break; 725 } 726 lsa = (struct lsa *)((uchar_t *)lsa + 727 ntohs(lsa->ls_hdr.ls_length)); 728 } 729 730 break; 731 732 case OSPF_TYPE_LSA: 733 if (flags & F_DTAIL) { 734 show_header("OSPF LSA: ", "Link State Ack Packet", 735 fraglen); 736 show_space(); 737 } 738 lsah = ospf->ospf_lsa.lsa_lshdr; 739 nlsah = 0; 740 while ((uchar_t *)lsah < ((uchar_t *)ospf + fraglen)) { 741 if ((uchar_t *)lsah + sizeof (struct lsa_hdr) > 742 ((uchar_t *)ospf + fraglen)) { 743 trunc = B_TRUE; 744 break; 745 } 746 nlsah++; 747 if (flags & F_DTAIL) 748 interpret_ospf_lsa_hdr(flags, lsah); 749 ++lsah; 750 } 751 if (flags & F_SUM) { 752 sprintf(sum_line, "%d LSAs", nlsah); 753 sum_line += strlen(sum_line); 754 } 755 break; 756 757 default: 758 /* NOTREACHED */ 759 break; 760 } 761 if (trunc) { 762 if (flags & F_SUM) { 763 sprintf(sum_line, "--truncated"); 764 sum_line += strlen(sum_line); 765 } 766 if (flags & F_DTAIL) 767 snprintf(get_line(0, 0), get_line_remain(), 768 "--truncated"); 769 } 770 771 return (fraglen); 772 } 773