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