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