1 /* 2 * Copyright (c) 1992, 1993, 1994, 1995, 1996 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) 22 */ 23 24 #ifndef lint 25 static char rcsid[] = 26 "@(#) $Header: print-ospf.c,v 1.19 96/07/14 19:39:03 leres Exp $ (LBL)"; 27 #endif 28 29 #include <sys/param.h> 30 #include <sys/time.h> 31 #include <sys/socket.h> 32 33 #include <netinet/in.h> 34 #include <netinet/in_systm.h> 35 #include <netinet/ip.h> 36 #include <netinet/ip_var.h> 37 38 #include <ctype.h> 39 #include <stdio.h> 40 41 #include "interface.h" 42 #include "addrtoname.h" 43 44 #include "ospf.h" 45 46 struct bits { 47 u_int32_t bit; 48 const char *str; 49 }; 50 51 static const struct bits ospf_option_bits[] = { 52 { OSPF_OPTION_T, "T" }, 53 { OSPF_OPTION_E, "E" }, 54 { OSPF_OPTION_MC, "MC" }, 55 { 0, NULL } 56 }; 57 58 static const struct bits ospf_rla_flag_bits[] = { 59 { RLA_FLAG_B, "B" }, 60 { RLA_FLAG_E, "E" }, 61 { RLA_FLAG_W1, "W1" }, 62 { RLA_FLAG_W2, "W2" }, 63 { 0, NULL } 64 }; 65 66 static const char *ospf_types[OSPF_TYPE_MAX] = { 67 (char *) 0, 68 "hello", 69 "dd", 70 "ls_req", 71 "ls_upd", 72 "ls_ack" 73 }; 74 75 static inline void 76 ospf_print_seqage(register u_int32_t seq, register time_t us) 77 { 78 register time_t sec = us % 60; 79 register time_t mins = (us / 60) % 60; 80 register time_t hour = us/3600; 81 82 printf(" S %X age ", seq); 83 if (hour) { 84 printf("%u:%02u:%02u", 85 (u_int32_t)hour, 86 (u_int32_t)mins, 87 (u_int32_t)sec); 88 } else if (mins) { 89 printf("%u:%02u", 90 (u_int32_t)mins, 91 (u_int32_t)sec); 92 } else { 93 printf("%u", 94 (u_int32_t)sec); 95 } 96 } 97 98 99 static inline void 100 ospf_print_bits(register const struct bits *bp, register u_char options) 101 { 102 char sep = ' '; 103 104 do { 105 if (options & bp->bit) { 106 printf("%c%s", 107 sep, 108 bp->str); 109 sep = '/'; 110 } 111 } while ((++bp)->bit) ; 112 } 113 114 115 #define LS_PRINT(lsp, type) switch (type) { \ 116 case LS_TYPE_ROUTER: \ 117 printf(" rtr %s ", ipaddr_string(&lsp->ls_router)); break; \ 118 case LS_TYPE_NETWORK: \ 119 printf(" net dr %s if %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \ 120 case LS_TYPE_SUM_IP: \ 121 printf(" sum %s abr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \ 122 case LS_TYPE_SUM_ABR: \ 123 printf(" abr %s rtr %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \ 124 case LS_TYPE_ASE: \ 125 printf(" ase %s asbr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \ 126 case LS_TYPE_GROUP: \ 127 printf(" group %s rtr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \ 128 } 129 130 static int 131 ospf_print_lshdr(register const struct lsa_hdr *lshp, const caddr_t end) 132 { 133 if ((caddr_t) (lshp + 1) > end) { 134 return 1; 135 } 136 137 printf(" {"); /* } (ctags) */ 138 139 if (!lshp->ls_type || lshp->ls_type >= LS_TYPE_MAX) { 140 printf(" ??LS type %d?? }", lshp->ls_type); /* { (ctags) */ 141 return 1; 142 } 143 144 ospf_print_bits(ospf_option_bits, lshp->ls_options); 145 ospf_print_seqage(ntohl(lshp->ls_seq), ntohs(lshp->ls_age)); 146 147 LS_PRINT(lshp, lshp->ls_type); 148 149 return 0; 150 } 151 152 153 /* 154 * Print a single link state advertisement. If truncated return 1, else 0. 155 */ 156 157 static int 158 ospf_print_lsa(register const struct lsa *lsap, const caddr_t end) 159 { 160 register const char *ls_end; 161 const struct rlalink *rlp; 162 const struct tos_metric *tosp; 163 const struct in_addr *ap; 164 const struct aslametric *almp; 165 const struct mcla *mcp; 166 const u_int32_t *lp; 167 int j, k; 168 169 if (ospf_print_lshdr(&lsap->ls_hdr, end)) { 170 return 1; 171 } 172 173 ls_end = (caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length); 174 175 if (ls_end > end) { 176 printf(" }"); /* { (ctags) */ 177 return 1; 178 } 179 180 switch (lsap->ls_hdr.ls_type) { 181 case LS_TYPE_ROUTER: 182 ospf_print_bits(ospf_rla_flag_bits, lsap->lsa_un.un_rla.rla_flags); 183 184 j = ntohs(lsap->lsa_un.un_rla.rla_count); 185 rlp = lsap->lsa_un.un_rla.rla_link; 186 while (j--) { 187 struct rlalink *rln = (struct rlalink *) ((caddr_t) (rlp + 1) + ((rlp->link_toscount) * sizeof (struct tos_metric))); 188 189 if ((caddr_t) rln > ls_end) { 190 break; 191 } 192 printf(" {"); /* } (ctags) */ 193 194 switch (rlp->link_type) { 195 case RLA_TYPE_VIRTUAL: 196 printf(" virt"); 197 /* Fall through */ 198 199 case RLA_TYPE_ROUTER: 200 printf(" nbrid %s if %s", 201 ipaddr_string(&rlp->link_id), 202 ipaddr_string(&rlp->link_data)); 203 break; 204 205 case RLA_TYPE_TRANSIT: 206 printf(" dr %s if %s", 207 ipaddr_string(&rlp->link_id), 208 ipaddr_string(&rlp->link_data)); 209 break; 210 211 case RLA_TYPE_STUB: 212 printf(" net %s mask %s", 213 ipaddr_string(&rlp->link_id), 214 ipaddr_string(&rlp->link_data)); 215 break; 216 217 default: 218 printf(" ??RouterLinksType %d?? }", /* { (ctags) */ 219 rlp->link_type); 220 return 0; 221 } 222 printf(" tos 0 metric %d", 223 ntohs(rlp->link_tos0metric)); 224 tosp = (struct tos_metric *) ((sizeof rlp->link_tos0metric) + (caddr_t) rlp); 225 for (k = 0; k < rlp->link_toscount; k++, tosp++) { 226 printf(" tos %d metric %d", 227 tosp->tos_type, 228 ntohs(tosp->tos_metric)); 229 } 230 printf(" }"); /* { (ctags) */ 231 rlp = rln; 232 } 233 break; 234 235 case LS_TYPE_NETWORK: 236 printf(" mask %s rtrs", 237 ipaddr_string(&lsap->lsa_un.un_nla.nla_mask)); 238 for (ap = lsap->lsa_un.un_nla.nla_router; 239 (caddr_t) (ap + 1) <= ls_end; 240 ap++) { 241 printf(" %s", 242 ipaddr_string(ap)); 243 } 244 break; 245 246 case LS_TYPE_SUM_IP: 247 printf(" mask %s", 248 ipaddr_string(&lsap->lsa_un.un_sla.sla_mask)); 249 /* Fall through */ 250 251 case LS_TYPE_SUM_ABR: 252 253 for (lp = lsap->lsa_un.un_sla.sla_tosmetric; 254 (caddr_t) (lp + 1) <= ls_end; 255 lp++) { 256 u_int32_t ul = ntohl(*lp); 257 258 printf(" tos %d metric %d", 259 (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS, 260 ul & SLA_MASK_METRIC); 261 } 262 break; 263 264 case LS_TYPE_ASE: 265 printf(" mask %s", 266 ipaddr_string(&lsap->lsa_un.un_asla.asla_mask)); 267 268 for (almp = lsap->lsa_un.un_asla.asla_metric; 269 (caddr_t) (almp + 1) <= ls_end; 270 almp++) { 271 u_int32_t ul = ntohl(almp->asla_tosmetric); 272 273 printf(" type %d tos %d metric %d", 274 (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1, 275 (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS, 276 (ul & ASLA_MASK_METRIC)); 277 if (almp->asla_forward.s_addr) { 278 printf(" forward %s", 279 ipaddr_string(&almp->asla_forward)); 280 } 281 if (almp->asla_tag.s_addr) { 282 printf(" tag %s", 283 ipaddr_string(&almp->asla_tag)); 284 } 285 } 286 break; 287 288 case LS_TYPE_GROUP: 289 /* Multicast extensions as of 23 July 1991 */ 290 for (mcp = lsap->lsa_un.un_mcla; 291 (caddr_t) (mcp + 1) <= ls_end; 292 mcp++) { 293 switch (ntohl(mcp->mcla_vtype)) { 294 case MCLA_VERTEX_ROUTER: 295 printf(" rtr rtrid %s", 296 ipaddr_string(&mcp->mcla_vid)); 297 break; 298 299 case MCLA_VERTEX_NETWORK: 300 printf(" net dr %s", 301 ipaddr_string(&mcp->mcla_vid)); 302 break; 303 304 default: 305 printf(" ??VertexType %u??", 306 (u_int32_t)ntohl(mcp->mcla_vtype)); 307 break; 308 } 309 } 310 } 311 312 printf(" }"); /* { (ctags) */ 313 return 0; 314 } 315 316 317 void 318 ospf_print(register const u_char *bp, register u_int length, 319 register const u_char *bp2) 320 { 321 register const struct ospfhdr *op; 322 register const struct ip *ip; 323 register const caddr_t end = (caddr_t)snapend; 324 register const struct lsa *lsap; 325 register const struct lsa_hdr *lshp; 326 char sep; 327 int i, j; 328 const struct in_addr *ap; 329 const struct lsr *lsrp; 330 331 op = (struct ospfhdr *)bp; 332 ip = (struct ip *)bp2; 333 /* Print the source and destination address */ 334 (void) printf("%s > %s:", 335 ipaddr_string(&ip->ip_src), 336 ipaddr_string(&ip->ip_dst)); 337 338 if ((caddr_t) (&op->ospf_len + 1) > end) { 339 goto trunc_test; 340 } 341 342 /* If the type is valid translate it, or just print the type */ 343 /* value. If it's not valid, say so and return */ 344 if (op->ospf_type || op->ospf_type < OSPF_TYPE_MAX) { 345 printf(" OSPFv%d-%s %d:", 346 op->ospf_version, 347 ospf_types[op->ospf_type], 348 length); 349 } else { 350 printf(" ospf-v%d-??type %d?? %d:", 351 op->ospf_version, 352 op->ospf_type, 353 length); 354 return; 355 } 356 357 if (length != ntohs(op->ospf_len)) { 358 printf(" ??len %d??", 359 ntohs(op->ospf_len)); 360 goto trunc_test; 361 } 362 363 if ((caddr_t) (&op->ospf_routerid + 1) > end) { 364 goto trunc_test; 365 } 366 367 /* Print the routerid if it is not the same as the source */ 368 if (ip->ip_src.s_addr != op->ospf_routerid.s_addr) { 369 printf(" rtrid %s", 370 ipaddr_string(&op->ospf_routerid)); 371 } 372 373 if ((caddr_t) (&op->ospf_areaid + 1) > end) { 374 goto trunc_test; 375 } 376 377 if (op->ospf_areaid.s_addr) { 378 printf(" area %s", 379 ipaddr_string(&op->ospf_areaid)); 380 } else { 381 printf(" backbone"); 382 } 383 384 if ((caddr_t) (op->ospf_authdata + OSPF_AUTH_SIZE) > end) { 385 goto trunc_test; 386 } 387 388 if (vflag) { 389 /* Print authentication data (should we really do this?) */ 390 switch (ntohs(op->ospf_authtype)) { 391 case OSPF_AUTH_NONE: 392 break; 393 394 case OSPF_AUTH_SIMPLE: 395 printf(" auth "); 396 j = 0; 397 for (i = 0; i < sizeof (op->ospf_authdata); i++) { 398 if (!isprint(op->ospf_authdata[i])) { 399 j = 1; 400 break; 401 } 402 } 403 if (j) { 404 /* Print the auth-data as a string of octets */ 405 printf("%s.%s", 406 ipaddr_string((struct in_addr *) op->ospf_authdata), 407 ipaddr_string((struct in_addr *) &op->ospf_authdata[sizeof (struct in_addr)])); 408 } else { 409 /* Print the auth-data as a text string */ 410 printf("'%.8s'", 411 op->ospf_authdata); 412 } 413 break; 414 415 default: 416 printf(" ??authtype-%d??", 417 ntohs(op->ospf_authtype)); 418 return; 419 } 420 } 421 422 423 /* Do rest according to version. */ 424 switch (op->ospf_version) { 425 case 2: 426 /* ospf version 2 */ 427 switch (op->ospf_type) { 428 case OSPF_TYPE_UMD: /* Rob Coltun's special monitoring packets; do nothing */ 429 break; 430 431 case OSPF_TYPE_HELLO: 432 if ((caddr_t) (&op->ospf_hello.hello_deadint + 1) > end) { 433 break; 434 } 435 if (vflag) { 436 ospf_print_bits(ospf_option_bits, op->ospf_hello.hello_options); 437 printf(" mask %s int %d pri %d dead %u", 438 ipaddr_string(&op->ospf_hello.hello_mask), 439 ntohs(op->ospf_hello.hello_helloint), 440 op->ospf_hello.hello_priority, 441 (u_int32_t)ntohl(op->ospf_hello.hello_deadint)); 442 } 443 444 if ((caddr_t) (&op->ospf_hello.hello_dr + 1) > end) { 445 break; 446 } 447 if (op->ospf_hello.hello_dr.s_addr) { 448 printf(" dr %s", 449 ipaddr_string(&op->ospf_hello.hello_dr)); 450 } 451 452 if ((caddr_t) (&op->ospf_hello.hello_bdr + 1) > end) { 453 break; 454 } 455 if (op->ospf_hello.hello_bdr.s_addr) { 456 printf(" bdr %s", 457 ipaddr_string(&op->ospf_hello.hello_bdr)); 458 } 459 460 if (vflag) { 461 if ((caddr_t) (op->ospf_hello.hello_neighbor + 1) > end) { 462 break; 463 } 464 printf(" nbrs"); 465 for (ap = op->ospf_hello.hello_neighbor; 466 (caddr_t) (ap + 1) <= end; 467 ap++) { 468 printf(" %s", 469 ipaddr_string(ap)); 470 } 471 } 472 break; /* HELLO */ 473 474 case OSPF_TYPE_DB: 475 if ((caddr_t) (&op->ospf_db.db_seq + 1) > end) { 476 break; 477 } 478 ospf_print_bits(ospf_option_bits, op->ospf_db.db_options); 479 sep = ' '; 480 if (op->ospf_db.db_flags & OSPF_DB_INIT) { 481 printf("%cI", 482 sep); 483 sep = '/'; 484 } 485 if (op->ospf_db.db_flags & OSPF_DB_MORE) { 486 printf("%cM", 487 sep); 488 sep = '/'; 489 } 490 if (op->ospf_db.db_flags & OSPF_DB_MASTER) { 491 printf("%cMS", 492 sep); 493 sep = '/'; 494 } 495 printf(" S %X", (u_int32_t)ntohl(op->ospf_db.db_seq)); 496 497 if (vflag) { 498 /* Print all the LS adv's */ 499 lshp = op->ospf_db.db_lshdr; 500 501 while (!ospf_print_lshdr(lshp, end)) { 502 printf(" }"); /* { (ctags) */ 503 lshp++; 504 } 505 } 506 break; 507 508 case OSPF_TYPE_LSR: 509 if (vflag) { 510 for (lsrp = op->ospf_lsr; (caddr_t) (lsrp+1) <= end; lsrp++) { 511 int32_t type; 512 513 if ((caddr_t) (lsrp + 1) > end) { 514 break; 515 } 516 517 printf(" {"); /* } (ctags) */ 518 if (!(type = ntohl(lsrp->ls_type)) || type >= LS_TYPE_MAX) { 519 printf(" ??LinkStateType %d }", type); /* { (ctags) */ 520 printf(" }"); /* { (ctags) */ 521 break; 522 } 523 524 LS_PRINT(lsrp, type); 525 printf(" }"); /* { (ctags) */ 526 } 527 } 528 break; 529 530 case OSPF_TYPE_LSU: 531 if (vflag) { 532 lsap = op->ospf_lsu.lsu_lsa; 533 i = ntohl(op->ospf_lsu.lsu_count); 534 535 while (i-- && 536 !ospf_print_lsa(lsap, end)) { 537 lsap = (struct lsa *) ((caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length)); 538 } 539 } 540 break; 541 542 543 case OSPF_TYPE_LSA: 544 if (vflag) { 545 lshp = op->ospf_lsa.lsa_lshdr; 546 547 while (!ospf_print_lshdr(lshp, end)) { 548 printf(" }"); /* { (ctags) */ 549 lshp++; 550 } 551 break; 552 } 553 } /* end switch on v2 packet type */ 554 break; 555 556 default: 557 printf(" ospf [version %d]", 558 op->ospf_version); 559 break; 560 } /* end switch on version */ 561 562 trunc_test: 563 if ((snapend - bp) < length) { 564 printf(" [|]"); 565 } 566 567 return; /* from ospf_print */ 568 } 569