1 /* $OpenBSD: ospfctl.c,v 1.64 2016/12/05 22:39:25 jca Exp $ */ 2 3 /* 4 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 5 * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> 6 * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/types.h> 22 #include <sys/socket.h> 23 #include <sys/un.h> 24 #include <netinet/in.h> 25 #include <arpa/inet.h> 26 #include <net/if_media.h> 27 #include <net/if_types.h> 28 29 #include <err.h> 30 #include <errno.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <unistd.h> 35 36 #include "ospf.h" 37 #include "ospfd.h" 38 #include "ospfe.h" 39 #include "parser.h" 40 41 __dead void usage(void); 42 int show_summary_msg(struct imsg *); 43 uint64_t get_ifms_type(uint8_t); 44 int show_interface_msg(struct imsg *); 45 int show_interface_detail_msg(struct imsg *); 46 const char *print_link(int); 47 const char *fmt_timeframe(time_t t); 48 const char *fmt_timeframe_core(time_t t); 49 const char *log_id(u_int32_t ); 50 const char *log_adv_rtr(u_int32_t); 51 void show_database_head(struct in_addr, char *, u_int8_t); 52 int show_database_msg(struct imsg *); 53 char *print_ls_type(u_int8_t); 54 void show_db_hdr_msg_detail(struct lsa_hdr *); 55 char *print_rtr_link_type(u_int8_t); 56 const char *print_ospf_flags(u_int8_t); 57 int show_db_msg_detail(struct imsg *imsg); 58 int show_nbr_msg(struct imsg *); 59 const char *print_ospf_options(u_int8_t); 60 int show_nbr_detail_msg(struct imsg *); 61 int show_rib_msg(struct imsg *); 62 void show_rib_head(struct in_addr, u_int8_t, u_int8_t); 63 const char *print_ospf_rtr_flags(u_int8_t); 64 int show_rib_detail_msg(struct imsg *); 65 void show_fib_head(void); 66 int show_fib_msg(struct imsg *); 67 void show_interface_head(void); 68 const char * get_media_descr(uint64_t); 69 const char * get_linkstate(uint8_t, int); 70 void print_baudrate(u_int64_t); 71 int show_fib_interface_msg(struct imsg *); 72 73 struct imsgbuf *ibuf; 74 75 __dead void 76 usage(void) 77 { 78 extern char *__progname; 79 80 fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n", 81 __progname); 82 exit(1); 83 } 84 85 int 86 main(int argc, char *argv[]) 87 { 88 struct sockaddr_un sun; 89 struct parse_result *res; 90 struct imsg imsg; 91 unsigned int ifidx = 0; 92 int ctl_sock; 93 int done = 0; 94 int n, verbose = 0; 95 int ch; 96 char *sockname; 97 98 sockname = OSPFD_SOCKET; 99 while ((ch = getopt(argc, argv, "s:")) != -1) { 100 switch (ch) { 101 case 's': 102 sockname = optarg; 103 break; 104 default: 105 usage(); 106 /* NOTREACHED */ 107 } 108 } 109 argc -= optind; 110 argv += optind; 111 112 /* parse options */ 113 if ((res = parse(argc, argv)) == NULL) 114 exit(1); 115 116 /* connect to ospfd control socket */ 117 if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 118 err(1, "socket"); 119 120 bzero(&sun, sizeof(sun)); 121 sun.sun_family = AF_UNIX; 122 123 strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path)); 124 if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 125 err(1, "connect: %s", sockname); 126 127 if (pledge("stdio", NULL) == -1) 128 err(1, "pledge"); 129 130 if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 131 err(1, NULL); 132 imsg_init(ibuf, ctl_sock); 133 done = 0; 134 135 /* process user request */ 136 switch (res->action) { 137 case NONE: 138 usage(); 139 /* not reached */ 140 case SHOW: 141 case SHOW_SUM: 142 imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); 143 break; 144 case SHOW_IFACE: 145 printf("%-11s %-18s %-6s %-10s %-10s %-8s %3s %3s\n", 146 "Interface", "Address", "State", "HelloTimer", "Linkstate", 147 "Uptime", "nc", "ac"); 148 /*FALLTHROUGH*/ 149 case SHOW_IFACE_DTAIL: 150 if (*res->ifname) { 151 ifidx = if_nametoindex(res->ifname); 152 if (ifidx == 0) 153 errx(1, "no such interface %s", res->ifname); 154 } 155 imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 156 &ifidx, sizeof(ifidx)); 157 break; 158 case SHOW_NBR: 159 printf("%-15s %-3s %-12s %-8s %-15s %-9s %s\n", "ID", "Pri", 160 "State", "DeadTime", "Address", "Iface","Uptime"); 161 /*FALLTHROUGH*/ 162 case SHOW_NBR_DTAIL: 163 imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 164 break; 165 case SHOW_DB: 166 imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0); 167 break; 168 case SHOW_DBBYAREA: 169 imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, 170 &res->addr, sizeof(res->addr)); 171 break; 172 case SHOW_DBEXT: 173 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0); 174 break; 175 case SHOW_DBNET: 176 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0); 177 break; 178 case SHOW_DBRTR: 179 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0); 180 break; 181 case SHOW_DBSELF: 182 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0); 183 break; 184 case SHOW_DBSUM: 185 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0); 186 break; 187 case SHOW_DBASBR: 188 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0); 189 break; 190 case SHOW_DBOPAQ: 191 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_OPAQ, 0, 0, -1, NULL, 0); 192 break; 193 case SHOW_RIB: 194 printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", 195 "Nexthop", "Path Type", "Type", "Cost", "Uptime"); 196 /*FALLTHROUGH*/ 197 case SHOW_RIB_DTAIL: 198 imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); 199 break; 200 case SHOW_FIB: 201 if (!res->addr.s_addr) 202 imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, 203 &res->flags, sizeof(res->flags)); 204 else 205 imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, 206 &res->addr, sizeof(res->addr)); 207 show_fib_head(); 208 break; 209 case SHOW_FIB_IFACE: 210 if (*res->ifname) 211 imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, 212 res->ifname, sizeof(res->ifname)); 213 else 214 imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0); 215 show_interface_head(); 216 break; 217 case FIB: 218 errx(1, "fib couple|decouple"); 219 break; 220 case FIB_COUPLE: 221 imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0); 222 printf("couple request sent.\n"); 223 done = 1; 224 break; 225 case FIB_DECOUPLE: 226 imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0); 227 printf("decouple request sent.\n"); 228 done = 1; 229 break; 230 case FIB_RELOAD: 231 imsg_compose(ibuf, IMSG_CTL_FIB_RELOAD, 0, 0, -1, NULL, 0); 232 printf("reload request sent.\n"); 233 done = 1; 234 break; 235 case LOG_VERBOSE: 236 verbose = 1; 237 /* FALLTHROUGH */ 238 case LOG_BRIEF: 239 imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, 240 &verbose, sizeof(verbose)); 241 printf("logging request sent.\n"); 242 done = 1; 243 break; 244 case RELOAD: 245 imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 246 printf("reload request sent.\n"); 247 done = 1; 248 break; 249 } 250 251 while (ibuf->w.queued) 252 if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) 253 err(1, "write error"); 254 255 while (!done) { 256 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 257 errx(1, "imsg_read error"); 258 if (n == 0) 259 errx(1, "pipe closed"); 260 261 while (!done) { 262 if ((n = imsg_get(ibuf, &imsg)) == -1) 263 errx(1, "imsg_get error"); 264 if (n == 0) 265 break; 266 switch (res->action) { 267 case SHOW: 268 case SHOW_SUM: 269 done = show_summary_msg(&imsg); 270 break; 271 case SHOW_IFACE: 272 done = show_interface_msg(&imsg); 273 break; 274 case SHOW_IFACE_DTAIL: 275 done = show_interface_detail_msg(&imsg); 276 break; 277 case SHOW_NBR: 278 done = show_nbr_msg(&imsg); 279 break; 280 case SHOW_NBR_DTAIL: 281 done = show_nbr_detail_msg(&imsg); 282 break; 283 case SHOW_DB: 284 case SHOW_DBBYAREA: 285 case SHOW_DBSELF: 286 done = show_database_msg(&imsg); 287 break; 288 case SHOW_DBEXT: 289 case SHOW_DBNET: 290 case SHOW_DBRTR: 291 case SHOW_DBSUM: 292 case SHOW_DBASBR: 293 case SHOW_DBOPAQ: 294 done = show_db_msg_detail(&imsg); 295 break; 296 case SHOW_RIB: 297 done = show_rib_msg(&imsg); 298 break; 299 case SHOW_RIB_DTAIL: 300 done = show_rib_detail_msg(&imsg); 301 break; 302 case SHOW_FIB: 303 done = show_fib_msg(&imsg); 304 break; 305 case SHOW_FIB_IFACE: 306 done = show_fib_interface_msg(&imsg); 307 break; 308 case NONE: 309 case FIB: 310 case FIB_COUPLE: 311 case FIB_DECOUPLE: 312 case FIB_RELOAD: 313 case LOG_VERBOSE: 314 case LOG_BRIEF: 315 case RELOAD: 316 break; 317 } 318 imsg_free(&imsg); 319 } 320 } 321 close(ctl_sock); 322 free(ibuf); 323 324 return (0); 325 } 326 327 int 328 show_summary_msg(struct imsg *imsg) 329 { 330 struct ctl_sum *sum; 331 struct ctl_sum_area *sumarea; 332 333 switch (imsg->hdr.type) { 334 case IMSG_CTL_SHOW_SUM: 335 sum = imsg->data; 336 printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); 337 printf("Uptime: %s\n", fmt_timeframe_core(sum->uptime)); 338 printf("RFC1583 compatibility flag is "); 339 if (sum->rfc1583compat) 340 printf("enabled\n"); 341 else 342 printf("disabled\n"); 343 344 printf("SPF delay is %d msec(s), hold time between two SPFs " 345 "is %d msec(s)\n", sum->spf_delay, sum->spf_hold_time); 346 printf("Number of external LSA(s) %d (Checksum sum 0x%x)\n", 347 sum->num_ext_lsa, sum->ext_lsa_cksum); 348 printf("Number of areas attached to this router: %d\n", 349 sum->num_area); 350 break; 351 case IMSG_CTL_SHOW_SUM_AREA: 352 sumarea = imsg->data; 353 printf("\nArea ID: %s\n", inet_ntoa(sumarea->area)); 354 printf(" Number of interfaces in this area: %d\n", 355 sumarea->num_iface); 356 printf(" Number of fully adjacent neighbors in this " 357 "area: %d\n", sumarea->num_adj_nbr); 358 printf(" SPF algorithm executed %d time(s)\n", 359 sumarea->num_spf_calc); 360 printf(" Number LSA(s) %d (Checksum sum 0x%x)\n", 361 sumarea->num_lsa, sumarea->lsa_cksum); 362 break; 363 case IMSG_CTL_END: 364 printf("\n"); 365 return (1); 366 default: 367 break; 368 } 369 370 return (0); 371 } 372 373 uint64_t 374 get_ifms_type(uint8_t if_type) 375 { 376 switch (if_type) { 377 case IFT_ETHER: 378 return (IFM_ETHER); 379 case IFT_FDDI: 380 return (IFM_FDDI); 381 case IFT_CARP: 382 return (IFM_CARP); 383 case IFT_PPP: 384 return (IFM_TDM); 385 default: 386 return (0); 387 } 388 } 389 390 int 391 show_interface_msg(struct imsg *imsg) 392 { 393 struct ctl_iface *iface; 394 char *netid; 395 396 switch (imsg->hdr.type) { 397 case IMSG_CTL_SHOW_INTERFACE: 398 iface = imsg->data; 399 400 if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), 401 mask2prefixlen(iface->mask.s_addr)) == -1) 402 err(1, NULL); 403 printf("%-11s %-18s %-6s %-10s %-10s %s %3d %3d\n", 404 iface->name, netid, if_state_name(iface->state), 405 iface->hello_timer.tv_sec < 0 ? "-" : 406 fmt_timeframe_core(iface->hello_timer.tv_sec), 407 get_linkstate(iface->if_type, iface->linkstate), 408 fmt_timeframe_core(iface->uptime), 409 iface->nbr_cnt, iface->adj_cnt); 410 free(netid); 411 break; 412 case IMSG_CTL_END: 413 printf("\n"); 414 return (1); 415 default: 416 break; 417 } 418 419 return (0); 420 } 421 422 int 423 show_interface_detail_msg(struct imsg *imsg) 424 { 425 struct ctl_iface *iface; 426 427 switch (imsg->hdr.type) { 428 case IMSG_CTL_SHOW_INTERFACE: 429 iface = imsg->data; 430 printf("\n"); 431 printf("Interface %s, line protocol is %s\n", 432 iface->name, print_link(iface->flags)); 433 printf(" Internet address %s/%d, ", 434 inet_ntoa(iface->addr), 435 mask2prefixlen(iface->mask.s_addr)); 436 printf("Area %s\n", inet_ntoa(iface->area)); 437 printf(" Linkstate %s,", 438 get_linkstate(iface->if_type, iface->linkstate)); 439 printf(" mtu %d\n", iface->mtu); 440 printf(" Router ID %s, network type %s, cost: %d\n", 441 inet_ntoa(iface->rtr_id), 442 if_type_name(iface->type), iface->metric); 443 printf(" Transmit delay is %d sec(s), state %s, priority %d\n", 444 iface->transmit_delay, if_state_name(iface->state), 445 iface->priority); 446 printf(" Designated Router (ID) %s, ", 447 inet_ntoa(iface->dr_id)); 448 printf("interface address %s\n", inet_ntoa(iface->dr_addr)); 449 printf(" Backup Designated Router (ID) %s, ", 450 inet_ntoa(iface->bdr_id)); 451 printf("interface address %s\n", inet_ntoa(iface->bdr_addr)); 452 if (iface->dead_interval == FAST_RTR_DEAD_TIME) { 453 printf(" Timer intervals configured, " 454 "hello %d msec, dead %d, wait %d, retransmit %d\n", 455 iface->fast_hello_interval, iface->dead_interval, 456 iface->dead_interval, iface->rxmt_interval); 457 458 } else { 459 printf(" Timer intervals configured, " 460 "hello %d, dead %d, wait %d, retransmit %d\n", 461 iface->hello_interval, iface->dead_interval, 462 iface->dead_interval, iface->rxmt_interval); 463 } 464 if (iface->passive) 465 printf(" Passive interface (No Hellos)\n"); 466 else if (iface->hello_timer.tv_sec < 0) 467 printf(" Hello timer not running\n"); 468 else 469 printf(" Hello timer due in %s+%ldmsec\n", 470 fmt_timeframe_core(iface->hello_timer.tv_sec), 471 iface->hello_timer.tv_usec / 1000); 472 printf(" Uptime %s\n", fmt_timeframe_core(iface->uptime)); 473 printf(" Neighbor count is %d, adjacent neighbor count is " 474 "%d\n", iface->nbr_cnt, iface->adj_cnt); 475 if (iface->auth_type > 0) { 476 switch (iface->auth_type) { 477 case AUTH_SIMPLE: 478 printf(" Simple password authentication " 479 "enabled\n"); 480 break; 481 case AUTH_CRYPT: 482 printf(" Message digest authentication " 483 "enabled\n"); 484 printf(" Primary key id is %d\n", 485 iface->auth_keyid); 486 break; 487 default: 488 break; 489 } 490 } 491 break; 492 case IMSG_CTL_END: 493 printf("\n"); 494 return (1); 495 default: 496 break; 497 } 498 499 return (0); 500 } 501 502 const char * 503 print_link(int state) 504 { 505 if (state & IFF_UP) 506 return ("UP"); 507 else 508 return ("DOWN"); 509 } 510 511 #define TF_BUFS 8 512 #define TF_LEN 9 513 514 const char * 515 fmt_timeframe(time_t t) 516 { 517 if (t == 0) 518 return ("Never"); 519 else 520 return (fmt_timeframe_core(time(NULL) - t)); 521 } 522 523 const char * 524 fmt_timeframe_core(time_t t) 525 { 526 char *buf; 527 static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 528 static int idx = 0; 529 unsigned int sec, min, hrs, day; 530 unsigned long long week; 531 532 if (t == 0) 533 return ("00:00:00"); 534 535 buf = tfbuf[idx++]; 536 if (idx == TF_BUFS) 537 idx = 0; 538 539 week = t; 540 541 sec = week % 60; 542 week /= 60; 543 min = week % 60; 544 week /= 60; 545 hrs = week % 24; 546 week /= 24; 547 day = week % 7; 548 week /= 7; 549 550 if (week > 0) 551 snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs); 552 else if (day > 0) 553 snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 554 else 555 snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 556 557 return (buf); 558 } 559 560 const char * 561 log_id(u_int32_t id) 562 { 563 static char buf[48]; 564 struct in_addr addr; 565 566 addr.s_addr = id; 567 568 if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 569 return ("?"); 570 else 571 return (buf); 572 } 573 574 const char * 575 log_adv_rtr(u_int32_t adv_rtr) 576 { 577 static char buf[48]; 578 struct in_addr addr; 579 580 addr.s_addr = adv_rtr; 581 582 if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 583 return ("?"); 584 else 585 return (buf); 586 } 587 588 /* prototype defined in ospfd.h and shared with the kroute.c version */ 589 u_int8_t 590 mask2prefixlen(in_addr_t ina) 591 { 592 if (ina == 0) 593 return (0); 594 else 595 return (33 - ffs(ntohl(ina))); 596 } 597 598 void 599 show_database_head(struct in_addr aid, char *ifname, u_int8_t type) 600 { 601 char *header, *format; 602 int cleanup = 0; 603 604 switch (type) { 605 case LSA_TYPE_ROUTER: 606 format = "Router Link States"; 607 break; 608 case LSA_TYPE_NETWORK: 609 format = "Net Link States"; 610 break; 611 case LSA_TYPE_SUM_NETWORK: 612 format = "Summary Net Link States"; 613 break; 614 case LSA_TYPE_SUM_ROUTER: 615 format = "Summary Router Link States"; 616 break; 617 case LSA_TYPE_EXTERNAL: 618 format = NULL; 619 if ((header = strdup("Type-5 AS External Link States")) == NULL) 620 err(1, NULL); 621 break; 622 case LSA_TYPE_LINK_OPAQ: 623 format = "Type-9 Link Local Opaque Link States"; 624 break; 625 case LSA_TYPE_AREA_OPAQ: 626 format = "Type-10 Area Local Opaque Link States"; 627 break; 628 case LSA_TYPE_AS_OPAQ: 629 format = NULL; 630 if ((header = strdup("Type-11 AS Wide Opaque Link States")) == 631 NULL) 632 err(1, NULL); 633 break; 634 default: 635 if (asprintf(&format, "LSA type %x", ntohs(type)) == -1) 636 err(1, NULL); 637 cleanup = 1; 638 break; 639 } 640 if (type == LSA_TYPE_LINK_OPAQ) { 641 if (asprintf(&header, "%s (Area %s Interface %s)", format, 642 inet_ntoa(aid), ifname) == -1) 643 err(1, NULL); 644 } else if (type != LSA_TYPE_EXTERNAL && type != LSA_TYPE_AS_OPAQ) 645 if (asprintf(&header, "%s (Area %s)", format, 646 inet_ntoa(aid)) == -1) 647 err(1, NULL); 648 649 printf("\n%-15s %s\n\n", "", header); 650 free(header); 651 if (cleanup) 652 free(format); 653 } 654 655 int 656 show_database_msg(struct imsg *imsg) 657 { 658 static struct in_addr area_id; 659 static char ifname[IF_NAMESIZE]; 660 static u_int8_t lasttype; 661 struct area *area; 662 struct iface *iface; 663 struct lsa_hdr *lsa; 664 665 switch (imsg->hdr.type) { 666 case IMSG_CTL_SHOW_DATABASE: 667 case IMSG_CTL_SHOW_DB_SELF: 668 lsa = imsg->data; 669 if (lsa->type != lasttype) { 670 show_database_head(area_id, ifname, lsa->type); 671 printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID", 672 "Adv Router", "Age", "Seq#", "Checksum"); 673 } 674 printf("%-15s %-15s %-4d 0x%08x 0x%04x\n", 675 log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr), 676 ntohs(lsa->age), ntohl(lsa->seq_num), 677 ntohs(lsa->ls_chksum)); 678 lasttype = lsa->type; 679 break; 680 case IMSG_CTL_AREA: 681 area = imsg->data; 682 area_id = area->id; 683 lasttype = 0; 684 break; 685 case IMSG_CTL_IFACE: 686 iface = imsg->data; 687 strlcpy(ifname, iface->name, sizeof(ifname)); 688 lasttype = 0; 689 break; 690 case IMSG_CTL_END: 691 printf("\n"); 692 return (1); 693 default: 694 break; 695 } 696 697 return (0); 698 } 699 700 char * 701 print_ls_type(u_int8_t type) 702 { 703 switch (type) { 704 case LSA_TYPE_ROUTER: 705 return ("Router"); 706 case LSA_TYPE_NETWORK: 707 return ("Network"); 708 case LSA_TYPE_SUM_NETWORK: 709 return ("Summary (Network)"); 710 case LSA_TYPE_SUM_ROUTER: 711 return ("Summary (Router)"); 712 case LSA_TYPE_EXTERNAL: 713 return ("AS External"); 714 case LSA_TYPE_LINK_OPAQ: 715 return ("Type-9 Opaque"); 716 case LSA_TYPE_AREA_OPAQ: 717 return ("Type-10 Opaque"); 718 case LSA_TYPE_AS_OPAQ: 719 return ("Type-11 Opaque"); 720 default: 721 return ("Unknown"); 722 } 723 } 724 725 void 726 show_db_hdr_msg_detail(struct lsa_hdr *lsa) 727 { 728 printf("LS age: %d\n", ntohs(lsa->age)); 729 printf("Options: %s\n", print_ospf_options(lsa->opts)); 730 printf("LS Type: %s\n", print_ls_type(lsa->type)); 731 732 switch (lsa->type) { 733 case LSA_TYPE_ROUTER: 734 printf("Link State ID: %s\n", log_id(lsa->ls_id)); 735 break; 736 case LSA_TYPE_NETWORK: 737 printf("Link State ID: %s (address of Designated Router)\n", 738 log_id(lsa->ls_id)); 739 break; 740 case LSA_TYPE_SUM_NETWORK: 741 printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id)); 742 break; 743 case LSA_TYPE_SUM_ROUTER: 744 printf("Link State ID: %s (ASBR Router ID)\n", 745 log_id(lsa->ls_id)); 746 break; 747 case LSA_TYPE_EXTERNAL: 748 printf("Link State ID: %s (External Network Number)\n", 749 log_id(lsa->ls_id)); 750 break; 751 case LSA_TYPE_LINK_OPAQ: 752 case LSA_TYPE_AREA_OPAQ: 753 case LSA_TYPE_AS_OPAQ: 754 printf("Link State ID: %s Type %d ID %d\n", log_id(lsa->ls_id), 755 LSA_24_GETHI(ntohl(lsa->ls_id)), 756 LSA_24_GETLO(ntohl(lsa->ls_id))); 757 break; 758 } 759 760 printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr)); 761 printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num)); 762 printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum)); 763 printf("Length: %d\n", ntohs(lsa->len)); 764 } 765 766 char * 767 print_rtr_link_type(u_int8_t type) 768 { 769 switch (type) { 770 case LINK_TYPE_POINTTOPOINT: 771 return ("Point-to-Point"); 772 case LINK_TYPE_TRANSIT_NET: 773 return ("Transit Network"); 774 case LINK_TYPE_STUB_NET: 775 return ("Stub Network"); 776 case LINK_TYPE_VIRTUAL: 777 return ("Virtual Link"); 778 default: 779 return ("Unknown"); 780 } 781 } 782 783 const char * 784 print_ospf_flags(u_int8_t opts) 785 { 786 static char optbuf[32]; 787 788 snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s", 789 opts & OSPF_RTR_V ? "V" : "-", 790 opts & OSPF_RTR_E ? "E" : "-", 791 opts & OSPF_RTR_B ? "B" : "-"); 792 return (optbuf); 793 } 794 795 int 796 show_db_msg_detail(struct imsg *imsg) 797 { 798 static struct in_addr area_id; 799 static char ifname[IF_NAMESIZE]; 800 static u_int8_t lasttype; 801 struct in_addr addr, data; 802 struct area *area; 803 struct iface *iface; 804 struct lsa *lsa; 805 struct lsa_rtr_link *rtr_link; 806 struct lsa_asext *asext; 807 u_int16_t i, nlinks, off; 808 809 /* XXX sanity checks! */ 810 811 switch (imsg->hdr.type) { 812 case IMSG_CTL_SHOW_DB_EXT: 813 lsa = imsg->data; 814 if (lsa->hdr.type != lasttype) 815 show_database_head(area_id, ifname, lsa->hdr.type); 816 show_db_hdr_msg_detail(&lsa->hdr); 817 addr.s_addr = lsa->data.asext.mask; 818 printf("Network Mask: %s\n", inet_ntoa(addr)); 819 820 asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr)); 821 822 printf(" Metric type: "); 823 if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) 824 printf("2\n"); 825 else 826 printf("1\n"); 827 printf(" Metric: %d\n", ntohl(asext->metric) 828 & LSA_METRIC_MASK); 829 addr.s_addr = asext->fw_addr; 830 printf(" Forwarding Address: %s\n", inet_ntoa(addr)); 831 printf(" External Route Tag: %d\n\n", ntohl(asext->ext_tag)); 832 833 lasttype = lsa->hdr.type; 834 break; 835 case IMSG_CTL_SHOW_DB_NET: 836 lsa = imsg->data; 837 if (lsa->hdr.type != lasttype) 838 show_database_head(area_id, ifname, lsa->hdr.type); 839 show_db_hdr_msg_detail(&lsa->hdr); 840 addr.s_addr = lsa->data.net.mask; 841 printf("Network Mask: %s\n", inet_ntoa(addr)); 842 843 nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) 844 - sizeof(u_int32_t)) / sizeof(struct lsa_net_link); 845 off = sizeof(lsa->hdr) + sizeof(u_int32_t); 846 printf("Number of Routers: %d\n", nlinks); 847 848 for (i = 0; i < nlinks; i++) { 849 addr.s_addr = lsa->data.net.att_rtr[i]; 850 printf(" Attached Router: %s\n", inet_ntoa(addr)); 851 } 852 853 printf("\n"); 854 lasttype = lsa->hdr.type; 855 break; 856 case IMSG_CTL_SHOW_DB_RTR: 857 lsa = imsg->data; 858 if (lsa->hdr.type != lasttype) 859 show_database_head(area_id, ifname, lsa->hdr.type); 860 show_db_hdr_msg_detail(&lsa->hdr); 861 printf("Flags: %s\n", print_ospf_flags(lsa->data.rtr.flags)); 862 nlinks = ntohs(lsa->data.rtr.nlinks); 863 printf("Number of Links: %d\n\n", nlinks); 864 865 off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr); 866 867 for (i = 0; i < nlinks; i++) { 868 rtr_link = (struct lsa_rtr_link *)((char *)lsa + off); 869 870 printf(" Link connected to: %s\n", 871 print_rtr_link_type(rtr_link->type)); 872 873 addr.s_addr = rtr_link->id; 874 data.s_addr = rtr_link->data; 875 876 switch (rtr_link->type) { 877 case LINK_TYPE_POINTTOPOINT: 878 case LINK_TYPE_VIRTUAL: 879 printf(" Link ID (Neighbors Router ID):" 880 " %s\n", inet_ntoa(addr)); 881 printf(" Link Data (Router Interface " 882 "address): %s\n", inet_ntoa(data)); 883 break; 884 case LINK_TYPE_TRANSIT_NET: 885 printf(" Link ID (Designated Router " 886 "address): %s\n", inet_ntoa(addr)); 887 printf(" Link Data (Router Interface " 888 "address): %s\n", inet_ntoa(data)); 889 break; 890 case LINK_TYPE_STUB_NET: 891 printf(" Link ID (Network ID): %s\n", 892 inet_ntoa(addr)); 893 printf(" Link Data (Network Mask): %s\n", 894 inet_ntoa(data)); 895 break; 896 default: 897 printf(" Link ID (Unknown): %s\n", 898 inet_ntoa(addr)); 899 printf(" Link Data (Unknown): %s\n", 900 inet_ntoa(data)); 901 break; 902 } 903 904 printf(" Metric: %d\n\n", ntohs(rtr_link->metric)); 905 906 off += sizeof(struct lsa_rtr_link) + 907 rtr_link->num_tos * sizeof(u_int32_t); 908 } 909 910 lasttype = lsa->hdr.type; 911 break; 912 case IMSG_CTL_SHOW_DB_SUM: 913 case IMSG_CTL_SHOW_DB_ASBR: 914 lsa = imsg->data; 915 if (lsa->hdr.type != lasttype) 916 show_database_head(area_id, ifname, lsa->hdr.type); 917 show_db_hdr_msg_detail(&lsa->hdr); 918 addr.s_addr = lsa->data.sum.mask; 919 printf("Network Mask: %s\n", inet_ntoa(addr)); 920 printf("Metric: %d\n\n", ntohl(lsa->data.sum.metric) & 921 LSA_METRIC_MASK); 922 lasttype = lsa->hdr.type; 923 break; 924 case IMSG_CTL_SHOW_DB_OPAQ: 925 lsa = imsg->data; 926 if (lsa->hdr.type != lasttype) 927 show_database_head(area_id, ifname, lsa->hdr.type); 928 show_db_hdr_msg_detail(&lsa->hdr); 929 /* XXX should we hexdump the data? */ 930 lasttype = lsa->hdr.type; 931 break; 932 case IMSG_CTL_AREA: 933 area = imsg->data; 934 area_id = area->id; 935 lasttype = 0; 936 break; 937 case IMSG_CTL_IFACE: 938 iface = imsg->data; 939 strlcpy(ifname, iface->name, sizeof(ifname)); 940 lasttype = 0; 941 break; 942 case IMSG_CTL_END: 943 return (1); 944 default: 945 break; 946 } 947 948 return (0); 949 } 950 951 int 952 show_nbr_msg(struct imsg *imsg) 953 { 954 struct ctl_nbr *nbr; 955 char *state; 956 957 switch (imsg->hdr.type) { 958 case IMSG_CTL_SHOW_NBR: 959 nbr = imsg->data; 960 if (asprintf(&state, "%s/%s", nbr_state_name(nbr->nbr_state), 961 if_state_name(nbr->iface_state)) == -1) 962 err(1, NULL); 963 printf("%-15s %-3d %-12s %-9s", inet_ntoa(nbr->id), 964 nbr->priority, state, fmt_timeframe_core(nbr->dead_timer)); 965 printf("%-15s %-9s %s\n", inet_ntoa(nbr->addr), nbr->name, 966 nbr->uptime == 0 ? "-" : fmt_timeframe_core(nbr->uptime)); 967 free(state); 968 break; 969 case IMSG_CTL_END: 970 printf("\n"); 971 return (1); 972 default: 973 break; 974 } 975 976 return (0); 977 } 978 979 const char * 980 print_ospf_options(u_int8_t opts) 981 { 982 static char optbuf[32]; 983 984 snprintf(optbuf, sizeof(optbuf), "%s|%s|%s|%s|%s|%s|%s|%s", 985 opts & OSPF_OPTION_DN ? "DN" : "-", 986 opts & OSPF_OPTION_O ? "O" : "-", 987 opts & OSPF_OPTION_DC ? "DC" : "-", 988 opts & OSPF_OPTION_EA ? "EA" : "-", 989 opts & OSPF_OPTION_NP ? "N/P" : "-", 990 opts & OSPF_OPTION_MC ? "MC" : "-", 991 opts & OSPF_OPTION_E ? "E" : "-", 992 opts & OSPF_OPTION_MT ? "MT" : "-"); 993 return (optbuf); 994 } 995 996 int 997 show_nbr_detail_msg(struct imsg *imsg) 998 { 999 struct ctl_nbr *nbr; 1000 1001 switch (imsg->hdr.type) { 1002 case IMSG_CTL_SHOW_NBR: 1003 nbr = imsg->data; 1004 printf("\nNeighbor %s, ", inet_ntoa(nbr->id)); 1005 printf("interface address %s\n", inet_ntoa(nbr->addr)); 1006 printf(" Area %s, interface %s\n", inet_ntoa(nbr->area), 1007 nbr->name); 1008 printf(" Neighbor priority is %d, " 1009 "State is %s, %d state changes\n", 1010 nbr->priority, nbr_state_name(nbr->nbr_state), 1011 nbr->state_chng_cnt); 1012 printf(" DR is %s, ", inet_ntoa(nbr->dr)); 1013 printf("BDR is %s\n", inet_ntoa(nbr->bdr)); 1014 printf(" Options %s\n", print_ospf_options(nbr->options)); 1015 printf(" Dead timer due in %s\n", 1016 fmt_timeframe_core(nbr->dead_timer)); 1017 printf(" Uptime %s\n", fmt_timeframe_core(nbr->uptime)); 1018 printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt); 1019 printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt); 1020 printf(" Link State Retransmission List %d\n", 1021 nbr->ls_retrans_lst_cnt); 1022 break; 1023 case IMSG_CTL_END: 1024 printf("\n"); 1025 return (1); 1026 default: 1027 break; 1028 } 1029 1030 return (0); 1031 } 1032 1033 int 1034 show_rib_msg(struct imsg *imsg) 1035 { 1036 struct ctl_rt *rt; 1037 char *dstnet; 1038 1039 switch (imsg->hdr.type) { 1040 case IMSG_CTL_SHOW_RIB: 1041 rt = imsg->data; 1042 switch (rt->d_type) { 1043 case DT_NET: 1044 if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), 1045 rt->prefixlen) == -1) 1046 err(1, NULL); 1047 break; 1048 case DT_RTR: 1049 if (asprintf(&dstnet, "%s", 1050 inet_ntoa(rt->prefix)) == -1) 1051 err(1, NULL); 1052 break; 1053 default: 1054 errx(1, "Invalid route type"); 1055 } 1056 1057 printf("%-20s %-16s%s %-12s %-9s %-7d %s\n", dstnet, 1058 inet_ntoa(rt->nexthop), rt->connected ? "C" : " ", 1059 path_type_name(rt->p_type), 1060 dst_type_name(rt->d_type), rt->cost, 1061 rt->uptime == 0 ? "-" : fmt_timeframe_core(rt->uptime)); 1062 free(dstnet); 1063 break; 1064 case IMSG_CTL_END: 1065 printf("\n"); 1066 return (1); 1067 default: 1068 break; 1069 } 1070 1071 return (0); 1072 } 1073 1074 void 1075 show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) 1076 { 1077 char *header, *format, *format2; 1078 1079 switch (p_type) { 1080 case PT_INTRA_AREA: 1081 case PT_INTER_AREA: 1082 switch (d_type) { 1083 case DT_NET: 1084 format = "Network Routing Table"; 1085 format2 = ""; 1086 break; 1087 case DT_RTR: 1088 format = "Router Routing Table"; 1089 format2 = "Type"; 1090 break; 1091 default: 1092 errx(1, "unknown route type"); 1093 } 1094 break; 1095 case PT_TYPE1_EXT: 1096 case PT_TYPE2_EXT: 1097 format = NULL; 1098 format2 = "Cost 2"; 1099 if ((header = strdup("External Routing Table")) == NULL) 1100 err(1, NULL); 1101 break; 1102 default: 1103 errx(1, "unknown route type"); 1104 } 1105 1106 if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) 1107 if (asprintf(&header, "%s (Area %s)", format, 1108 inet_ntoa(aid)) == -1) 1109 err(1, NULL); 1110 1111 printf("\n%-18s %s\n", "", header); 1112 free(header); 1113 1114 printf("\n%-18s %-15s %-15s %-12s %-7s %-7s\n", "Destination", 1115 "Nexthop", "Adv Router", "Path type", "Cost", format2); 1116 } 1117 1118 const char * 1119 print_ospf_rtr_flags(u_int8_t opts) 1120 { 1121 static char optbuf[32]; 1122 1123 snprintf(optbuf, sizeof(optbuf), "%s%s%s", 1124 opts & OSPF_RTR_E ? "AS" : "", 1125 opts & OSPF_RTR_E && opts & OSPF_RTR_B ? "+" : "", 1126 opts & OSPF_RTR_B ? "ABR" : ""); 1127 return (optbuf); 1128 } 1129 1130 int 1131 show_rib_detail_msg(struct imsg *imsg) 1132 { 1133 static struct in_addr area_id; 1134 struct ctl_rt *rt; 1135 struct area *area; 1136 char *dstnet; 1137 static u_int8_t lasttype; 1138 1139 switch (imsg->hdr.type) { 1140 case IMSG_CTL_SHOW_RIB: 1141 rt = imsg->data; 1142 1143 switch (rt->p_type) { 1144 case PT_INTRA_AREA: 1145 case PT_INTER_AREA: 1146 switch (rt->d_type) { 1147 case DT_NET: 1148 if (lasttype != RIB_NET) 1149 show_rib_head(rt->area, rt->d_type, 1150 rt->p_type); 1151 if (asprintf(&dstnet, "%s/%d", 1152 inet_ntoa(rt->prefix), rt->prefixlen) == -1) 1153 err(1, NULL); 1154 lasttype = RIB_NET; 1155 break; 1156 case DT_RTR: 1157 if (lasttype != RIB_RTR) 1158 show_rib_head(rt->area, rt->d_type, 1159 rt->p_type); 1160 if (asprintf(&dstnet, "%s", 1161 inet_ntoa(rt->prefix)) == -1) 1162 err(1, NULL); 1163 lasttype = RIB_RTR; 1164 break; 1165 default: 1166 errx(1, "unknown route type"); 1167 } 1168 printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); 1169 printf("%-15s %-12s %-7d", inet_ntoa(rt->adv_rtr), 1170 path_type_name(rt->p_type), rt->cost); 1171 free(dstnet); 1172 1173 if (rt->d_type == DT_RTR) 1174 printf(" %-7s", 1175 print_ospf_rtr_flags(rt->flags)); 1176 1177 printf("\n"); 1178 break; 1179 case PT_TYPE1_EXT: 1180 case PT_TYPE2_EXT: 1181 if (lasttype != RIB_EXT) 1182 show_rib_head(rt->area, rt->d_type, rt->p_type); 1183 1184 if (asprintf(&dstnet, "%s/%d", 1185 inet_ntoa(rt->prefix), rt->prefixlen) == -1) 1186 err(1, NULL); 1187 1188 printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); 1189 printf("%-15s %-12s %-7d %-7d\n", 1190 inet_ntoa(rt->adv_rtr), path_type_name(rt->p_type), 1191 rt->cost, rt->cost2); 1192 free(dstnet); 1193 1194 lasttype = RIB_EXT; 1195 break; 1196 default: 1197 errx(1, "unknown route type"); 1198 } 1199 break; 1200 case IMSG_CTL_AREA: 1201 area = imsg->data; 1202 area_id = area->id; 1203 break; 1204 case IMSG_CTL_END: 1205 printf("\n"); 1206 return (1); 1207 default: 1208 break; 1209 } 1210 1211 return (0); 1212 } 1213 1214 void 1215 show_fib_head(void) 1216 { 1217 printf("flags: * = valid, O = OSPF, C = Connected, S = Static\n"); 1218 printf("%-6s %-4s %-20s %-17s\n", "Flags", "Prio", "Destination", "Nexthop"); 1219 } 1220 1221 int 1222 show_fib_msg(struct imsg *imsg) 1223 { 1224 struct kroute *k; 1225 char *p; 1226 1227 switch (imsg->hdr.type) { 1228 case IMSG_CTL_KROUTE: 1229 if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) 1230 errx(1, "wrong imsg len"); 1231 k = imsg->data; 1232 1233 if (k->flags & F_DOWN) 1234 printf(" "); 1235 else 1236 printf("*"); 1237 1238 if (!(k->flags & F_KERNEL)) 1239 printf("O"); 1240 else if (k->flags & F_CONNECTED) 1241 printf("C"); 1242 else if (k->flags & F_STATIC) 1243 printf("S"); 1244 else 1245 printf(" "); 1246 1247 printf(" "); 1248 printf("%4d ", k->priority); 1249 if (asprintf(&p, "%s/%u", inet_ntoa(k->prefix), k->prefixlen) == 1250 -1) 1251 err(1, NULL); 1252 printf("%-20s ", p); 1253 free(p); 1254 1255 if (k->nexthop.s_addr) 1256 printf("%s", inet_ntoa(k->nexthop)); 1257 else if (k->flags & F_CONNECTED) 1258 printf("link#%u", k->ifindex); 1259 printf("\n"); 1260 1261 break; 1262 case IMSG_CTL_END: 1263 printf("\n"); 1264 return (1); 1265 default: 1266 break; 1267 } 1268 1269 return (0); 1270 } 1271 1272 void 1273 show_interface_head(void) 1274 { 1275 printf("%-15s%-15s%s\n", "Interface", "Flags", 1276 "Link state"); 1277 } 1278 1279 const struct if_status_description 1280 if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; 1281 const struct ifmedia_description 1282 ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; 1283 1284 const char * 1285 get_media_descr(uint64_t media_type) 1286 { 1287 const struct ifmedia_description *p; 1288 1289 for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) 1290 if (media_type == p->ifmt_word) 1291 return (p->ifmt_string); 1292 1293 return ("unknown"); 1294 } 1295 1296 const char * 1297 get_linkstate(uint8_t if_type, int link_state) 1298 { 1299 const struct if_status_description *p; 1300 static char buf[8]; 1301 1302 for (p = if_status_descriptions; p->ifs_string != NULL; p++) { 1303 if (LINK_STATE_DESC_MATCH(p, if_type, link_state)) 1304 return (p->ifs_string); 1305 } 1306 snprintf(buf, sizeof(buf), "[#%d]", link_state); 1307 return (buf); 1308 } 1309 1310 void 1311 print_baudrate(u_int64_t baudrate) 1312 { 1313 if (baudrate > IF_Gbps(1)) 1314 printf("%llu GBit/s", baudrate / IF_Gbps(1)); 1315 else if (baudrate > IF_Mbps(1)) 1316 printf("%llu MBit/s", baudrate / IF_Mbps(1)); 1317 else if (baudrate > IF_Kbps(1)) 1318 printf("%llu KBit/s", baudrate / IF_Kbps(1)); 1319 else 1320 printf("%llu Bit/s", baudrate); 1321 } 1322 1323 int 1324 show_fib_interface_msg(struct imsg *imsg) 1325 { 1326 struct kif *k; 1327 uint64_t ifms_type; 1328 1329 switch (imsg->hdr.type) { 1330 case IMSG_CTL_IFINFO: 1331 k = imsg->data; 1332 printf("%-15s", k->ifname); 1333 printf("%-15s", k->flags & IFF_UP ? "UP" : ""); 1334 ifms_type = get_ifms_type(k->if_type); 1335 if (ifms_type) 1336 printf("%s, ", get_media_descr(ifms_type)); 1337 1338 printf("%s", get_linkstate(k->if_type, k->link_state)); 1339 1340 if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { 1341 printf(", "); 1342 print_baudrate(k->baudrate); 1343 } 1344 printf("\n"); 1345 break; 1346 case IMSG_CTL_END: 1347 printf("\n"); 1348 return (1); 1349 default: 1350 break; 1351 } 1352 1353 return (0); 1354 } 1355