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