1*ec107b41Sremi /* $OpenBSD: ospfctl.c,v 1.65 2018/07/11 12:09:34 remi Exp $ */ 2b49634deSclaudio 3b49634deSclaudio /* 4b49634deSclaudio * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 537355230Snorby * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> 6b49634deSclaudio * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> 7b49634deSclaudio * 8b49634deSclaudio * Permission to use, copy, modify, and distribute this software for any 9b49634deSclaudio * purpose with or without fee is hereby granted, provided that the above 10b49634deSclaudio * copyright notice and this permission notice appear in all copies. 11b49634deSclaudio * 12b49634deSclaudio * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13b49634deSclaudio * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14b49634deSclaudio * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15b49634deSclaudio * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16b49634deSclaudio * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17b49634deSclaudio * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18b49634deSclaudio * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19b49634deSclaudio */ 20b49634deSclaudio 21b49634deSclaudio #include <sys/types.h> 22b49634deSclaudio #include <sys/socket.h> 23b49634deSclaudio #include <sys/un.h> 24b49634deSclaudio #include <netinet/in.h> 25b49634deSclaudio #include <arpa/inet.h> 26c47b7f65Sclaudio #include <net/if_media.h> 27c47b7f65Sclaudio #include <net/if_types.h> 28b49634deSclaudio 29b49634deSclaudio #include <err.h> 30c0dbf5cfSsthen #include <errno.h> 31b49634deSclaudio #include <stdio.h> 32b49634deSclaudio #include <stdlib.h> 33b49634deSclaudio #include <string.h> 34b49634deSclaudio #include <unistd.h> 35b49634deSclaudio 36b49634deSclaudio #include "ospf.h" 37b49634deSclaudio #include "ospfd.h" 38b49634deSclaudio #include "ospfe.h" 39b49634deSclaudio #include "parser.h" 40b49634deSclaudio 41cbb557dbShenning __dead void usage(void); 4259df52c7Snorby int show_summary_msg(struct imsg *); 4318ffdd94Sstsp uint64_t get_ifms_type(uint8_t); 44b49634deSclaudio int show_interface_msg(struct imsg *); 4512bb42a0Snorby int show_interface_detail_msg(struct imsg *); 46b49634deSclaudio const char *print_link(int); 47b49634deSclaudio const char *fmt_timeframe(time_t t); 48b49634deSclaudio const char *fmt_timeframe_core(time_t t); 49b49634deSclaudio const char *log_id(u_int32_t ); 50b49634deSclaudio const char *log_adv_rtr(u_int32_t); 5197494e25Sclaudio void show_database_head(struct in_addr, char *, u_int8_t); 52b49634deSclaudio int show_database_msg(struct imsg *); 5332286112Snorby char *print_ls_type(u_int8_t); 5432286112Snorby void show_db_hdr_msg_detail(struct lsa_hdr *); 5532286112Snorby char *print_rtr_link_type(u_int8_t); 5632286112Snorby const char *print_ospf_flags(u_int8_t); 5732286112Snorby int show_db_msg_detail(struct imsg *imsg); 58b49634deSclaudio int show_nbr_msg(struct imsg *); 59b49634deSclaudio const char *print_ospf_options(u_int8_t); 60b49634deSclaudio int show_nbr_detail_msg(struct imsg *); 6137355230Snorby int show_rib_msg(struct imsg *); 6237355230Snorby void show_rib_head(struct in_addr, u_int8_t, u_int8_t); 6391e3b0aeSnorby const char *print_ospf_rtr_flags(u_int8_t); 6437355230Snorby int show_rib_detail_msg(struct imsg *); 65c47b7f65Sclaudio void show_fib_head(void); 66c47b7f65Sclaudio int show_fib_msg(struct imsg *); 67c47b7f65Sclaudio void show_interface_head(void); 68e5605ae3Sderaadt const char * get_media_descr(uint64_t); 6918ffdd94Sstsp const char * get_linkstate(uint8_t, int); 7056babc06Sclaudio void print_baudrate(u_int64_t); 71c47b7f65Sclaudio int show_fib_interface_msg(struct imsg *); 72b49634deSclaudio 73b49634deSclaudio struct imsgbuf *ibuf; 74b49634deSclaudio 75cbb557dbShenning __dead void 76b49634deSclaudio usage(void) 77b49634deSclaudio { 78b49634deSclaudio extern char *__progname; 79b49634deSclaudio 80d1b94773Sreyk fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n", 81d1b94773Sreyk __progname); 82b49634deSclaudio exit(1); 83b49634deSclaudio } 84b49634deSclaudio 85b49634deSclaudio int 86b49634deSclaudio main(int argc, char *argv[]) 87b49634deSclaudio { 88b49634deSclaudio struct sockaddr_un sun; 89b49634deSclaudio struct parse_result *res; 90b49634deSclaudio struct imsg imsg; 91b49634deSclaudio unsigned int ifidx = 0; 92*ec107b41Sremi int ctl_sock, r; 93b49634deSclaudio int done = 0; 94c3319070Sclaudio int n, verbose = 0; 95d1b94773Sreyk int ch; 96d1b94773Sreyk char *sockname; 97d1b94773Sreyk 98*ec107b41Sremi r = getrtable(); 99*ec107b41Sremi if (asprintf(&sockname, "%s.%d", OSPFD_SOCKET, r) == -1) 100*ec107b41Sremi err(1, "asprintf"); 101*ec107b41Sremi 102d1b94773Sreyk while ((ch = getopt(argc, argv, "s:")) != -1) { 103d1b94773Sreyk switch (ch) { 104d1b94773Sreyk case 's': 105d1b94773Sreyk sockname = optarg; 106d1b94773Sreyk break; 107d1b94773Sreyk default: 108d1b94773Sreyk usage(); 109d1b94773Sreyk /* NOTREACHED */ 110d1b94773Sreyk } 111d1b94773Sreyk } 112d1b94773Sreyk argc -= optind; 113d1b94773Sreyk argv += optind; 114b49634deSclaudio 115b49634deSclaudio /* parse options */ 116d1b94773Sreyk if ((res = parse(argc, argv)) == NULL) 117b49634deSclaudio exit(1); 118b49634deSclaudio 119b49634deSclaudio /* connect to ospfd control socket */ 120b49634deSclaudio if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 121b49634deSclaudio err(1, "socket"); 122b49634deSclaudio 123b49634deSclaudio bzero(&sun, sizeof(sun)); 124b49634deSclaudio sun.sun_family = AF_UNIX; 125d1b94773Sreyk 126d1b94773Sreyk strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path)); 127b49634deSclaudio if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 128d1b94773Sreyk err(1, "connect: %s", sockname); 129b49634deSclaudio 13068598ea0Sderaadt if (pledge("stdio", NULL) == -1) 13168598ea0Sderaadt err(1, "pledge"); 13268598ea0Sderaadt 133b49634deSclaudio if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 134d2141824Sstevesk err(1, NULL); 1357b4c0c10Seric imsg_init(ibuf, ctl_sock); 136b49634deSclaudio done = 0; 137b49634deSclaudio 138b49634deSclaudio /* process user request */ 139b49634deSclaudio switch (res->action) { 140b49634deSclaudio case NONE: 141b49634deSclaudio usage(); 142b49634deSclaudio /* not reached */ 143b49634deSclaudio case SHOW: 14459df52c7Snorby case SHOW_SUM: 1457f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); 146b49634deSclaudio break; 147b49634deSclaudio case SHOW_IFACE: 14812bb42a0Snorby printf("%-11s %-18s %-6s %-10s %-10s %-8s %3s %3s\n", 14912bb42a0Snorby "Interface", "Address", "State", "HelloTimer", "Linkstate", 15012bb42a0Snorby "Uptime", "nc", "ac"); 151c5ba8b41Sderaadt /*FALLTHROUGH*/ 15212bb42a0Snorby case SHOW_IFACE_DTAIL: 153b49634deSclaudio if (*res->ifname) { 154b49634deSclaudio ifidx = if_nametoindex(res->ifname); 155b49634deSclaudio if (ifidx == 0) 156b49634deSclaudio errx(1, "no such interface %s", res->ifname); 157b49634deSclaudio } 1587f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 159b49634deSclaudio &ifidx, sizeof(ifidx)); 160b49634deSclaudio break; 161b49634deSclaudio case SHOW_NBR: 162129e6b5fSnorby printf("%-15s %-3s %-12s %-8s %-15s %-9s %s\n", "ID", "Pri", 163129e6b5fSnorby "State", "DeadTime", "Address", "Iface","Uptime"); 164c5ba8b41Sderaadt /*FALLTHROUGH*/ 165b49634deSclaudio case SHOW_NBR_DTAIL: 1667f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 167b49634deSclaudio break; 168b49634deSclaudio case SHOW_DB: 1697f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0); 170b49634deSclaudio break; 171b49634deSclaudio case SHOW_DBBYAREA: 1727f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, 173b49634deSclaudio &res->addr, sizeof(res->addr)); 174b49634deSclaudio break; 17532286112Snorby case SHOW_DBEXT: 1767f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0); 17732286112Snorby break; 17832286112Snorby case SHOW_DBNET: 1797f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0); 18032286112Snorby break; 18132286112Snorby case SHOW_DBRTR: 1827f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0); 18332286112Snorby break; 18432286112Snorby case SHOW_DBSELF: 1857f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0); 18632286112Snorby break; 18732286112Snorby case SHOW_DBSUM: 1887f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0); 18932286112Snorby break; 19032286112Snorby case SHOW_DBASBR: 1917f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0); 19232286112Snorby break; 19397494e25Sclaudio case SHOW_DBOPAQ: 19497494e25Sclaudio imsg_compose(ibuf, IMSG_CTL_SHOW_DB_OPAQ, 0, 0, -1, NULL, 0); 19597494e25Sclaudio break; 19637355230Snorby case SHOW_RIB: 1977aa44f3cSnorby printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", 1987aa44f3cSnorby "Nexthop", "Path Type", "Type", "Cost", "Uptime"); 199c5ba8b41Sderaadt /*FALLTHROUGH*/ 20037355230Snorby case SHOW_RIB_DTAIL: 2017f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); 20237355230Snorby break; 203c47b7f65Sclaudio case SHOW_FIB: 204c47b7f65Sclaudio if (!res->addr.s_addr) 2057f472484Spyr imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, 206c47b7f65Sclaudio &res->flags, sizeof(res->flags)); 207c47b7f65Sclaudio else 2087f472484Spyr imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, 209c47b7f65Sclaudio &res->addr, sizeof(res->addr)); 210c47b7f65Sclaudio show_fib_head(); 211c47b7f65Sclaudio break; 212c47b7f65Sclaudio case SHOW_FIB_IFACE: 2134c561fb6Sclaudio if (*res->ifname) 2147f472484Spyr imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, 2154c561fb6Sclaudio res->ifname, sizeof(res->ifname)); 2164c561fb6Sclaudio else 2177f472484Spyr imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0); 218c47b7f65Sclaudio show_interface_head(); 219c47b7f65Sclaudio break; 22073a141beSclaudio case FIB: 22173a141beSclaudio errx(1, "fib couple|decouple"); 22273a141beSclaudio break; 22373a141beSclaudio case FIB_COUPLE: 2247f472484Spyr imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0); 22573a141beSclaudio printf("couple request sent.\n"); 22673a141beSclaudio done = 1; 22773a141beSclaudio break; 22873a141beSclaudio case FIB_DECOUPLE: 2297f472484Spyr imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0); 23073a141beSclaudio printf("decouple request sent.\n"); 23173a141beSclaudio done = 1; 23273a141beSclaudio break; 233119f0f1dSdlg case FIB_RELOAD: 234119f0f1dSdlg imsg_compose(ibuf, IMSG_CTL_FIB_RELOAD, 0, 0, -1, NULL, 0); 235119f0f1dSdlg printf("reload request sent.\n"); 236119f0f1dSdlg done = 1; 237119f0f1dSdlg break; 238c3319070Sclaudio case LOG_VERBOSE: 239c3319070Sclaudio verbose = 1; 240c3319070Sclaudio /* FALLTHROUGH */ 241c3319070Sclaudio case LOG_BRIEF: 242c3319070Sclaudio imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, 243c3319070Sclaudio &verbose, sizeof(verbose)); 244c3319070Sclaudio printf("logging request sent.\n"); 245c3319070Sclaudio done = 1; 246c3319070Sclaudio break; 247b49634deSclaudio case RELOAD: 2487f472484Spyr imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 249b49634deSclaudio printf("reload request sent.\n"); 250b49634deSclaudio done = 1; 251b49634deSclaudio break; 252b49634deSclaudio } 253b49634deSclaudio 254b49634deSclaudio while (ibuf->w.queued) 255c0dbf5cfSsthen if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) 256b49634deSclaudio err(1, "write error"); 257b49634deSclaudio 258b49634deSclaudio while (!done) { 259cc37529cSclaudio if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 260b49634deSclaudio errx(1, "imsg_read error"); 261b49634deSclaudio if (n == 0) 262b49634deSclaudio errx(1, "pipe closed"); 263b49634deSclaudio 264b49634deSclaudio while (!done) { 265b49634deSclaudio if ((n = imsg_get(ibuf, &imsg)) == -1) 266b49634deSclaudio errx(1, "imsg_get error"); 267b49634deSclaudio if (n == 0) 268b49634deSclaudio break; 269b49634deSclaudio switch (res->action) { 270b49634deSclaudio case SHOW: 27159df52c7Snorby case SHOW_SUM: 27259df52c7Snorby done = show_summary_msg(&imsg); 273b49634deSclaudio break; 274b49634deSclaudio case SHOW_IFACE: 275b49634deSclaudio done = show_interface_msg(&imsg); 276b49634deSclaudio break; 27712bb42a0Snorby case SHOW_IFACE_DTAIL: 27812bb42a0Snorby done = show_interface_detail_msg(&imsg); 27912bb42a0Snorby break; 280b49634deSclaudio case SHOW_NBR: 281b49634deSclaudio done = show_nbr_msg(&imsg); 282b49634deSclaudio break; 283b49634deSclaudio case SHOW_NBR_DTAIL: 284b49634deSclaudio done = show_nbr_detail_msg(&imsg); 285b49634deSclaudio break; 286b49634deSclaudio case SHOW_DB: 287b49634deSclaudio case SHOW_DBBYAREA: 28832286112Snorby case SHOW_DBSELF: 289b49634deSclaudio done = show_database_msg(&imsg); 290b49634deSclaudio break; 29132286112Snorby case SHOW_DBEXT: 29232286112Snorby case SHOW_DBNET: 29332286112Snorby case SHOW_DBRTR: 29432286112Snorby case SHOW_DBSUM: 29532286112Snorby case SHOW_DBASBR: 29697494e25Sclaudio case SHOW_DBOPAQ: 29732286112Snorby done = show_db_msg_detail(&imsg); 29832286112Snorby break; 29937355230Snorby case SHOW_RIB: 30037355230Snorby done = show_rib_msg(&imsg); 30137355230Snorby break; 30237355230Snorby case SHOW_RIB_DTAIL: 30337355230Snorby done = show_rib_detail_msg(&imsg); 30437355230Snorby break; 305c47b7f65Sclaudio case SHOW_FIB: 306c47b7f65Sclaudio done = show_fib_msg(&imsg); 307c47b7f65Sclaudio break; 308c47b7f65Sclaudio case SHOW_FIB_IFACE: 309c47b7f65Sclaudio done = show_fib_interface_msg(&imsg); 310c47b7f65Sclaudio break; 311b49634deSclaudio case NONE: 31273a141beSclaudio case FIB: 31373a141beSclaudio case FIB_COUPLE: 31473a141beSclaudio case FIB_DECOUPLE: 315119f0f1dSdlg case FIB_RELOAD: 316c3319070Sclaudio case LOG_VERBOSE: 317c3319070Sclaudio case LOG_BRIEF: 318b49634deSclaudio case RELOAD: 319b49634deSclaudio break; 320b49634deSclaudio } 321b49634deSclaudio imsg_free(&imsg); 322b49634deSclaudio } 323b49634deSclaudio } 324b49634deSclaudio close(ctl_sock); 325b49634deSclaudio free(ibuf); 326b49634deSclaudio 327b49634deSclaudio return (0); 328b49634deSclaudio } 329b49634deSclaudio 330b49634deSclaudio int 33159df52c7Snorby show_summary_msg(struct imsg *imsg) 332b49634deSclaudio { 33359df52c7Snorby struct ctl_sum *sum; 33459df52c7Snorby struct ctl_sum_area *sumarea; 33559df52c7Snorby 33659df52c7Snorby switch (imsg->hdr.type) { 33759df52c7Snorby case IMSG_CTL_SHOW_SUM: 33859df52c7Snorby sum = imsg->data; 33959df52c7Snorby printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); 34011c16ffaSnorby printf("Uptime: %s\n", fmt_timeframe_core(sum->uptime)); 34159df52c7Snorby printf("RFC1583 compatibility flag is "); 34259df52c7Snorby if (sum->rfc1583compat) 34359df52c7Snorby printf("enabled\n"); 34459df52c7Snorby else 34559df52c7Snorby printf("disabled\n"); 34659df52c7Snorby 34737877ca4Sdlg printf("SPF delay is %d msec(s), hold time between two SPFs " 34837877ca4Sdlg "is %d msec(s)\n", sum->spf_delay, sum->spf_hold_time); 3490439e4c8Sclaudio printf("Number of external LSA(s) %d (Checksum sum 0x%x)\n", 3500439e4c8Sclaudio sum->num_ext_lsa, sum->ext_lsa_cksum); 35159df52c7Snorby printf("Number of areas attached to this router: %d\n", 35259df52c7Snorby sum->num_area); 35359df52c7Snorby break; 35459df52c7Snorby case IMSG_CTL_SHOW_SUM_AREA: 35559df52c7Snorby sumarea = imsg->data; 35659df52c7Snorby printf("\nArea ID: %s\n", inet_ntoa(sumarea->area)); 35759df52c7Snorby printf(" Number of interfaces in this area: %d\n", 35859df52c7Snorby sumarea->num_iface); 35959df52c7Snorby printf(" Number of fully adjacent neighbors in this " 36059df52c7Snorby "area: %d\n", sumarea->num_adj_nbr); 36159df52c7Snorby printf(" SPF algorithm executed %d time(s)\n", 36259df52c7Snorby sumarea->num_spf_calc); 3630439e4c8Sclaudio printf(" Number LSA(s) %d (Checksum sum 0x%x)\n", 3640439e4c8Sclaudio sumarea->num_lsa, sumarea->lsa_cksum); 36559df52c7Snorby break; 36659df52c7Snorby case IMSG_CTL_END: 36759df52c7Snorby printf("\n"); 36859df52c7Snorby return (1); 36959df52c7Snorby default: 37059df52c7Snorby break; 37159df52c7Snorby } 372b49634deSclaudio 373b49634deSclaudio return (0); 374b49634deSclaudio } 375b49634deSclaudio 37618ffdd94Sstsp uint64_t 37718ffdd94Sstsp get_ifms_type(uint8_t if_type) 3783caca30dSnorby { 37918ffdd94Sstsp switch (if_type) { 3803caca30dSnorby case IFT_ETHER: 3813caca30dSnorby return (IFM_ETHER); 3823caca30dSnorby case IFT_FDDI: 3833caca30dSnorby return (IFM_FDDI); 3843caca30dSnorby case IFT_CARP: 3853caca30dSnorby return (IFM_CARP); 386a5bcf77aSclaudio case IFT_PPP: 387a5bcf77aSclaudio return (IFM_TDM); 3883caca30dSnorby default: 3893caca30dSnorby return (0); 3903caca30dSnorby } 3913caca30dSnorby } 3923caca30dSnorby 3933caca30dSnorby int 394b49634deSclaudio show_interface_msg(struct imsg *imsg) 395b49634deSclaudio { 396b49634deSclaudio struct ctl_iface *iface; 39712bb42a0Snorby char *netid; 39812bb42a0Snorby 39912bb42a0Snorby switch (imsg->hdr.type) { 40012bb42a0Snorby case IMSG_CTL_SHOW_INTERFACE: 40112bb42a0Snorby iface = imsg->data; 40212bb42a0Snorby 40312bb42a0Snorby if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), 40412bb42a0Snorby mask2prefixlen(iface->mask.s_addr)) == -1) 40512bb42a0Snorby err(1, NULL); 40612bb42a0Snorby printf("%-11s %-18s %-6s %-10s %-10s %s %3d %3d\n", 40712bb42a0Snorby iface->name, netid, if_state_name(iface->state), 4087afdfd2dSdlg iface->hello_timer.tv_sec < 0 ? "-" : 4097afdfd2dSdlg fmt_timeframe_core(iface->hello_timer.tv_sec), 41018ffdd94Sstsp get_linkstate(iface->if_type, iface->linkstate), 4110f617141Sclaudio fmt_timeframe_core(iface->uptime), 41211c16ffaSnorby iface->nbr_cnt, iface->adj_cnt); 41312bb42a0Snorby free(netid); 41412bb42a0Snorby break; 41512bb42a0Snorby case IMSG_CTL_END: 41612bb42a0Snorby printf("\n"); 41712bb42a0Snorby return (1); 41812bb42a0Snorby default: 41912bb42a0Snorby break; 42012bb42a0Snorby } 42112bb42a0Snorby 42212bb42a0Snorby return (0); 42312bb42a0Snorby } 42412bb42a0Snorby 42512bb42a0Snorby int 42612bb42a0Snorby show_interface_detail_msg(struct imsg *imsg) 42712bb42a0Snorby { 42812bb42a0Snorby struct ctl_iface *iface; 429b49634deSclaudio 430b49634deSclaudio switch (imsg->hdr.type) { 431b49634deSclaudio case IMSG_CTL_SHOW_INTERFACE: 432b49634deSclaudio iface = imsg->data; 433b49634deSclaudio printf("\n"); 4343caca30dSnorby printf("Interface %s, line protocol is %s\n", 4353caca30dSnorby iface->name, print_link(iface->flags)); 436b49634deSclaudio printf(" Internet address %s/%d, ", 437b49634deSclaudio inet_ntoa(iface->addr), 4383ec0d80eSclaudio mask2prefixlen(iface->mask.s_addr)); 439b49634deSclaudio printf("Area %s\n", inet_ntoa(iface->area)); 440eb777345Sjca printf(" Linkstate %s,", 44118ffdd94Sstsp get_linkstate(iface->if_type, iface->linkstate)); 442eb777345Sjca printf(" mtu %d\n", iface->mtu); 443b49634deSclaudio printf(" Router ID %s, network type %s, cost: %d\n", 444b49634deSclaudio inet_ntoa(iface->rtr_id), 4459ac7929fSclaudio if_type_name(iface->type), iface->metric); 44659df52c7Snorby printf(" Transmit delay is %d sec(s), state %s, priority %d\n", 4479ac7929fSclaudio iface->transmit_delay, if_state_name(iface->state), 448b49634deSclaudio iface->priority); 449b49634deSclaudio printf(" Designated Router (ID) %s, ", 450b49634deSclaudio inet_ntoa(iface->dr_id)); 451b49634deSclaudio printf("interface address %s\n", inet_ntoa(iface->dr_addr)); 452b49634deSclaudio printf(" Backup Designated Router (ID) %s, ", 453b49634deSclaudio inet_ntoa(iface->bdr_id)); 454b49634deSclaudio printf("interface address %s\n", inet_ntoa(iface->bdr_addr)); 4557afdfd2dSdlg if (iface->dead_interval == FAST_RTR_DEAD_TIME) { 4567afdfd2dSdlg printf(" Timer intervals configured, " 4577afdfd2dSdlg "hello %d msec, dead %d, wait %d, retransmit %d\n", 4587afdfd2dSdlg iface->fast_hello_interval, iface->dead_interval, 4597afdfd2dSdlg iface->dead_interval, iface->rxmt_interval); 4607afdfd2dSdlg 4617afdfd2dSdlg } else { 462b49634deSclaudio printf(" Timer intervals configured, " 463b49634deSclaudio "hello %d, dead %d, wait %d, retransmit %d\n", 464b49634deSclaudio iface->hello_interval, iface->dead_interval, 465b49634deSclaudio iface->dead_interval, iface->rxmt_interval); 4667afdfd2dSdlg } 467a68e4c86Sstevesk if (iface->passive) 468a68e4c86Sstevesk printf(" Passive interface (No Hellos)\n"); 4697afdfd2dSdlg else if (iface->hello_timer.tv_sec < 0) 470b49634deSclaudio printf(" Hello timer not running\n"); 471b49634deSclaudio else 4727afdfd2dSdlg printf(" Hello timer due in %s+%ldmsec\n", 4737afdfd2dSdlg fmt_timeframe_core(iface->hello_timer.tv_sec), 4747afdfd2dSdlg iface->hello_timer.tv_usec / 1000); 47511c16ffaSnorby printf(" Uptime %s\n", fmt_timeframe_core(iface->uptime)); 476b49634deSclaudio printf(" Neighbor count is %d, adjacent neighbor count is " 477b49634deSclaudio "%d\n", iface->nbr_cnt, iface->adj_cnt); 478a4aef966Smsf if (iface->auth_type > 0) { 479a4aef966Smsf switch (iface->auth_type) { 480a4aef966Smsf case AUTH_SIMPLE: 481a4aef966Smsf printf(" Simple password authentication " 482a4aef966Smsf "enabled\n"); 4839b01acb5Sstevesk break; 484a4aef966Smsf case AUTH_CRYPT: 485a4aef966Smsf printf(" Message digest authentication " 486a4aef966Smsf "enabled\n"); 487a4aef966Smsf printf(" Primary key id is %d\n", 488a4aef966Smsf iface->auth_keyid); 4899b01acb5Sstevesk break; 490a4aef966Smsf default: 491a4aef966Smsf break; 492a4aef966Smsf } 493a4aef966Smsf } 494b49634deSclaudio break; 495b49634deSclaudio case IMSG_CTL_END: 496b49634deSclaudio printf("\n"); 497b49634deSclaudio return (1); 498b49634deSclaudio default: 499b49634deSclaudio break; 500b49634deSclaudio } 501b49634deSclaudio 502b49634deSclaudio return (0); 503b49634deSclaudio } 504b49634deSclaudio 505b49634deSclaudio const char * 506b49634deSclaudio print_link(int state) 507b49634deSclaudio { 508b49634deSclaudio if (state & IFF_UP) 509b49634deSclaudio return ("UP"); 510b49634deSclaudio else 511b49634deSclaudio return ("DOWN"); 512b49634deSclaudio } 513b49634deSclaudio 514b49634deSclaudio #define TF_BUFS 8 515b49634deSclaudio #define TF_LEN 9 516b49634deSclaudio 517b49634deSclaudio const char * 518b49634deSclaudio fmt_timeframe(time_t t) 519b49634deSclaudio { 520b49634deSclaudio if (t == 0) 521b49634deSclaudio return ("Never"); 522b49634deSclaudio else 523b49634deSclaudio return (fmt_timeframe_core(time(NULL) - t)); 524b49634deSclaudio } 525b49634deSclaudio 526b49634deSclaudio const char * 527b49634deSclaudio fmt_timeframe_core(time_t t) 528b49634deSclaudio { 529b49634deSclaudio char *buf; 530b49634deSclaudio static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 531b49634deSclaudio static int idx = 0; 532035b0708Sgilles unsigned int sec, min, hrs, day; 533035b0708Sgilles unsigned long long week; 534b49634deSclaudio 535b49634deSclaudio if (t == 0) 53611c16ffaSnorby return ("00:00:00"); 537b49634deSclaudio 538b49634deSclaudio buf = tfbuf[idx++]; 539b49634deSclaudio if (idx == TF_BUFS) 540b49634deSclaudio idx = 0; 541b49634deSclaudio 542b49634deSclaudio week = t; 543b49634deSclaudio 544b49634deSclaudio sec = week % 60; 545b49634deSclaudio week /= 60; 546b49634deSclaudio min = week % 60; 547b49634deSclaudio week /= 60; 548b49634deSclaudio hrs = week % 24; 549b49634deSclaudio week /= 24; 550b49634deSclaudio day = week % 7; 551b49634deSclaudio week /= 7; 552b49634deSclaudio 553b49634deSclaudio if (week > 0) 554035b0708Sgilles snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs); 555b49634deSclaudio else if (day > 0) 556b49634deSclaudio snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 557b49634deSclaudio else 558b49634deSclaudio snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 559b49634deSclaudio 560b49634deSclaudio return (buf); 561b49634deSclaudio } 562b49634deSclaudio 563b49634deSclaudio const char * 564b49634deSclaudio log_id(u_int32_t id) 565b49634deSclaudio { 566b49634deSclaudio static char buf[48]; 567b49634deSclaudio struct in_addr addr; 568b49634deSclaudio 569b49634deSclaudio addr.s_addr = id; 570b49634deSclaudio 571b49634deSclaudio if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 572b49634deSclaudio return ("?"); 573b49634deSclaudio else 574b49634deSclaudio return (buf); 575b49634deSclaudio } 576b49634deSclaudio 577b49634deSclaudio const char * 578b49634deSclaudio log_adv_rtr(u_int32_t adv_rtr) 579b49634deSclaudio { 580b49634deSclaudio static char buf[48]; 581b49634deSclaudio struct in_addr addr; 582b49634deSclaudio 583b49634deSclaudio addr.s_addr = adv_rtr; 584b49634deSclaudio 585b49634deSclaudio if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 586b49634deSclaudio return ("?"); 587b49634deSclaudio else 588b49634deSclaudio return (buf); 589b49634deSclaudio } 590b49634deSclaudio 5913ec0d80eSclaudio /* prototype defined in ospfd.h and shared with the kroute.c version */ 592b49634deSclaudio u_int8_t 5933ec0d80eSclaudio mask2prefixlen(in_addr_t ina) 594b49634deSclaudio { 5953ec0d80eSclaudio if (ina == 0) 596b49634deSclaudio return (0); 597b49634deSclaudio else 5983ec0d80eSclaudio return (33 - ffs(ntohl(ina))); 599b49634deSclaudio } 600b49634deSclaudio 601b49634deSclaudio void 60297494e25Sclaudio show_database_head(struct in_addr aid, char *ifname, u_int8_t type) 603b49634deSclaudio { 604b49634deSclaudio char *header, *format; 60597494e25Sclaudio int cleanup = 0; 606b49634deSclaudio 607b49634deSclaudio switch (type) { 608b49634deSclaudio case LSA_TYPE_ROUTER: 609b49634deSclaudio format = "Router Link States"; 610b49634deSclaudio break; 611b49634deSclaudio case LSA_TYPE_NETWORK: 612b49634deSclaudio format = "Net Link States"; 613b49634deSclaudio break; 614b49634deSclaudio case LSA_TYPE_SUM_NETWORK: 615b49634deSclaudio format = "Summary Net Link States"; 616b49634deSclaudio break; 617b49634deSclaudio case LSA_TYPE_SUM_ROUTER: 618b49634deSclaudio format = "Summary Router Link States"; 619b49634deSclaudio break; 620b49634deSclaudio case LSA_TYPE_EXTERNAL: 621b49634deSclaudio format = NULL; 622b49634deSclaudio if ((header = strdup("Type-5 AS External Link States")) == NULL) 623b49634deSclaudio err(1, NULL); 624b49634deSclaudio break; 62597494e25Sclaudio case LSA_TYPE_LINK_OPAQ: 62697494e25Sclaudio format = "Type-9 Link Local Opaque Link States"; 62797494e25Sclaudio break; 62897494e25Sclaudio case LSA_TYPE_AREA_OPAQ: 62997494e25Sclaudio format = "Type-10 Area Local Opaque Link States"; 63097494e25Sclaudio break; 63197494e25Sclaudio case LSA_TYPE_AS_OPAQ: 63297494e25Sclaudio format = NULL; 63397494e25Sclaudio if ((header = strdup("Type-11 AS Wide Opaque Link States")) == 63497494e25Sclaudio NULL) 63597494e25Sclaudio err(1, NULL); 63697494e25Sclaudio break; 637b49634deSclaudio default: 63897494e25Sclaudio if (asprintf(&format, "LSA type %x", ntohs(type)) == -1) 63997494e25Sclaudio err(1, NULL); 64097494e25Sclaudio cleanup = 1; 64197494e25Sclaudio break; 642b49634deSclaudio } 64397494e25Sclaudio if (type == LSA_TYPE_LINK_OPAQ) { 64497494e25Sclaudio if (asprintf(&header, "%s (Area %s Interface %s)", format, 64597494e25Sclaudio inet_ntoa(aid), ifname) == -1) 64697494e25Sclaudio err(1, NULL); 64797494e25Sclaudio } else if (type != LSA_TYPE_EXTERNAL && type != LSA_TYPE_AS_OPAQ) 648b49634deSclaudio if (asprintf(&header, "%s (Area %s)", format, 649b49634deSclaudio inet_ntoa(aid)) == -1) 650b49634deSclaudio err(1, NULL); 651b49634deSclaudio 65232286112Snorby printf("\n%-15s %s\n\n", "", header); 653b49634deSclaudio free(header); 65497494e25Sclaudio if (cleanup) 65597494e25Sclaudio free(format); 656b49634deSclaudio } 657b49634deSclaudio 658b49634deSclaudio int 659b49634deSclaudio show_database_msg(struct imsg *imsg) 660b49634deSclaudio { 661b49634deSclaudio static struct in_addr area_id; 66297494e25Sclaudio static char ifname[IF_NAMESIZE]; 663b49634deSclaudio static u_int8_t lasttype; 664b49634deSclaudio struct area *area; 66597494e25Sclaudio struct iface *iface; 666b49634deSclaudio struct lsa_hdr *lsa; 667b49634deSclaudio 668b49634deSclaudio switch (imsg->hdr.type) { 669b49634deSclaudio case IMSG_CTL_SHOW_DATABASE: 67032286112Snorby case IMSG_CTL_SHOW_DB_SELF: 671b49634deSclaudio lsa = imsg->data; 67232286112Snorby if (lsa->type != lasttype) { 67397494e25Sclaudio show_database_head(area_id, ifname, lsa->type); 67432286112Snorby printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID", 67532286112Snorby "Adv Router", "Age", "Seq#", "Checksum"); 67632286112Snorby } 677b49634deSclaudio printf("%-15s %-15s %-4d 0x%08x 0x%04x\n", 678b49634deSclaudio log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr), 679b49634deSclaudio ntohs(lsa->age), ntohl(lsa->seq_num), 680b49634deSclaudio ntohs(lsa->ls_chksum)); 681b49634deSclaudio lasttype = lsa->type; 682b49634deSclaudio break; 683b49634deSclaudio case IMSG_CTL_AREA: 684b49634deSclaudio area = imsg->data; 685b49634deSclaudio area_id = area->id; 68643dbf367Snorby lasttype = 0; 687b49634deSclaudio break; 68897494e25Sclaudio case IMSG_CTL_IFACE: 68997494e25Sclaudio iface = imsg->data; 69097494e25Sclaudio strlcpy(ifname, iface->name, sizeof(ifname)); 69197494e25Sclaudio lasttype = 0; 69297494e25Sclaudio break; 693b49634deSclaudio case IMSG_CTL_END: 69432286112Snorby printf("\n"); 69532286112Snorby return (1); 69632286112Snorby default: 69732286112Snorby break; 69832286112Snorby } 69932286112Snorby 70032286112Snorby return (0); 70132286112Snorby } 70232286112Snorby 70332286112Snorby char * 70432286112Snorby print_ls_type(u_int8_t type) 70532286112Snorby { 70632286112Snorby switch (type) { 70732286112Snorby case LSA_TYPE_ROUTER: 70832286112Snorby return ("Router"); 70932286112Snorby case LSA_TYPE_NETWORK: 71032286112Snorby return ("Network"); 71132286112Snorby case LSA_TYPE_SUM_NETWORK: 71232286112Snorby return ("Summary (Network)"); 71332286112Snorby case LSA_TYPE_SUM_ROUTER: 71432286112Snorby return ("Summary (Router)"); 71532286112Snorby case LSA_TYPE_EXTERNAL: 71632286112Snorby return ("AS External"); 71797494e25Sclaudio case LSA_TYPE_LINK_OPAQ: 71897494e25Sclaudio return ("Type-9 Opaque"); 71997494e25Sclaudio case LSA_TYPE_AREA_OPAQ: 72097494e25Sclaudio return ("Type-10 Opaque"); 72197494e25Sclaudio case LSA_TYPE_AS_OPAQ: 72297494e25Sclaudio return ("Type-11 Opaque"); 72332286112Snorby default: 72432286112Snorby return ("Unknown"); 72532286112Snorby } 72632286112Snorby } 72732286112Snorby 72832286112Snorby void 72932286112Snorby show_db_hdr_msg_detail(struct lsa_hdr *lsa) 73032286112Snorby { 73132286112Snorby printf("LS age: %d\n", ntohs(lsa->age)); 73232286112Snorby printf("Options: %s\n", print_ospf_options(lsa->opts)); 73332286112Snorby printf("LS Type: %s\n", print_ls_type(lsa->type)); 73432286112Snorby 73532286112Snorby switch (lsa->type) { 73632286112Snorby case LSA_TYPE_ROUTER: 73732286112Snorby printf("Link State ID: %s\n", log_id(lsa->ls_id)); 73832286112Snorby break; 73932286112Snorby case LSA_TYPE_NETWORK: 74032286112Snorby printf("Link State ID: %s (address of Designated Router)\n", 74132286112Snorby log_id(lsa->ls_id)); 74232286112Snorby break; 74332286112Snorby case LSA_TYPE_SUM_NETWORK: 74432286112Snorby printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id)); 74532286112Snorby break; 74632286112Snorby case LSA_TYPE_SUM_ROUTER: 74732286112Snorby printf("Link State ID: %s (ASBR Router ID)\n", 74832286112Snorby log_id(lsa->ls_id)); 74932286112Snorby break; 75032286112Snorby case LSA_TYPE_EXTERNAL: 75132286112Snorby printf("Link State ID: %s (External Network Number)\n", 75232286112Snorby log_id(lsa->ls_id)); 75332286112Snorby break; 75497494e25Sclaudio case LSA_TYPE_LINK_OPAQ: 75597494e25Sclaudio case LSA_TYPE_AREA_OPAQ: 75697494e25Sclaudio case LSA_TYPE_AS_OPAQ: 75797494e25Sclaudio printf("Link State ID: %s Type %d ID %d\n", log_id(lsa->ls_id), 75897494e25Sclaudio LSA_24_GETHI(ntohl(lsa->ls_id)), 75997494e25Sclaudio LSA_24_GETLO(ntohl(lsa->ls_id))); 76097494e25Sclaudio break; 76132286112Snorby } 76232286112Snorby 76332286112Snorby printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr)); 76432286112Snorby printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num)); 76532286112Snorby printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum)); 76632286112Snorby printf("Length: %d\n", ntohs(lsa->len)); 76732286112Snorby } 76832286112Snorby 76932286112Snorby char * 77032286112Snorby print_rtr_link_type(u_int8_t type) 77132286112Snorby { 77232286112Snorby switch (type) { 77332286112Snorby case LINK_TYPE_POINTTOPOINT: 77432286112Snorby return ("Point-to-Point"); 77532286112Snorby case LINK_TYPE_TRANSIT_NET: 77632286112Snorby return ("Transit Network"); 77732286112Snorby case LINK_TYPE_STUB_NET: 77832286112Snorby return ("Stub Network"); 77932286112Snorby case LINK_TYPE_VIRTUAL: 78032286112Snorby return ("Virtual Link"); 78132286112Snorby default: 78232286112Snorby return ("Unknown"); 78332286112Snorby } 78432286112Snorby } 78532286112Snorby 78632286112Snorby const char * 78732286112Snorby print_ospf_flags(u_int8_t opts) 78832286112Snorby { 78932286112Snorby static char optbuf[32]; 79032286112Snorby 79132286112Snorby snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s", 79232286112Snorby opts & OSPF_RTR_V ? "V" : "-", 79332286112Snorby opts & OSPF_RTR_E ? "E" : "-", 79432286112Snorby opts & OSPF_RTR_B ? "B" : "-"); 79532286112Snorby return (optbuf); 79632286112Snorby } 79732286112Snorby 79832286112Snorby int 79932286112Snorby show_db_msg_detail(struct imsg *imsg) 80032286112Snorby { 80132286112Snorby static struct in_addr area_id; 80297494e25Sclaudio static char ifname[IF_NAMESIZE]; 80332286112Snorby static u_int8_t lasttype; 80432286112Snorby struct in_addr addr, data; 80532286112Snorby struct area *area; 80697494e25Sclaudio struct iface *iface; 80732286112Snorby struct lsa *lsa; 80832286112Snorby struct lsa_rtr_link *rtr_link; 80932286112Snorby struct lsa_asext *asext; 81032286112Snorby u_int16_t i, nlinks, off; 81132286112Snorby 81232286112Snorby /* XXX sanity checks! */ 81332286112Snorby 81432286112Snorby switch (imsg->hdr.type) { 81532286112Snorby case IMSG_CTL_SHOW_DB_EXT: 81632286112Snorby lsa = imsg->data; 81732286112Snorby if (lsa->hdr.type != lasttype) 81897494e25Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 81932286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 82032286112Snorby addr.s_addr = lsa->data.asext.mask; 82132286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 82232286112Snorby 82332286112Snorby asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr)); 82432286112Snorby 82532286112Snorby printf(" Metric type: "); 82632286112Snorby if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) 82732286112Snorby printf("2\n"); 82832286112Snorby else 82932286112Snorby printf("1\n"); 83032286112Snorby printf(" Metric: %d\n", ntohl(asext->metric) 83132286112Snorby & LSA_METRIC_MASK); 83232286112Snorby addr.s_addr = asext->fw_addr; 83332286112Snorby printf(" Forwarding Address: %s\n", inet_ntoa(addr)); 83432286112Snorby printf(" External Route Tag: %d\n\n", ntohl(asext->ext_tag)); 83532286112Snorby 83632286112Snorby lasttype = lsa->hdr.type; 83732286112Snorby break; 83832286112Snorby case IMSG_CTL_SHOW_DB_NET: 83932286112Snorby lsa = imsg->data; 84032286112Snorby if (lsa->hdr.type != lasttype) 84197494e25Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 84232286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 84332286112Snorby addr.s_addr = lsa->data.net.mask; 84432286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 84532286112Snorby 84632286112Snorby nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) 84732286112Snorby - sizeof(u_int32_t)) / sizeof(struct lsa_net_link); 84832286112Snorby off = sizeof(lsa->hdr) + sizeof(u_int32_t); 849ce1e71ccSbluhm printf("Number of Routers: %d\n", nlinks); 85032286112Snorby 85132286112Snorby for (i = 0; i < nlinks; i++) { 85232286112Snorby addr.s_addr = lsa->data.net.att_rtr[i]; 85332286112Snorby printf(" Attached Router: %s\n", inet_ntoa(addr)); 85432286112Snorby } 85532286112Snorby 85632286112Snorby printf("\n"); 85732286112Snorby lasttype = lsa->hdr.type; 85832286112Snorby break; 85932286112Snorby case IMSG_CTL_SHOW_DB_RTR: 86032286112Snorby lsa = imsg->data; 86132286112Snorby if (lsa->hdr.type != lasttype) 86297494e25Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 86332286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 86432286112Snorby printf("Flags: %s\n", print_ospf_flags(lsa->data.rtr.flags)); 86532286112Snorby nlinks = ntohs(lsa->data.rtr.nlinks); 86632286112Snorby printf("Number of Links: %d\n\n", nlinks); 86732286112Snorby 86832286112Snorby off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr); 86932286112Snorby 87032286112Snorby for (i = 0; i < nlinks; i++) { 87132286112Snorby rtr_link = (struct lsa_rtr_link *)((char *)lsa + off); 87232286112Snorby 87332286112Snorby printf(" Link connected to: %s\n", 87432286112Snorby print_rtr_link_type(rtr_link->type)); 87532286112Snorby 87632286112Snorby addr.s_addr = rtr_link->id; 87732286112Snorby data.s_addr = rtr_link->data; 87832286112Snorby 87932286112Snorby switch (rtr_link->type) { 88032286112Snorby case LINK_TYPE_POINTTOPOINT: 88132286112Snorby case LINK_TYPE_VIRTUAL: 88232286112Snorby printf(" Link ID (Neighbors Router ID):" 88332286112Snorby " %s\n", inet_ntoa(addr)); 88432286112Snorby printf(" Link Data (Router Interface " 88532286112Snorby "address): %s\n", inet_ntoa(data)); 88632286112Snorby break; 88732286112Snorby case LINK_TYPE_TRANSIT_NET: 88832286112Snorby printf(" Link ID (Designated Router " 88932286112Snorby "address): %s\n", inet_ntoa(addr)); 89032286112Snorby printf(" Link Data (Router Interface " 89132286112Snorby "address): %s\n", inet_ntoa(data)); 89232286112Snorby break; 89332286112Snorby case LINK_TYPE_STUB_NET: 89432286112Snorby printf(" Link ID (Network ID): %s\n", 89532286112Snorby inet_ntoa(addr)); 89632286112Snorby printf(" Link Data (Network Mask): %s\n", 89732286112Snorby inet_ntoa(data)); 89832286112Snorby break; 89932286112Snorby default: 90032286112Snorby printf(" Link ID (Unknown): %s\n", 90132286112Snorby inet_ntoa(addr)); 90232286112Snorby printf(" Link Data (Unknown): %s\n", 90332286112Snorby inet_ntoa(data)); 90432286112Snorby break; 90532286112Snorby } 90632286112Snorby 90732286112Snorby printf(" Metric: %d\n\n", ntohs(rtr_link->metric)); 90832286112Snorby 90932286112Snorby off += sizeof(struct lsa_rtr_link) + 91032286112Snorby rtr_link->num_tos * sizeof(u_int32_t); 91132286112Snorby } 91232286112Snorby 91332286112Snorby lasttype = lsa->hdr.type; 91432286112Snorby break; 91532286112Snorby case IMSG_CTL_SHOW_DB_SUM: 91632286112Snorby case IMSG_CTL_SHOW_DB_ASBR: 91732286112Snorby lsa = imsg->data; 91832286112Snorby if (lsa->hdr.type != lasttype) 91997494e25Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 92032286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 92132286112Snorby addr.s_addr = lsa->data.sum.mask; 92232286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 92332286112Snorby printf("Metric: %d\n\n", ntohl(lsa->data.sum.metric) & 92432286112Snorby LSA_METRIC_MASK); 92532286112Snorby lasttype = lsa->hdr.type; 92632286112Snorby break; 92797494e25Sclaudio case IMSG_CTL_SHOW_DB_OPAQ: 92897494e25Sclaudio lsa = imsg->data; 92997494e25Sclaudio if (lsa->hdr.type != lasttype) 93097494e25Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 93197494e25Sclaudio show_db_hdr_msg_detail(&lsa->hdr); 93297494e25Sclaudio /* XXX should we hexdump the data? */ 93397494e25Sclaudio lasttype = lsa->hdr.type; 93497494e25Sclaudio break; 93532286112Snorby case IMSG_CTL_AREA: 93632286112Snorby area = imsg->data; 93732286112Snorby area_id = area->id; 93815904804Snorby lasttype = 0; 93932286112Snorby break; 94097494e25Sclaudio case IMSG_CTL_IFACE: 94197494e25Sclaudio iface = imsg->data; 94297494e25Sclaudio strlcpy(ifname, iface->name, sizeof(ifname)); 94397494e25Sclaudio lasttype = 0; 94497494e25Sclaudio break; 94532286112Snorby case IMSG_CTL_END: 946b49634deSclaudio return (1); 947b49634deSclaudio default: 948b49634deSclaudio break; 949b49634deSclaudio } 950b49634deSclaudio 951b49634deSclaudio return (0); 952b49634deSclaudio } 953b49634deSclaudio 954b49634deSclaudio int 955b49634deSclaudio show_nbr_msg(struct imsg *imsg) 956b49634deSclaudio { 957b49634deSclaudio struct ctl_nbr *nbr; 958b49634deSclaudio char *state; 959b49634deSclaudio 960b49634deSclaudio switch (imsg->hdr.type) { 961b49634deSclaudio case IMSG_CTL_SHOW_NBR: 962b49634deSclaudio nbr = imsg->data; 9639ac7929fSclaudio if (asprintf(&state, "%s/%s", nbr_state_name(nbr->nbr_state), 9649ac7929fSclaudio if_state_name(nbr->iface_state)) == -1) 965b49634deSclaudio err(1, NULL); 966129e6b5fSnorby printf("%-15s %-3d %-12s %-9s", inet_ntoa(nbr->id), 967b49634deSclaudio nbr->priority, state, fmt_timeframe_core(nbr->dead_timer)); 968129e6b5fSnorby printf("%-15s %-9s %s\n", inet_ntoa(nbr->addr), nbr->name, 969129e6b5fSnorby nbr->uptime == 0 ? "-" : fmt_timeframe_core(nbr->uptime)); 970b49634deSclaudio free(state); 971b49634deSclaudio break; 972b49634deSclaudio case IMSG_CTL_END: 973b49634deSclaudio printf("\n"); 974b49634deSclaudio return (1); 975b49634deSclaudio default: 976b49634deSclaudio break; 977b49634deSclaudio } 978b49634deSclaudio 979b49634deSclaudio return (0); 980b49634deSclaudio } 981b49634deSclaudio 982b49634deSclaudio const char * 983b49634deSclaudio print_ospf_options(u_int8_t opts) 984b49634deSclaudio { 985b49634deSclaudio static char optbuf[32]; 986b49634deSclaudio 98797494e25Sclaudio snprintf(optbuf, sizeof(optbuf), "%s|%s|%s|%s|%s|%s|%s|%s", 98897494e25Sclaudio opts & OSPF_OPTION_DN ? "DN" : "-", 98997494e25Sclaudio opts & OSPF_OPTION_O ? "O" : "-", 990b49634deSclaudio opts & OSPF_OPTION_DC ? "DC" : "-", 991b49634deSclaudio opts & OSPF_OPTION_EA ? "EA" : "-", 992b49634deSclaudio opts & OSPF_OPTION_NP ? "N/P" : "-", 993b49634deSclaudio opts & OSPF_OPTION_MC ? "MC" : "-", 99497494e25Sclaudio opts & OSPF_OPTION_E ? "E" : "-", 99597494e25Sclaudio opts & OSPF_OPTION_MT ? "MT" : "-"); 996b49634deSclaudio return (optbuf); 997b49634deSclaudio } 998b49634deSclaudio 999b49634deSclaudio int 1000b49634deSclaudio show_nbr_detail_msg(struct imsg *imsg) 1001b49634deSclaudio { 1002b49634deSclaudio struct ctl_nbr *nbr; 1003b49634deSclaudio 1004b49634deSclaudio switch (imsg->hdr.type) { 1005b49634deSclaudio case IMSG_CTL_SHOW_NBR: 1006b49634deSclaudio nbr = imsg->data; 1007b49634deSclaudio printf("\nNeighbor %s, ", inet_ntoa(nbr->id)); 1008b49634deSclaudio printf("interface address %s\n", inet_ntoa(nbr->addr)); 100952580a1cSnorby printf(" Area %s, interface %s\n", inet_ntoa(nbr->area), 101052580a1cSnorby nbr->name); 1011b49634deSclaudio printf(" Neighbor priority is %d, " 1012b49634deSclaudio "State is %s, %d state changes\n", 10139ac7929fSclaudio nbr->priority, nbr_state_name(nbr->nbr_state), 1014b49634deSclaudio nbr->state_chng_cnt); 1015b49634deSclaudio printf(" DR is %s, ", inet_ntoa(nbr->dr)); 1016b49634deSclaudio printf("BDR is %s\n", inet_ntoa(nbr->bdr)); 101752580a1cSnorby printf(" Options %s\n", print_ospf_options(nbr->options)); 1018b49634deSclaudio printf(" Dead timer due in %s\n", 1019b49634deSclaudio fmt_timeframe_core(nbr->dead_timer)); 1020a9686be3Snorby printf(" Uptime %s\n", fmt_timeframe_core(nbr->uptime)); 1021b49634deSclaudio printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt); 1022b49634deSclaudio printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt); 1023b49634deSclaudio printf(" Link State Retransmission List %d\n", 1024b49634deSclaudio nbr->ls_retrans_lst_cnt); 1025b49634deSclaudio break; 1026b49634deSclaudio case IMSG_CTL_END: 1027b49634deSclaudio printf("\n"); 1028b49634deSclaudio return (1); 1029b49634deSclaudio default: 1030b49634deSclaudio break; 1031b49634deSclaudio } 1032b49634deSclaudio 1033b49634deSclaudio return (0); 1034b49634deSclaudio } 103537355230Snorby 103637355230Snorby int 103737355230Snorby show_rib_msg(struct imsg *imsg) 103837355230Snorby { 103937355230Snorby struct ctl_rt *rt; 104037355230Snorby char *dstnet; 104137355230Snorby 104237355230Snorby switch (imsg->hdr.type) { 104337355230Snorby case IMSG_CTL_SHOW_RIB: 104437355230Snorby rt = imsg->data; 104537355230Snorby switch (rt->d_type) { 104637355230Snorby case DT_NET: 104737355230Snorby if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), 104837355230Snorby rt->prefixlen) == -1) 104937355230Snorby err(1, NULL); 105037355230Snorby break; 105137355230Snorby case DT_RTR: 105237355230Snorby if (asprintf(&dstnet, "%s", 105337355230Snorby inet_ntoa(rt->prefix)) == -1) 105437355230Snorby err(1, NULL); 105537355230Snorby break; 105637355230Snorby default: 105737355230Snorby errx(1, "Invalid route type"); 105837355230Snorby } 105937355230Snorby 10608e72645bSclaudio printf("%-20s %-16s%s %-12s %-9s %-7d %s\n", dstnet, 10618e72645bSclaudio inet_ntoa(rt->nexthop), rt->connected ? "C" : " ", 10628e72645bSclaudio path_type_name(rt->p_type), 10639ac7929fSclaudio dst_type_name(rt->d_type), rt->cost, 10647aa44f3cSnorby rt->uptime == 0 ? "-" : fmt_timeframe_core(rt->uptime)); 106537355230Snorby free(dstnet); 106637355230Snorby break; 106737355230Snorby case IMSG_CTL_END: 106837355230Snorby printf("\n"); 106937355230Snorby return (1); 107037355230Snorby default: 107137355230Snorby break; 107237355230Snorby } 107337355230Snorby 107437355230Snorby return (0); 107537355230Snorby } 107637355230Snorby 107737355230Snorby void 107837355230Snorby show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) 107937355230Snorby { 108091e3b0aeSnorby char *header, *format, *format2; 108137355230Snorby 108237355230Snorby switch (p_type) { 108337355230Snorby case PT_INTRA_AREA: 108437355230Snorby case PT_INTER_AREA: 108537355230Snorby switch (d_type) { 108637355230Snorby case DT_NET: 108737355230Snorby format = "Network Routing Table"; 108891e3b0aeSnorby format2 = ""; 108937355230Snorby break; 109037355230Snorby case DT_RTR: 109137355230Snorby format = "Router Routing Table"; 109291e3b0aeSnorby format2 = "Type"; 109337355230Snorby break; 109437355230Snorby default: 109537355230Snorby errx(1, "unknown route type"); 109637355230Snorby } 109737355230Snorby break; 109837355230Snorby case PT_TYPE1_EXT: 109937355230Snorby case PT_TYPE2_EXT: 110037355230Snorby format = NULL; 110191e3b0aeSnorby format2 = "Cost 2"; 110237355230Snorby if ((header = strdup("External Routing Table")) == NULL) 110337355230Snorby err(1, NULL); 110437355230Snorby break; 110537355230Snorby default: 110637355230Snorby errx(1, "unknown route type"); 110737355230Snorby } 110837355230Snorby 110937355230Snorby if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) 111037355230Snorby if (asprintf(&header, "%s (Area %s)", format, 111137355230Snorby inet_ntoa(aid)) == -1) 111237355230Snorby err(1, NULL); 111337355230Snorby 111491e3b0aeSnorby printf("\n%-18s %s\n", "", header); 111537355230Snorby free(header); 111637355230Snorby 111791e3b0aeSnorby printf("\n%-18s %-15s %-15s %-12s %-7s %-7s\n", "Destination", 111891e3b0aeSnorby "Nexthop", "Adv Router", "Path type", "Cost", format2); 111991e3b0aeSnorby } 112037355230Snorby 112191e3b0aeSnorby const char * 112291e3b0aeSnorby print_ospf_rtr_flags(u_int8_t opts) 112391e3b0aeSnorby { 112491e3b0aeSnorby static char optbuf[32]; 112591e3b0aeSnorby 112691e3b0aeSnorby snprintf(optbuf, sizeof(optbuf), "%s%s%s", 112791e3b0aeSnorby opts & OSPF_RTR_E ? "AS" : "", 112891e3b0aeSnorby opts & OSPF_RTR_E && opts & OSPF_RTR_B ? "+" : "", 112991e3b0aeSnorby opts & OSPF_RTR_B ? "ABR" : ""); 113091e3b0aeSnorby return (optbuf); 113137355230Snorby } 113237355230Snorby 113337355230Snorby int 113437355230Snorby show_rib_detail_msg(struct imsg *imsg) 113537355230Snorby { 113637355230Snorby static struct in_addr area_id; 113737355230Snorby struct ctl_rt *rt; 113837355230Snorby struct area *area; 113937355230Snorby char *dstnet; 114037355230Snorby static u_int8_t lasttype; 114137355230Snorby 114237355230Snorby switch (imsg->hdr.type) { 114337355230Snorby case IMSG_CTL_SHOW_RIB: 114437355230Snorby rt = imsg->data; 114537355230Snorby 114637355230Snorby switch (rt->p_type) { 114737355230Snorby case PT_INTRA_AREA: 114837355230Snorby case PT_INTER_AREA: 114937355230Snorby switch (rt->d_type) { 115037355230Snorby case DT_NET: 115137355230Snorby if (lasttype != RIB_NET) 115237355230Snorby show_rib_head(rt->area, rt->d_type, 115337355230Snorby rt->p_type); 115437355230Snorby if (asprintf(&dstnet, "%s/%d", 115537355230Snorby inet_ntoa(rt->prefix), rt->prefixlen) == -1) 115637355230Snorby err(1, NULL); 115737355230Snorby lasttype = RIB_NET; 115837355230Snorby break; 115937355230Snorby case DT_RTR: 116037355230Snorby if (lasttype != RIB_RTR) 116137355230Snorby show_rib_head(rt->area, rt->d_type, 116237355230Snorby rt->p_type); 116337355230Snorby if (asprintf(&dstnet, "%s", 116437355230Snorby inet_ntoa(rt->prefix)) == -1) 116537355230Snorby err(1, NULL); 116637355230Snorby lasttype = RIB_RTR; 116737355230Snorby break; 116837355230Snorby default: 116937355230Snorby errx(1, "unknown route type"); 117037355230Snorby } 117191e3b0aeSnorby printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); 117291e3b0aeSnorby printf("%-15s %-12s %-7d", inet_ntoa(rt->adv_rtr), 11739ac7929fSclaudio path_type_name(rt->p_type), rt->cost); 117437355230Snorby free(dstnet); 117591e3b0aeSnorby 117691e3b0aeSnorby if (rt->d_type == DT_RTR) 117791e3b0aeSnorby printf(" %-7s", 117891e3b0aeSnorby print_ospf_rtr_flags(rt->flags)); 117991e3b0aeSnorby 118091e3b0aeSnorby printf("\n"); 118137355230Snorby break; 118237355230Snorby case PT_TYPE1_EXT: 118337355230Snorby case PT_TYPE2_EXT: 118491e3b0aeSnorby if (lasttype != RIB_EXT) 118591e3b0aeSnorby show_rib_head(rt->area, rt->d_type, rt->p_type); 118691e3b0aeSnorby 118791e3b0aeSnorby if (asprintf(&dstnet, "%s/%d", 118891e3b0aeSnorby inet_ntoa(rt->prefix), rt->prefixlen) == -1) 118991e3b0aeSnorby err(1, NULL); 119091e3b0aeSnorby 119191e3b0aeSnorby printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); 119291e3b0aeSnorby printf("%-15s %-12s %-7d %-7d\n", 11939ac7929fSclaudio inet_ntoa(rt->adv_rtr), path_type_name(rt->p_type), 119491e3b0aeSnorby rt->cost, rt->cost2); 11951c1dafb4Snorby free(dstnet); 119691e3b0aeSnorby 119791e3b0aeSnorby lasttype = RIB_EXT; 119837355230Snorby break; 119937355230Snorby default: 120037355230Snorby errx(1, "unknown route type"); 120137355230Snorby } 120237355230Snorby break; 120337355230Snorby case IMSG_CTL_AREA: 120437355230Snorby area = imsg->data; 120537355230Snorby area_id = area->id; 120637355230Snorby break; 120737355230Snorby case IMSG_CTL_END: 120837355230Snorby printf("\n"); 120937355230Snorby return (1); 121037355230Snorby default: 121137355230Snorby break; 121237355230Snorby } 121337355230Snorby 121437355230Snorby return (0); 121537355230Snorby } 1216c47b7f65Sclaudio 1217c47b7f65Sclaudio void 1218c47b7f65Sclaudio show_fib_head(void) 1219c47b7f65Sclaudio { 1220c47b7f65Sclaudio printf("flags: * = valid, O = OSPF, C = Connected, S = Static\n"); 1221253df265Sclaudio printf("%-6s %-4s %-20s %-17s\n", "Flags", "Prio", "Destination", "Nexthop"); 1222c47b7f65Sclaudio } 1223c47b7f65Sclaudio 1224c47b7f65Sclaudio int 1225c47b7f65Sclaudio show_fib_msg(struct imsg *imsg) 1226c47b7f65Sclaudio { 1227c47b7f65Sclaudio struct kroute *k; 1228c47b7f65Sclaudio char *p; 1229c47b7f65Sclaudio 1230c47b7f65Sclaudio switch (imsg->hdr.type) { 1231c47b7f65Sclaudio case IMSG_CTL_KROUTE: 1232c47b7f65Sclaudio if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) 1233c47b7f65Sclaudio errx(1, "wrong imsg len"); 1234c47b7f65Sclaudio k = imsg->data; 1235c47b7f65Sclaudio 1236c47b7f65Sclaudio if (k->flags & F_DOWN) 1237c47b7f65Sclaudio printf(" "); 1238c47b7f65Sclaudio else 1239c47b7f65Sclaudio printf("*"); 1240c47b7f65Sclaudio 1241347b5019Sclaudio if (!(k->flags & F_KERNEL)) 1242c47b7f65Sclaudio printf("O"); 1243c47b7f65Sclaudio else if (k->flags & F_CONNECTED) 1244c47b7f65Sclaudio printf("C"); 1245fc1549e1Sclaudio else if (k->flags & F_STATIC) 1246c47b7f65Sclaudio printf("S"); 1247c47b7f65Sclaudio else 1248c47b7f65Sclaudio printf(" "); 1249c47b7f65Sclaudio 1250c47b7f65Sclaudio printf(" "); 1251253df265Sclaudio printf("%4d ", k->priority); 1252c47b7f65Sclaudio if (asprintf(&p, "%s/%u", inet_ntoa(k->prefix), k->prefixlen) == 1253c47b7f65Sclaudio -1) 1254c47b7f65Sclaudio err(1, NULL); 1255c47b7f65Sclaudio printf("%-20s ", p); 1256c47b7f65Sclaudio free(p); 1257c47b7f65Sclaudio 1258c47b7f65Sclaudio if (k->nexthop.s_addr) 1259c47b7f65Sclaudio printf("%s", inet_ntoa(k->nexthop)); 1260c47b7f65Sclaudio else if (k->flags & F_CONNECTED) 1261c47b7f65Sclaudio printf("link#%u", k->ifindex); 1262c47b7f65Sclaudio printf("\n"); 1263c47b7f65Sclaudio 1264c47b7f65Sclaudio break; 1265c47b7f65Sclaudio case IMSG_CTL_END: 1266c47b7f65Sclaudio printf("\n"); 1267c47b7f65Sclaudio return (1); 1268c47b7f65Sclaudio default: 1269c47b7f65Sclaudio break; 1270c47b7f65Sclaudio } 1271c47b7f65Sclaudio 1272c47b7f65Sclaudio return (0); 1273c47b7f65Sclaudio } 1274c47b7f65Sclaudio 1275c47b7f65Sclaudio void 1276c47b7f65Sclaudio show_interface_head(void) 1277c47b7f65Sclaudio { 12784c561fb6Sclaudio printf("%-15s%-15s%s\n", "Interface", "Flags", 1279c47b7f65Sclaudio "Link state"); 1280c47b7f65Sclaudio } 1281c47b7f65Sclaudio 12820f617141Sclaudio const struct if_status_description 12830f617141Sclaudio if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; 1284c47b7f65Sclaudio const struct ifmedia_description 1285c47b7f65Sclaudio ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; 1286c47b7f65Sclaudio 1287c47b7f65Sclaudio const char * 1288e5605ae3Sderaadt get_media_descr(uint64_t media_type) 1289c47b7f65Sclaudio { 1290c47b7f65Sclaudio const struct ifmedia_description *p; 1291c47b7f65Sclaudio 1292c47b7f65Sclaudio for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) 1293c47b7f65Sclaudio if (media_type == p->ifmt_word) 1294c47b7f65Sclaudio return (p->ifmt_string); 1295c47b7f65Sclaudio 1296a5bcf77aSclaudio return ("unknown"); 1297c47b7f65Sclaudio } 1298c47b7f65Sclaudio 1299c47b7f65Sclaudio const char * 130018ffdd94Sstsp get_linkstate(uint8_t if_type, int link_state) 1301c47b7f65Sclaudio { 13020f617141Sclaudio const struct if_status_description *p; 13030f617141Sclaudio static char buf[8]; 1304c47b7f65Sclaudio 13050f617141Sclaudio for (p = if_status_descriptions; p->ifs_string != NULL; p++) { 130618ffdd94Sstsp if (LINK_STATE_DESC_MATCH(p, if_type, link_state)) 13070f617141Sclaudio return (p->ifs_string); 1308c47b7f65Sclaudio } 13090f617141Sclaudio snprintf(buf, sizeof(buf), "[#%d]", link_state); 13100f617141Sclaudio return (buf); 1311c47b7f65Sclaudio } 1312c47b7f65Sclaudio 1313c47b7f65Sclaudio void 131456babc06Sclaudio print_baudrate(u_int64_t baudrate) 1315c47b7f65Sclaudio { 1316c47b7f65Sclaudio if (baudrate > IF_Gbps(1)) 131756babc06Sclaudio printf("%llu GBit/s", baudrate / IF_Gbps(1)); 1318c47b7f65Sclaudio else if (baudrate > IF_Mbps(1)) 131956babc06Sclaudio printf("%llu MBit/s", baudrate / IF_Mbps(1)); 1320c47b7f65Sclaudio else if (baudrate > IF_Kbps(1)) 132156babc06Sclaudio printf("%llu KBit/s", baudrate / IF_Kbps(1)); 1322c47b7f65Sclaudio else 132356babc06Sclaudio printf("%llu Bit/s", baudrate); 1324c47b7f65Sclaudio } 1325c47b7f65Sclaudio 1326c47b7f65Sclaudio int 1327c47b7f65Sclaudio show_fib_interface_msg(struct imsg *imsg) 1328c47b7f65Sclaudio { 1329c47b7f65Sclaudio struct kif *k; 1330e5605ae3Sderaadt uint64_t ifms_type; 1331c47b7f65Sclaudio 1332c47b7f65Sclaudio switch (imsg->hdr.type) { 13334c561fb6Sclaudio case IMSG_CTL_IFINFO: 1334c47b7f65Sclaudio k = imsg->data; 1335c47b7f65Sclaudio printf("%-15s", k->ifname); 1336c47b7f65Sclaudio printf("%-15s", k->flags & IFF_UP ? "UP" : ""); 133718ffdd94Sstsp ifms_type = get_ifms_type(k->if_type); 1338c47b7f65Sclaudio if (ifms_type) 13390f617141Sclaudio printf("%s, ", get_media_descr(ifms_type)); 13400f617141Sclaudio 134118ffdd94Sstsp printf("%s", get_linkstate(k->if_type, k->link_state)); 1342c47b7f65Sclaudio 1343c47b7f65Sclaudio if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { 1344c47b7f65Sclaudio printf(", "); 1345c47b7f65Sclaudio print_baudrate(k->baudrate); 1346c47b7f65Sclaudio } 1347c47b7f65Sclaudio printf("\n"); 1348c47b7f65Sclaudio break; 1349c47b7f65Sclaudio case IMSG_CTL_END: 1350c47b7f65Sclaudio printf("\n"); 1351c47b7f65Sclaudio return (1); 1352c47b7f65Sclaudio default: 1353c47b7f65Sclaudio break; 1354c47b7f65Sclaudio } 1355c47b7f65Sclaudio 1356c47b7f65Sclaudio return (0); 1357c47b7f65Sclaudio } 1358