1*32286112Snorby /* $OpenBSD: ospfctl.c,v 1.14 2005/05/12 19:10:12 norby 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> 30b49634deSclaudio #include <stdio.h> 31b49634deSclaudio #include <stdlib.h> 32b49634deSclaudio #include <string.h> 33b49634deSclaudio #include <unistd.h> 34b49634deSclaudio 35b49634deSclaudio #include "ospf.h" 36b49634deSclaudio #include "ospfd.h" 37b49634deSclaudio #include "ospfe.h" 38b49634deSclaudio #include "parser.h" 39b49634deSclaudio #include "log.h" 40b49634deSclaudio 41cbb557dbShenning __dead void usage(void); 4259df52c7Snorby int show_summary_msg(struct imsg *); 43b49634deSclaudio int show_interface_msg(struct imsg *); 44b49634deSclaudio void print_baudrate(u_long); 45b49634deSclaudio const char *print_if_type(enum iface_type type); 46b49634deSclaudio const char *print_if_state(int); 47b49634deSclaudio const char *print_nbr_state(int); 48b49634deSclaudio const char *print_link(int); 49b49634deSclaudio const char *fmt_timeframe(time_t t); 50b49634deSclaudio const char *fmt_timeframe_core(time_t t); 51b49634deSclaudio const char *log_id(u_int32_t ); 52b49634deSclaudio const char *log_adv_rtr(u_int32_t); 53b49634deSclaudio void show_database_head(struct in_addr, u_int8_t); 54b49634deSclaudio int show_database_msg(struct imsg *); 55*32286112Snorby char *print_ls_type(u_int8_t); 56*32286112Snorby void show_db_hdr_msg_detail(struct lsa_hdr *); 57*32286112Snorby char *print_rtr_link_type(u_int8_t); 58*32286112Snorby const char *print_ospf_flags(u_int8_t); 59*32286112Snorby int show_db_msg_detail(struct imsg *imsg); 60b49634deSclaudio int show_nbr_msg(struct imsg *); 61b49634deSclaudio const char *print_ospf_options(u_int8_t); 62b49634deSclaudio int show_nbr_detail_msg(struct imsg *); 6337355230Snorby int show_rib_msg(struct imsg *); 6437355230Snorby void show_rib_head(struct in_addr, u_int8_t, u_int8_t); 6537355230Snorby int show_rib_detail_msg(struct imsg *); 66c47b7f65Sclaudio void show_fib_head(void); 67c47b7f65Sclaudio int show_fib_msg(struct imsg *); 68c47b7f65Sclaudio void show_interface_head(void); 69c47b7f65Sclaudio const char * get_media_descr(int); 70c47b7f65Sclaudio const char * get_linkstate(int, int); 71c47b7f65Sclaudio void print_baudrate(u_long); 72c47b7f65Sclaudio int show_fib_interface_msg(struct imsg *); 73b49634deSclaudio 74b49634deSclaudio struct imsgbuf *ibuf; 75b49634deSclaudio 76cbb557dbShenning __dead void 77b49634deSclaudio usage(void) 78b49634deSclaudio { 79b49634deSclaudio extern char *__progname; 80b49634deSclaudio 81b49634deSclaudio fprintf(stderr, "usage: %s <command> [arg [...]]\n", __progname); 82b49634deSclaudio exit(1); 83b49634deSclaudio } 84b49634deSclaudio 85b49634deSclaudio void 86b49634deSclaudio imsg_event_add(struct imsgbuf *i) 87b49634deSclaudio { 88b49634deSclaudio } 89b49634deSclaudio 90b49634deSclaudio int 91b49634deSclaudio main(int argc, char *argv[]) 92b49634deSclaudio { 93b49634deSclaudio struct sockaddr_un sun; 94b49634deSclaudio struct parse_result *res; 95b49634deSclaudio struct imsg imsg; 96b49634deSclaudio unsigned int ifidx = 0; 97b49634deSclaudio int ctl_sock; 98b49634deSclaudio int done = 0; 99b49634deSclaudio int n; 100b49634deSclaudio 101b49634deSclaudio /* parse options */ 102b49634deSclaudio if ((res = parse(argc - 1, argv + 1)) == NULL) 103b49634deSclaudio exit(1); 104b49634deSclaudio 105b49634deSclaudio /* connect to ospfd control socket */ 106b49634deSclaudio if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 107b49634deSclaudio err(1, "socket"); 108b49634deSclaudio 109b49634deSclaudio bzero(&sun, sizeof(sun)); 110b49634deSclaudio sun.sun_family = AF_UNIX; 111b49634deSclaudio strlcpy(sun.sun_path, OSPFD_SOCKET, sizeof(sun.sun_path)); 112b49634deSclaudio if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 113b49634deSclaudio err(1, "connect: %s", OSPFD_SOCKET); 114b49634deSclaudio 115b49634deSclaudio if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 116b49634deSclaudio fatal(NULL); 117b49634deSclaudio imsg_init(ibuf, ctl_sock, NULL); 118b49634deSclaudio done = 0; 119b49634deSclaudio 120b49634deSclaudio /* process user request */ 121b49634deSclaudio switch (res->action) { 122b49634deSclaudio case NONE: 123b49634deSclaudio usage(); 124b49634deSclaudio /* not reached */ 125b49634deSclaudio case SHOW: 12659df52c7Snorby case SHOW_SUM: 12759df52c7Snorby imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); 128b49634deSclaudio break; 129b49634deSclaudio case SHOW_IFACE: 130b49634deSclaudio if (*res->ifname) { 131b49634deSclaudio ifidx = if_nametoindex(res->ifname); 132b49634deSclaudio if (ifidx == 0) 133b49634deSclaudio errx(1, "no such interface %s", res->ifname); 134b49634deSclaudio } 135b49634deSclaudio imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 136b49634deSclaudio &ifidx, sizeof(ifidx)); 137b49634deSclaudio break; 138b49634deSclaudio case SHOW_NBR: 13970d7d860Snorby printf("%-15s %-3s %-17s %-9s %-15s %s\n", "ID", "Pri", 14070d7d860Snorby "State", "DeadTime", "Address", "Interface"); 141b49634deSclaudio case SHOW_NBR_DTAIL: 142b49634deSclaudio imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 143b49634deSclaudio break; 144b49634deSclaudio case SHOW_DB: 145b49634deSclaudio imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0); 146b49634deSclaudio break; 147b49634deSclaudio case SHOW_DBBYAREA: 148b49634deSclaudio imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, 149b49634deSclaudio &res->addr, sizeof(res->addr)); 150b49634deSclaudio break; 151*32286112Snorby case SHOW_DBEXT: 152*32286112Snorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0); 153*32286112Snorby break; 154*32286112Snorby case SHOW_DBNET: 155*32286112Snorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0); 156*32286112Snorby break; 157*32286112Snorby case SHOW_DBRTR: 158*32286112Snorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0); 159*32286112Snorby break; 160*32286112Snorby case SHOW_DBSELF: 161*32286112Snorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0); 162*32286112Snorby break; 163*32286112Snorby case SHOW_DBSUM: 164*32286112Snorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0); 165*32286112Snorby break; 166*32286112Snorby case SHOW_DBASBR: 167*32286112Snorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0); 168*32286112Snorby break; 16937355230Snorby case SHOW_RIB: 17037355230Snorby printf("%-20s %-17s %-12s %-9s %-7s\n", "Destination", 17137355230Snorby "Nexthop", "Path Type", "Type", "Cost"); 17237355230Snorby case SHOW_RIB_DTAIL: 17337355230Snorby imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); 17437355230Snorby break; 175c47b7f65Sclaudio case SHOW_FIB: 176c47b7f65Sclaudio if (!res->addr.s_addr) 177c47b7f65Sclaudio imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, 178c47b7f65Sclaudio &res->flags, sizeof(res->flags)); 179c47b7f65Sclaudio else 180c47b7f65Sclaudio imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, 181c47b7f65Sclaudio &res->addr, sizeof(res->addr)); 182c47b7f65Sclaudio show_fib_head(); 183c47b7f65Sclaudio break; 184c47b7f65Sclaudio case SHOW_FIB_IFACE: 1854c561fb6Sclaudio if (*res->ifname) 1864c561fb6Sclaudio imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, 1874c561fb6Sclaudio res->ifname, sizeof(res->ifname)); 1884c561fb6Sclaudio else 189c47b7f65Sclaudio imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0); 190c47b7f65Sclaudio show_interface_head(); 191c47b7f65Sclaudio break; 192b49634deSclaudio case RELOAD: 193b49634deSclaudio imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 194b49634deSclaudio printf("reload request sent.\n"); 195b49634deSclaudio done = 1; 196b49634deSclaudio break; 197b49634deSclaudio } 198b49634deSclaudio 199b49634deSclaudio while (ibuf->w.queued) 200b49634deSclaudio if (msgbuf_write(&ibuf->w) < 0) 201b49634deSclaudio err(1, "write error"); 202b49634deSclaudio 203b49634deSclaudio while (!done) { 204b49634deSclaudio if ((n = imsg_read(ibuf)) == -1) 205b49634deSclaudio errx(1, "imsg_read error"); 206b49634deSclaudio if (n == 0) 207b49634deSclaudio errx(1, "pipe closed"); 208b49634deSclaudio 209b49634deSclaudio while (!done) { 210b49634deSclaudio if ((n = imsg_get(ibuf, &imsg)) == -1) 211b49634deSclaudio errx(1, "imsg_get error"); 212b49634deSclaudio if (n == 0) 213b49634deSclaudio break; 214b49634deSclaudio switch (res->action) { 215b49634deSclaudio case SHOW: 21659df52c7Snorby case SHOW_SUM: 21759df52c7Snorby done = show_summary_msg(&imsg); 218b49634deSclaudio break; 219b49634deSclaudio case SHOW_IFACE: 220b49634deSclaudio done = show_interface_msg(&imsg); 221b49634deSclaudio break; 222b49634deSclaudio case SHOW_NBR: 223b49634deSclaudio done = show_nbr_msg(&imsg); 224b49634deSclaudio break; 225b49634deSclaudio case SHOW_NBR_DTAIL: 226b49634deSclaudio done = show_nbr_detail_msg(&imsg); 227b49634deSclaudio break; 228b49634deSclaudio case SHOW_DB: 229b49634deSclaudio case SHOW_DBBYAREA: 230*32286112Snorby case SHOW_DBSELF: 231b49634deSclaudio done = show_database_msg(&imsg); 232b49634deSclaudio break; 233*32286112Snorby case SHOW_DBEXT: 234*32286112Snorby case SHOW_DBNET: 235*32286112Snorby case SHOW_DBRTR: 236*32286112Snorby case SHOW_DBSUM: 237*32286112Snorby case SHOW_DBASBR: 238*32286112Snorby done = show_db_msg_detail(&imsg); 239*32286112Snorby break; 24037355230Snorby case SHOW_RIB: 24137355230Snorby done = show_rib_msg(&imsg); 24237355230Snorby break; 24337355230Snorby case SHOW_RIB_DTAIL: 24437355230Snorby done = show_rib_detail_msg(&imsg); 24537355230Snorby break; 246c47b7f65Sclaudio case SHOW_FIB: 247c47b7f65Sclaudio done = show_fib_msg(&imsg); 248c47b7f65Sclaudio break; 249c47b7f65Sclaudio case SHOW_FIB_IFACE: 250c47b7f65Sclaudio done = show_fib_interface_msg(&imsg); 251c47b7f65Sclaudio break; 252b49634deSclaudio case NONE: 253b49634deSclaudio case RELOAD: 254b49634deSclaudio break; 255b49634deSclaudio } 256b49634deSclaudio imsg_free(&imsg); 257b49634deSclaudio } 258b49634deSclaudio } 259b49634deSclaudio close(ctl_sock); 260b49634deSclaudio free(ibuf); 261b49634deSclaudio 262b49634deSclaudio return (0); 263b49634deSclaudio } 264b49634deSclaudio 265b49634deSclaudio int 26659df52c7Snorby show_summary_msg(struct imsg *imsg) 267b49634deSclaudio { 26859df52c7Snorby struct ctl_sum *sum; 26959df52c7Snorby struct ctl_sum_area *sumarea; 27059df52c7Snorby 27159df52c7Snorby switch (imsg->hdr.type) { 27259df52c7Snorby case IMSG_CTL_SHOW_SUM: 27359df52c7Snorby sum = imsg->data; 27459df52c7Snorby printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); 27559df52c7Snorby printf("RFC1583 compatibility flag is "); 27659df52c7Snorby if (sum->rfc1583compat) 27759df52c7Snorby printf("enabled\n"); 27859df52c7Snorby else 27959df52c7Snorby printf("disabled\n"); 28059df52c7Snorby 28159df52c7Snorby printf("SPF delay is %d sec(s), hold time between two SPFs " 28259df52c7Snorby "is %d sec(s)\n", sum->spf_delay, sum->spf_hold_time); 28359df52c7Snorby printf("Number of external LSA(s) %d\n", sum->num_ext_lsa); 28459df52c7Snorby printf("Number of areas attached to this router: %d\n", 28559df52c7Snorby sum->num_area); 28659df52c7Snorby break; 28759df52c7Snorby case IMSG_CTL_SHOW_SUM_AREA: 28859df52c7Snorby sumarea = imsg->data; 28959df52c7Snorby printf("\nArea ID: %s\n", inet_ntoa(sumarea->area)); 29059df52c7Snorby printf(" Number of interfaces in this area: %d\n", 29159df52c7Snorby sumarea->num_iface); 29259df52c7Snorby printf(" Number of fully adjacent neighbors in this " 29359df52c7Snorby "area: %d\n", sumarea->num_adj_nbr); 29459df52c7Snorby printf(" SPF algorithm executed %d time(s)\n", 29559df52c7Snorby sumarea->num_spf_calc); 29659df52c7Snorby printf(" Number LSA(s) %d\n", sumarea->num_lsa); 29759df52c7Snorby break; 29859df52c7Snorby case IMSG_CTL_END: 29959df52c7Snorby printf("\n"); 30059df52c7Snorby return (1); 30159df52c7Snorby default: 30259df52c7Snorby break; 30359df52c7Snorby } 304b49634deSclaudio 305b49634deSclaudio return (0); 306b49634deSclaudio } 307b49634deSclaudio 308b49634deSclaudio int 309b49634deSclaudio show_interface_msg(struct imsg *imsg) 310b49634deSclaudio { 311b49634deSclaudio struct ctl_iface *iface; 312b49634deSclaudio 313b49634deSclaudio switch (imsg->hdr.type) { 314b49634deSclaudio case IMSG_CTL_SHOW_INTERFACE: 315b49634deSclaudio iface = imsg->data; 316b49634deSclaudio printf("\n"); 317b49634deSclaudio printf("Interface %s is %d, line protocol is %s\n", 318b49634deSclaudio iface->name, iface->linkstate, print_link(iface->flags)); 319b49634deSclaudio printf(" Internet address %s/%d, ", 320b49634deSclaudio inet_ntoa(iface->addr), 3213ec0d80eSclaudio mask2prefixlen(iface->mask.s_addr)); 322b49634deSclaudio printf("Area %s\n", inet_ntoa(iface->area)); 323b49634deSclaudio printf(" Router ID %s, network type %s, cost: %d\n", 324b49634deSclaudio inet_ntoa(iface->rtr_id), 325b49634deSclaudio print_if_type(iface->type), iface->metric); 32659df52c7Snorby printf(" Transmit delay is %d sec(s), state %s, priority %d\n", 3271d3a1c7dSnorby iface->transmit_delay, print_if_state(iface->state), 328b49634deSclaudio iface->priority); 329b49634deSclaudio printf(" Designated Router (ID) %s, ", 330b49634deSclaudio inet_ntoa(iface->dr_id)); 331b49634deSclaudio printf("interface address %s\n", inet_ntoa(iface->dr_addr)); 332b49634deSclaudio printf(" Backup Designated Router (ID) %s, ", 333b49634deSclaudio inet_ntoa(iface->bdr_id)); 334b49634deSclaudio printf("interface address %s\n", inet_ntoa(iface->bdr_addr)); 335b49634deSclaudio printf(" Timer intervals configured, " 336b49634deSclaudio "hello %d, dead %d, wait %d, retransmit %d\n", 337b49634deSclaudio iface->hello_interval, iface->dead_interval, 338b49634deSclaudio iface->dead_interval, iface->rxmt_interval); 339b49634deSclaudio if (iface->hello_timer < 0) 340b49634deSclaudio printf(" Hello timer not running\n"); 341b49634deSclaudio else 342b49634deSclaudio printf(" Hello timer due in %s\n", 343b49634deSclaudio fmt_timeframe_core(iface->hello_timer)); 344b49634deSclaudio printf(" Neighbor count is %d, adjacent neighbor count is " 345b49634deSclaudio "%d\n", iface->nbr_cnt, iface->adj_cnt); 346b49634deSclaudio break; 347b49634deSclaudio case IMSG_CTL_END: 348b49634deSclaudio printf("\n"); 349b49634deSclaudio return (1); 350b49634deSclaudio default: 351b49634deSclaudio break; 352b49634deSclaudio } 353b49634deSclaudio 354b49634deSclaudio return (0); 355b49634deSclaudio } 356b49634deSclaudio 357b49634deSclaudio const char * 358b49634deSclaudio print_if_type(enum iface_type type) 359b49634deSclaudio { 360b49634deSclaudio switch (type) { 361b49634deSclaudio case IF_TYPE_POINTOPOINT: 362b49634deSclaudio return ("POINTOPOINT"); 363b49634deSclaudio case IF_TYPE_BROADCAST: 364b49634deSclaudio return ("BROADCAST"); 365b49634deSclaudio case IF_TYPE_NBMA: 366b49634deSclaudio return ("NBMA"); 367b49634deSclaudio case IF_TYPE_POINTOMULTIPOINT: 368b49634deSclaudio return ("POINTOMULTIPOINT"); 369b49634deSclaudio case IF_TYPE_VIRTUALLINK: 370b49634deSclaudio return ("VIRTUALLINK"); 371b49634deSclaudio default: 372b49634deSclaudio return ("UNKNOWN"); 373b49634deSclaudio } 374b49634deSclaudio } 375b49634deSclaudio 376b49634deSclaudio const char * 377b49634deSclaudio print_if_state(int state) 378b49634deSclaudio { 379b49634deSclaudio switch (state) { 380b49634deSclaudio case IF_STA_DOWN: 381b49634deSclaudio return ("DOWN"); 382b49634deSclaudio case IF_STA_LOOPBACK: 383b49634deSclaudio return ("LOOPBACK"); 384b49634deSclaudio case IF_STA_WAITING: 385b49634deSclaudio return ("WAITING"); 386b49634deSclaudio case IF_STA_POINTTOPOINT: 387b49634deSclaudio return ("P2P"); 388b49634deSclaudio case IF_STA_DROTHER: 389b49634deSclaudio return ("DROTHER"); 390b49634deSclaudio case IF_STA_BACKUP: 391b49634deSclaudio return ("BACKUP"); 392b49634deSclaudio case IF_STA_DR: 393b49634deSclaudio return ("DR"); 394b49634deSclaudio default: 395b49634deSclaudio return ("UNKNOWN"); 396b49634deSclaudio } 397b49634deSclaudio } 398b49634deSclaudio 399b49634deSclaudio const char * 400b49634deSclaudio print_nbr_state(int state) 401b49634deSclaudio { 402b49634deSclaudio switch (state) { 403b49634deSclaudio case NBR_STA_DOWN: 404b49634deSclaudio return ("DOWN"); 405b49634deSclaudio case NBR_STA_ATTEMPT: 406b49634deSclaudio return ("ATTEMPT"); 407b49634deSclaudio case NBR_STA_INIT: 408b49634deSclaudio return ("INIT"); 409b49634deSclaudio case NBR_STA_2_WAY: 410b49634deSclaudio return ("2-WAY"); 411b49634deSclaudio case NBR_STA_XSTRT: 412b49634deSclaudio return ("EXSTART"); 413b49634deSclaudio case NBR_STA_SNAP: 414b49634deSclaudio return ("SNAPSHOT"); 415b49634deSclaudio case NBR_STA_XCHNG: 416b49634deSclaudio return ("EXCHANGE"); 417b49634deSclaudio case NBR_STA_LOAD: 418b49634deSclaudio return ("LOADING"); 419b49634deSclaudio case NBR_STA_FULL: 420b49634deSclaudio return ("FULL"); 421b49634deSclaudio default: 422b49634deSclaudio return ("UNKNOWN"); 423b49634deSclaudio } 424b49634deSclaudio } 425b49634deSclaudio 426b49634deSclaudio const char * 427b49634deSclaudio print_link(int state) 428b49634deSclaudio { 429b49634deSclaudio if (state & IFF_UP) 430b49634deSclaudio return ("UP"); 431b49634deSclaudio else 432b49634deSclaudio return ("DOWN"); 433b49634deSclaudio } 434b49634deSclaudio 435b49634deSclaudio #define TF_BUFS 8 436b49634deSclaudio #define TF_LEN 9 437b49634deSclaudio 438b49634deSclaudio const char * 439b49634deSclaudio fmt_timeframe(time_t t) 440b49634deSclaudio { 441b49634deSclaudio if (t == 0) 442b49634deSclaudio return ("Never"); 443b49634deSclaudio else 444b49634deSclaudio return (fmt_timeframe_core(time(NULL) - t)); 445b49634deSclaudio } 446b49634deSclaudio 447b49634deSclaudio const char * 448b49634deSclaudio fmt_timeframe_core(time_t t) 449b49634deSclaudio { 450b49634deSclaudio char *buf; 451b49634deSclaudio static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 452b49634deSclaudio static int idx = 0; 453b49634deSclaudio unsigned sec, min, hrs, day, week; 454b49634deSclaudio 455b49634deSclaudio if (t == 0) 456b49634deSclaudio return ("Stopped"); 457b49634deSclaudio 458b49634deSclaudio buf = tfbuf[idx++]; 459b49634deSclaudio if (idx == TF_BUFS) 460b49634deSclaudio idx = 0; 461b49634deSclaudio 462b49634deSclaudio week = t; 463b49634deSclaudio 464b49634deSclaudio sec = week % 60; 465b49634deSclaudio week /= 60; 466b49634deSclaudio min = week % 60; 467b49634deSclaudio week /= 60; 468b49634deSclaudio hrs = week % 24; 469b49634deSclaudio week /= 24; 470b49634deSclaudio day = week % 7; 471b49634deSclaudio week /= 7; 472b49634deSclaudio 473b49634deSclaudio if (week > 0) 474b49634deSclaudio snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs); 475b49634deSclaudio else if (day > 0) 476b49634deSclaudio snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 477b49634deSclaudio else 478b49634deSclaudio snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 479b49634deSclaudio 480b49634deSclaudio return (buf); 481b49634deSclaudio } 482b49634deSclaudio 483b49634deSclaudio const char * 484b49634deSclaudio log_id(u_int32_t id) 485b49634deSclaudio { 486b49634deSclaudio static char buf[48]; 487b49634deSclaudio struct in_addr addr; 488b49634deSclaudio 489b49634deSclaudio addr.s_addr = id; 490b49634deSclaudio 491b49634deSclaudio if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 492b49634deSclaudio return ("?"); 493b49634deSclaudio else 494b49634deSclaudio return (buf); 495b49634deSclaudio } 496b49634deSclaudio 497b49634deSclaudio const char * 498b49634deSclaudio log_adv_rtr(u_int32_t adv_rtr) 499b49634deSclaudio { 500b49634deSclaudio static char buf[48]; 501b49634deSclaudio struct in_addr addr; 502b49634deSclaudio 503b49634deSclaudio addr.s_addr = adv_rtr; 504b49634deSclaudio 505b49634deSclaudio if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 506b49634deSclaudio return ("?"); 507b49634deSclaudio else 508b49634deSclaudio return (buf); 509b49634deSclaudio } 510b49634deSclaudio 5113ec0d80eSclaudio /* prototype defined in ospfd.h and shared with the kroute.c version */ 512b49634deSclaudio u_int8_t 5133ec0d80eSclaudio mask2prefixlen(in_addr_t ina) 514b49634deSclaudio { 5153ec0d80eSclaudio if (ina == 0) 516b49634deSclaudio return (0); 517b49634deSclaudio else 5183ec0d80eSclaudio return (33 - ffs(ntohl(ina))); 519b49634deSclaudio } 520b49634deSclaudio 521b49634deSclaudio void 522b49634deSclaudio show_database_head(struct in_addr aid, u_int8_t type) 523b49634deSclaudio { 524b49634deSclaudio char *header, *format; 525b49634deSclaudio 526b49634deSclaudio switch (type) { 527b49634deSclaudio case LSA_TYPE_ROUTER: 528b49634deSclaudio format = "Router Link States"; 529b49634deSclaudio break; 530b49634deSclaudio case LSA_TYPE_NETWORK: 531b49634deSclaudio format = "Net Link States"; 532b49634deSclaudio break; 533b49634deSclaudio case LSA_TYPE_SUM_NETWORK: 534b49634deSclaudio format = "Summary Net Link States"; 535b49634deSclaudio break; 536b49634deSclaudio case LSA_TYPE_SUM_ROUTER: 537b49634deSclaudio format = "Summary Router Link States"; 538b49634deSclaudio break; 539b49634deSclaudio case LSA_TYPE_EXTERNAL: 540b49634deSclaudio format = NULL; 541b49634deSclaudio if ((header = strdup("Type-5 AS External Link States")) == NULL) 542b49634deSclaudio err(1, NULL); 543b49634deSclaudio break; 544b49634deSclaudio default: 545b49634deSclaudio errx(1, "unknown LSA type"); 546b49634deSclaudio } 547b49634deSclaudio if (type != LSA_TYPE_EXTERNAL) 548b49634deSclaudio if (asprintf(&header, "%s (Area %s)", format, 549b49634deSclaudio inet_ntoa(aid)) == -1) 550b49634deSclaudio err(1, NULL); 551b49634deSclaudio 552*32286112Snorby printf("\n%-15s %s\n\n", "", header); 553b49634deSclaudio free(header); 554b49634deSclaudio } 555b49634deSclaudio 556b49634deSclaudio int 557b49634deSclaudio show_database_msg(struct imsg *imsg) 558b49634deSclaudio { 559b49634deSclaudio static struct in_addr area_id; 560b49634deSclaudio static u_int8_t lasttype; 561b49634deSclaudio struct area *area; 562b49634deSclaudio struct lsa_hdr *lsa; 563b49634deSclaudio 564b49634deSclaudio switch (imsg->hdr.type) { 565b49634deSclaudio case IMSG_CTL_SHOW_DATABASE: 566*32286112Snorby case IMSG_CTL_SHOW_DB_SELF: 567b49634deSclaudio lsa = imsg->data; 568*32286112Snorby if (lsa->type != lasttype) { 569b49634deSclaudio show_database_head(area_id, lsa->type); 570*32286112Snorby printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID", 571*32286112Snorby "Adv Router", "Age", "Seq#", "Checksum"); 572*32286112Snorby } 573b49634deSclaudio printf("%-15s %-15s %-4d 0x%08x 0x%04x\n", 574b49634deSclaudio log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr), 575b49634deSclaudio ntohs(lsa->age), ntohl(lsa->seq_num), 576b49634deSclaudio ntohs(lsa->ls_chksum)); 577b49634deSclaudio lasttype = lsa->type; 578b49634deSclaudio break; 579b49634deSclaudio case IMSG_CTL_AREA: 580b49634deSclaudio area = imsg->data; 581b49634deSclaudio area_id = area->id; 58243dbf367Snorby lasttype = 0; 583b49634deSclaudio break; 584b49634deSclaudio case IMSG_CTL_END: 585*32286112Snorby printf("\n"); 586*32286112Snorby return (1); 587*32286112Snorby default: 588*32286112Snorby break; 589*32286112Snorby } 590*32286112Snorby 591*32286112Snorby return (0); 592*32286112Snorby } 593*32286112Snorby 594*32286112Snorby char * 595*32286112Snorby print_ls_type(u_int8_t type) 596*32286112Snorby { 597*32286112Snorby switch (type) { 598*32286112Snorby case LSA_TYPE_ROUTER: 599*32286112Snorby return ("Router"); 600*32286112Snorby case LSA_TYPE_NETWORK: 601*32286112Snorby return ("Network"); 602*32286112Snorby case LSA_TYPE_SUM_NETWORK: 603*32286112Snorby return ("Summary (Network)"); 604*32286112Snorby case LSA_TYPE_SUM_ROUTER: 605*32286112Snorby return ("Summary (Router)"); 606*32286112Snorby case LSA_TYPE_EXTERNAL: 607*32286112Snorby return ("AS External"); 608*32286112Snorby default: 609*32286112Snorby return ("Unknown"); 610*32286112Snorby } 611*32286112Snorby } 612*32286112Snorby 613*32286112Snorby void 614*32286112Snorby show_db_hdr_msg_detail(struct lsa_hdr *lsa) 615*32286112Snorby { 616*32286112Snorby printf("LS age: %d\n", ntohs(lsa->age)); 617*32286112Snorby printf("Options: %s\n", print_ospf_options(lsa->opts)); 618*32286112Snorby printf("LS Type: %s\n", print_ls_type(lsa->type)); 619*32286112Snorby 620*32286112Snorby switch (lsa->type) { 621*32286112Snorby case LSA_TYPE_ROUTER: 622*32286112Snorby printf("Link State ID: %s\n", log_id(lsa->ls_id)); 623*32286112Snorby break; 624*32286112Snorby case LSA_TYPE_NETWORK: 625*32286112Snorby printf("Link State ID: %s (address of Designated Router)\n", 626*32286112Snorby log_id(lsa->ls_id)); 627*32286112Snorby break; 628*32286112Snorby case LSA_TYPE_SUM_NETWORK: 629*32286112Snorby printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id)); 630*32286112Snorby break; 631*32286112Snorby case LSA_TYPE_SUM_ROUTER: 632*32286112Snorby printf("Link State ID: %s (ASBR Router ID)\n", 633*32286112Snorby log_id(lsa->ls_id)); 634*32286112Snorby break; 635*32286112Snorby case LSA_TYPE_EXTERNAL: 636*32286112Snorby printf("Link State ID: %s (External Network Number)\n", 637*32286112Snorby log_id(lsa->ls_id)); 638*32286112Snorby break; 639*32286112Snorby } 640*32286112Snorby 641*32286112Snorby printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr)); 642*32286112Snorby printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num)); 643*32286112Snorby printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum)); 644*32286112Snorby printf("Length: %d\n", ntohs(lsa->len)); 645*32286112Snorby } 646*32286112Snorby 647*32286112Snorby char * 648*32286112Snorby print_rtr_link_type(u_int8_t type) 649*32286112Snorby { 650*32286112Snorby switch (type) { 651*32286112Snorby case LINK_TYPE_POINTTOPOINT: 652*32286112Snorby return ("Point-to-Point"); 653*32286112Snorby case LINK_TYPE_TRANSIT_NET: 654*32286112Snorby return ("Transit Network"); 655*32286112Snorby case LINK_TYPE_STUB_NET: 656*32286112Snorby return ("Stub Network"); 657*32286112Snorby case LINK_TYPE_VIRTUAL: 658*32286112Snorby return ("Virtual Link"); 659*32286112Snorby default: 660*32286112Snorby return ("Unknown"); 661*32286112Snorby } 662*32286112Snorby } 663*32286112Snorby 664*32286112Snorby const char * 665*32286112Snorby print_ospf_flags(u_int8_t opts) 666*32286112Snorby { 667*32286112Snorby static char optbuf[32]; 668*32286112Snorby 669*32286112Snorby snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s", 670*32286112Snorby opts & OSPF_RTR_V ? "V" : "-", 671*32286112Snorby opts & OSPF_RTR_E ? "E" : "-", 672*32286112Snorby opts & OSPF_RTR_B ? "B" : "-"); 673*32286112Snorby return (optbuf); 674*32286112Snorby } 675*32286112Snorby 676*32286112Snorby int 677*32286112Snorby show_db_msg_detail(struct imsg *imsg) 678*32286112Snorby { 679*32286112Snorby static struct in_addr area_id; 680*32286112Snorby static u_int8_t lasttype; 681*32286112Snorby struct in_addr addr, data; 682*32286112Snorby struct area *area; 683*32286112Snorby struct lsa *lsa; 684*32286112Snorby struct lsa_rtr_link *rtr_link; 685*32286112Snorby struct lsa_asext *asext; 686*32286112Snorby u_int16_t i, nlinks, off; 687*32286112Snorby 688*32286112Snorby /* XXX sanity checks! */ 689*32286112Snorby 690*32286112Snorby switch (imsg->hdr.type) { 691*32286112Snorby case IMSG_CTL_SHOW_DB_EXT: 692*32286112Snorby lsa = imsg->data; 693*32286112Snorby if (lsa->hdr.type != lasttype) 694*32286112Snorby show_database_head(area_id, lsa->hdr.type); 695*32286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 696*32286112Snorby addr.s_addr = lsa->data.asext.mask; 697*32286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 698*32286112Snorby 699*32286112Snorby asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr)); 700*32286112Snorby 701*32286112Snorby printf(" Metric type: "); 702*32286112Snorby if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) 703*32286112Snorby printf("2\n"); 704*32286112Snorby else 705*32286112Snorby printf("1\n"); 706*32286112Snorby printf(" Metric: %d\n", ntohl(asext->metric) 707*32286112Snorby & LSA_METRIC_MASK); 708*32286112Snorby addr.s_addr = asext->fw_addr; 709*32286112Snorby printf(" Forwarding Address: %s\n", inet_ntoa(addr)); 710*32286112Snorby printf(" External Route Tag: %d\n\n", ntohl(asext->ext_tag)); 711*32286112Snorby 712*32286112Snorby lasttype = lsa->hdr.type; 713*32286112Snorby break; 714*32286112Snorby case IMSG_CTL_SHOW_DB_NET: 715*32286112Snorby lsa = imsg->data; 716*32286112Snorby if (lsa->hdr.type != lasttype) 717*32286112Snorby show_database_head(area_id, lsa->hdr.type); 718*32286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 719*32286112Snorby addr.s_addr = lsa->data.net.mask; 720*32286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 721*32286112Snorby 722*32286112Snorby nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) 723*32286112Snorby - sizeof(u_int32_t)) / sizeof(struct lsa_net_link); 724*32286112Snorby off = sizeof(lsa->hdr) + sizeof(u_int32_t); 725*32286112Snorby 726*32286112Snorby for (i = 0; i < nlinks; i++) { 727*32286112Snorby addr.s_addr = lsa->data.net.att_rtr[i]; 728*32286112Snorby printf(" Attached Router: %s\n", inet_ntoa(addr)); 729*32286112Snorby } 730*32286112Snorby 731*32286112Snorby printf("\n"); 732*32286112Snorby lasttype = lsa->hdr.type; 733*32286112Snorby break; 734*32286112Snorby case IMSG_CTL_SHOW_DB_RTR: 735*32286112Snorby lsa = imsg->data; 736*32286112Snorby if (lsa->hdr.type != lasttype) 737*32286112Snorby show_database_head(area_id, lsa->hdr.type); 738*32286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 739*32286112Snorby printf("Flags: %s\n", print_ospf_flags(lsa->data.rtr.flags)); 740*32286112Snorby nlinks = ntohs(lsa->data.rtr.nlinks); 741*32286112Snorby printf("Number of Links: %d\n\n", nlinks); 742*32286112Snorby 743*32286112Snorby off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr); 744*32286112Snorby 745*32286112Snorby for (i = 0; i < nlinks; i++) { 746*32286112Snorby rtr_link = (struct lsa_rtr_link *)((char *)lsa + off); 747*32286112Snorby 748*32286112Snorby printf(" Link connected to: %s\n", 749*32286112Snorby print_rtr_link_type(rtr_link->type)); 750*32286112Snorby 751*32286112Snorby addr.s_addr = rtr_link->id; 752*32286112Snorby data.s_addr = rtr_link->data; 753*32286112Snorby 754*32286112Snorby switch (rtr_link->type) { 755*32286112Snorby case LINK_TYPE_POINTTOPOINT: 756*32286112Snorby case LINK_TYPE_VIRTUAL: 757*32286112Snorby printf(" Link ID (Neighbors Router ID):" 758*32286112Snorby " %s\n", inet_ntoa(addr)); 759*32286112Snorby printf(" Link Data (Router Interface " 760*32286112Snorby "address): %s\n", inet_ntoa(data)); 761*32286112Snorby break; 762*32286112Snorby case LINK_TYPE_TRANSIT_NET: 763*32286112Snorby printf(" Link ID (Designated Router " 764*32286112Snorby "address): %s\n", inet_ntoa(addr)); 765*32286112Snorby printf(" Link Data (Router Interface " 766*32286112Snorby "address): %s\n", inet_ntoa(data)); 767*32286112Snorby break; 768*32286112Snorby case LINK_TYPE_STUB_NET: 769*32286112Snorby printf(" Link ID (Network ID): %s\n", 770*32286112Snorby inet_ntoa(addr)); 771*32286112Snorby printf(" Link Data (Network Mask): %s\n", 772*32286112Snorby inet_ntoa(data)); 773*32286112Snorby break; 774*32286112Snorby default: 775*32286112Snorby printf(" Link ID (Unknown): %s\n", 776*32286112Snorby inet_ntoa(addr)); 777*32286112Snorby printf(" Link Data (Unknown): %s\n", 778*32286112Snorby inet_ntoa(data)); 779*32286112Snorby break; 780*32286112Snorby } 781*32286112Snorby 782*32286112Snorby printf(" Metric: %d\n\n", ntohs(rtr_link->metric)); 783*32286112Snorby 784*32286112Snorby off += sizeof(struct lsa_rtr_link) + 785*32286112Snorby rtr_link->num_tos * sizeof(u_int32_t); 786*32286112Snorby } 787*32286112Snorby 788*32286112Snorby lasttype = lsa->hdr.type; 789*32286112Snorby break; 790*32286112Snorby case IMSG_CTL_SHOW_DB_SUM: 791*32286112Snorby case IMSG_CTL_SHOW_DB_ASBR: 792*32286112Snorby lsa = imsg->data; 793*32286112Snorby if (lsa->hdr.type != lasttype) 794*32286112Snorby show_database_head(area_id, lsa->hdr.type); 795*32286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 796*32286112Snorby addr.s_addr = lsa->data.sum.mask; 797*32286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 798*32286112Snorby printf("Metric: %d\n\n", ntohl(lsa->data.sum.metric) & 799*32286112Snorby LSA_METRIC_MASK); 800*32286112Snorby lasttype = lsa->hdr.type; 801*32286112Snorby break; 802*32286112Snorby case IMSG_CTL_AREA: 803*32286112Snorby area = imsg->data; 804*32286112Snorby area_id = area->id; 805*32286112Snorby break; 806*32286112Snorby case IMSG_CTL_END: 807b49634deSclaudio return (1); 808b49634deSclaudio default: 809b49634deSclaudio break; 810b49634deSclaudio } 811b49634deSclaudio 812b49634deSclaudio return (0); 813b49634deSclaudio } 814b49634deSclaudio 815b49634deSclaudio int 816b49634deSclaudio show_nbr_msg(struct imsg *imsg) 817b49634deSclaudio { 818b49634deSclaudio struct ctl_nbr *nbr; 819b49634deSclaudio char *state; 820b49634deSclaudio 821b49634deSclaudio switch (imsg->hdr.type) { 822b49634deSclaudio case IMSG_CTL_SHOW_NBR: 823b49634deSclaudio nbr = imsg->data; 824b49634deSclaudio if (asprintf(&state, "%s/%s", print_nbr_state(nbr->nbr_state), 825b49634deSclaudio print_if_state(nbr->iface_state)) == -1) 826b49634deSclaudio err(1, NULL); 827b49634deSclaudio printf("%-15s %-3d %-17s %-9s ", inet_ntoa(nbr->id), 828b49634deSclaudio nbr->priority, state, fmt_timeframe_core(nbr->dead_timer)); 829b49634deSclaudio printf("%-15s %s\n", inet_ntoa(nbr->addr), nbr->name); 830b49634deSclaudio free(state); 831b49634deSclaudio break; 832b49634deSclaudio case IMSG_CTL_END: 833b49634deSclaudio printf("\n"); 834b49634deSclaudio return (1); 835b49634deSclaudio default: 836b49634deSclaudio break; 837b49634deSclaudio } 838b49634deSclaudio 839b49634deSclaudio return (0); 840b49634deSclaudio } 841b49634deSclaudio 842b49634deSclaudio const char * 843b49634deSclaudio print_ospf_options(u_int8_t opts) 844b49634deSclaudio { 845b49634deSclaudio static char optbuf[32]; 846b49634deSclaudio 847b49634deSclaudio snprintf(optbuf, sizeof(optbuf), "*|*|%s|%s|%s|%s|%s|*", 848b49634deSclaudio opts & OSPF_OPTION_DC ? "DC" : "-", 849b49634deSclaudio opts & OSPF_OPTION_EA ? "EA" : "-", 850b49634deSclaudio opts & OSPF_OPTION_NP ? "N/P" : "-", 851b49634deSclaudio opts & OSPF_OPTION_MC ? "MC" : "-", 852b49634deSclaudio opts & OSPF_OPTION_E ? "E" : "-"); 853b49634deSclaudio return (optbuf); 854b49634deSclaudio } 855b49634deSclaudio 856b49634deSclaudio int 857b49634deSclaudio show_nbr_detail_msg(struct imsg *imsg) 858b49634deSclaudio { 859b49634deSclaudio struct ctl_nbr *nbr; 860b49634deSclaudio 861b49634deSclaudio switch (imsg->hdr.type) { 862b49634deSclaudio case IMSG_CTL_SHOW_NBR: 863b49634deSclaudio nbr = imsg->data; 864b49634deSclaudio printf("\nNeighbor %s, ", inet_ntoa(nbr->id)); 865b49634deSclaudio printf("interface address %s\n", inet_ntoa(nbr->addr)); 866b49634deSclaudio printf(" In the area %s via interface %s\n", 867b49634deSclaudio inet_ntoa(nbr->area), nbr->name); 868b49634deSclaudio printf(" Neighbor priority is %d, " 869b49634deSclaudio "State is %s, %d state changes\n", 870b49634deSclaudio nbr->priority, print_nbr_state(nbr->nbr_state), 871b49634deSclaudio nbr->state_chng_cnt); 872b49634deSclaudio printf(" DR is %s, ", inet_ntoa(nbr->dr)); 873b49634deSclaudio printf("BDR is %s\n", inet_ntoa(nbr->bdr)); 874b49634deSclaudio printf(" Options is 0x%x %s\n", nbr->options, 875b49634deSclaudio print_ospf_options(nbr->options)); 876b49634deSclaudio printf(" Dead timer due in %s\n", 877b49634deSclaudio fmt_timeframe_core(nbr->dead_timer)); 878b49634deSclaudio printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt); 879b49634deSclaudio printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt); 880b49634deSclaudio printf(" Link State Retransmission List %d\n", 881b49634deSclaudio nbr->ls_retrans_lst_cnt); 882b49634deSclaudio break; 883b49634deSclaudio case IMSG_CTL_END: 884b49634deSclaudio printf("\n"); 885b49634deSclaudio return (1); 886b49634deSclaudio default: 887b49634deSclaudio break; 888b49634deSclaudio } 889b49634deSclaudio 890b49634deSclaudio return (0); 891b49634deSclaudio } 89237355230Snorby 89337355230Snorby int 89437355230Snorby show_rib_msg(struct imsg *imsg) 89537355230Snorby { 89637355230Snorby struct ctl_rt *rt; 89737355230Snorby char *dstnet; 89837355230Snorby 89937355230Snorby switch (imsg->hdr.type) { 90037355230Snorby case IMSG_CTL_SHOW_RIB: 90137355230Snorby rt = imsg->data; 90237355230Snorby switch (rt->d_type) { 90337355230Snorby case DT_NET: 90437355230Snorby if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), 90537355230Snorby rt->prefixlen) == -1) 90637355230Snorby err(1, NULL); 90737355230Snorby break; 90837355230Snorby case DT_RTR: 90937355230Snorby if (asprintf(&dstnet, "%s", 91037355230Snorby inet_ntoa(rt->prefix)) == -1) 91137355230Snorby err(1, NULL); 91237355230Snorby break; 91337355230Snorby default: 91437355230Snorby errx(1, "Invalid route type"); 91537355230Snorby } 91637355230Snorby 91737355230Snorby printf("%-20s %-17s %-12s %-9s %-7d\n", dstnet, 91837355230Snorby inet_ntoa(rt->nexthop), path_type_names[rt->p_type], 91937355230Snorby dst_type_names[rt->d_type], rt->cost); 92037355230Snorby free(dstnet); 92137355230Snorby break; 92237355230Snorby case IMSG_CTL_END: 92337355230Snorby printf("\n"); 92437355230Snorby return (1); 92537355230Snorby default: 92637355230Snorby break; 92737355230Snorby } 92837355230Snorby 92937355230Snorby return (0); 93037355230Snorby } 93137355230Snorby 93237355230Snorby void 93337355230Snorby show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) 93437355230Snorby { 93537355230Snorby char *header, *format; 93637355230Snorby 93737355230Snorby switch (p_type) { 93837355230Snorby case PT_INTRA_AREA: 93937355230Snorby case PT_INTER_AREA: 94037355230Snorby switch (d_type) { 94137355230Snorby case DT_NET: 94237355230Snorby format = "Network Routing Table"; 94337355230Snorby break; 94437355230Snorby case DT_RTR: 94537355230Snorby format = "Router Routing Table"; 94637355230Snorby break; 94737355230Snorby default: 94837355230Snorby errx(1, "unknown route type"); 94937355230Snorby } 95037355230Snorby break; 95137355230Snorby case PT_TYPE1_EXT: 95237355230Snorby case PT_TYPE2_EXT: 95337355230Snorby format = NULL; 95437355230Snorby if ((header = strdup("External Routing Table")) == NULL) 95537355230Snorby err(1, NULL); 95637355230Snorby break; 95737355230Snorby default: 95837355230Snorby errx(1, "unknown route type"); 95937355230Snorby } 96037355230Snorby 96137355230Snorby if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) 96237355230Snorby if (asprintf(&header, "%s (Area %s)", format, 96337355230Snorby inet_ntoa(aid)) == -1) 96437355230Snorby err(1, NULL); 96537355230Snorby 96637355230Snorby printf("\n%-15s %s\n", "", header); 96737355230Snorby free(header); 96837355230Snorby 96937355230Snorby printf("\n%-20s %-17s %-17s %-12s %-8s\n", 97037355230Snorby "Destination", "Nexthop", "Adv Router", "Path type", "Cost"); 97137355230Snorby 97237355230Snorby } 97337355230Snorby 97437355230Snorby int 97537355230Snorby show_rib_detail_msg(struct imsg *imsg) 97637355230Snorby { 97737355230Snorby static struct in_addr area_id; 97837355230Snorby struct ctl_rt *rt; 97937355230Snorby struct area *area; 98037355230Snorby char *dstnet; 98137355230Snorby static u_int8_t lasttype; 98237355230Snorby 98337355230Snorby switch (imsg->hdr.type) { 98437355230Snorby case IMSG_CTL_SHOW_RIB: 98537355230Snorby rt = imsg->data; 98637355230Snorby 98737355230Snorby switch (rt->p_type) { 98837355230Snorby case PT_INTRA_AREA: 98937355230Snorby case PT_INTER_AREA: 99037355230Snorby switch (rt->d_type) { 99137355230Snorby case DT_NET: 99237355230Snorby if (lasttype != RIB_NET) 99337355230Snorby show_rib_head(rt->area, rt->d_type, 99437355230Snorby rt->p_type); 99537355230Snorby if (asprintf(&dstnet, "%s/%d", 99637355230Snorby inet_ntoa(rt->prefix), rt->prefixlen) == -1) 99737355230Snorby err(1, NULL); 99837355230Snorby lasttype = RIB_NET; 99937355230Snorby break; 100037355230Snorby case DT_RTR: 100137355230Snorby if (lasttype != RIB_RTR) 100237355230Snorby show_rib_head(rt->area, rt->d_type, 100337355230Snorby rt->p_type); 100437355230Snorby if (asprintf(&dstnet, "%s", 100537355230Snorby inet_ntoa(rt->prefix)) == -1) 100637355230Snorby err(1, NULL); 100737355230Snorby lasttype = RIB_RTR; 100837355230Snorby break; 100937355230Snorby default: 101037355230Snorby errx(1, "unknown route type"); 101137355230Snorby } 101237355230Snorby printf("%-20s %-17s ", dstnet, inet_ntoa(rt->nexthop)); 101337355230Snorby printf("%-17s %-12s %-7d\n", inet_ntoa(rt->adv_rtr), 101437355230Snorby path_type_names[rt->p_type], rt->cost); 101537355230Snorby free(dstnet); 101637355230Snorby break; 101737355230Snorby case PT_TYPE1_EXT: 101837355230Snorby case PT_TYPE2_EXT: 101937355230Snorby /* XXX TODO */ 102037355230Snorby break; 102137355230Snorby default: 102237355230Snorby errx(1, "unknown route type"); 102337355230Snorby } 102437355230Snorby break; 102537355230Snorby case IMSG_CTL_AREA: 102637355230Snorby area = imsg->data; 102737355230Snorby area_id = area->id; 102837355230Snorby break; 102937355230Snorby case IMSG_CTL_END: 103037355230Snorby printf("\n"); 103137355230Snorby return (1); 103237355230Snorby default: 103337355230Snorby break; 103437355230Snorby } 103537355230Snorby 103637355230Snorby return (0); 103737355230Snorby } 1038c47b7f65Sclaudio 1039c47b7f65Sclaudio void 1040c47b7f65Sclaudio show_fib_head(void) 1041c47b7f65Sclaudio { 1042c47b7f65Sclaudio printf("flags: * = valid, O = OSPF, C = Connected, S = Static\n"); 1043c47b7f65Sclaudio printf("%-6s %-20s %-17s\n", "Flags", "Destination", "Nexthop"); 1044c47b7f65Sclaudio } 1045c47b7f65Sclaudio 1046c47b7f65Sclaudio int 1047c47b7f65Sclaudio show_fib_msg(struct imsg *imsg) 1048c47b7f65Sclaudio { 1049c47b7f65Sclaudio struct kroute *k; 1050c47b7f65Sclaudio char *p; 1051c47b7f65Sclaudio 1052c47b7f65Sclaudio switch (imsg->hdr.type) { 1053c47b7f65Sclaudio case IMSG_CTL_KROUTE: 1054c47b7f65Sclaudio if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) 1055c47b7f65Sclaudio errx(1, "wrong imsg len"); 1056c47b7f65Sclaudio k = imsg->data; 1057c47b7f65Sclaudio 1058c47b7f65Sclaudio if (k->flags & F_DOWN) 1059c47b7f65Sclaudio printf(" "); 1060c47b7f65Sclaudio else 1061c47b7f65Sclaudio printf("*"); 1062c47b7f65Sclaudio 1063c47b7f65Sclaudio if (k->flags & F_OSPFD_INSERTED) 1064c47b7f65Sclaudio printf("O"); 1065c47b7f65Sclaudio else if (k->flags & F_CONNECTED) 1066c47b7f65Sclaudio printf("C"); 1067fc1549e1Sclaudio else if (k->flags & F_STATIC) 1068c47b7f65Sclaudio printf("S"); 1069c47b7f65Sclaudio else 1070c47b7f65Sclaudio printf(" "); 1071c47b7f65Sclaudio 1072c47b7f65Sclaudio printf(" "); 1073c47b7f65Sclaudio if (asprintf(&p, "%s/%u", inet_ntoa(k->prefix), k->prefixlen) == 1074c47b7f65Sclaudio -1) 1075c47b7f65Sclaudio err(1, NULL); 1076c47b7f65Sclaudio printf("%-20s ", p); 1077c47b7f65Sclaudio free(p); 1078c47b7f65Sclaudio 1079c47b7f65Sclaudio if (k->nexthop.s_addr) 1080c47b7f65Sclaudio printf("%s", inet_ntoa(k->nexthop)); 1081c47b7f65Sclaudio else if (k->flags & F_CONNECTED) 1082c47b7f65Sclaudio printf("link#%u", k->ifindex); 1083c47b7f65Sclaudio printf("\n"); 1084c47b7f65Sclaudio 1085c47b7f65Sclaudio break; 1086c47b7f65Sclaudio case IMSG_CTL_END: 1087c47b7f65Sclaudio printf("\n"); 1088c47b7f65Sclaudio return (1); 1089c47b7f65Sclaudio default: 1090c47b7f65Sclaudio break; 1091c47b7f65Sclaudio } 1092c47b7f65Sclaudio 1093c47b7f65Sclaudio return (0); 1094c47b7f65Sclaudio } 1095c47b7f65Sclaudio 1096c47b7f65Sclaudio void 1097c47b7f65Sclaudio show_interface_head(void) 1098c47b7f65Sclaudio { 10994c561fb6Sclaudio printf("%-15s%-15s%s\n", "Interface", "Flags", 1100c47b7f65Sclaudio "Link state"); 1101c47b7f65Sclaudio } 1102c47b7f65Sclaudio 1103c47b7f65Sclaudio const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST; 1104c47b7f65Sclaudio const struct ifmedia_status_description 1105c47b7f65Sclaudio ifm_status_descriptions[] = IFM_STATUS_DESCRIPTIONS; 1106c47b7f65Sclaudio const struct ifmedia_description 1107c47b7f65Sclaudio ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; 1108c47b7f65Sclaudio 1109c47b7f65Sclaudio const char * 1110c47b7f65Sclaudio get_media_descr(int media_type) 1111c47b7f65Sclaudio { 1112c47b7f65Sclaudio const struct ifmedia_description *p; 1113c47b7f65Sclaudio 1114c47b7f65Sclaudio for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) 1115c47b7f65Sclaudio if (media_type == p->ifmt_word) 1116c47b7f65Sclaudio return (p->ifmt_string); 1117c47b7f65Sclaudio 1118c47b7f65Sclaudio return ("unknown media"); 1119c47b7f65Sclaudio } 1120c47b7f65Sclaudio 1121c47b7f65Sclaudio const char * 1122c47b7f65Sclaudio get_linkstate(int media_type, int link_state) 1123c47b7f65Sclaudio { 1124c47b7f65Sclaudio const struct ifmedia_status_description *p; 1125c47b7f65Sclaudio int i; 1126c47b7f65Sclaudio 1127c47b7f65Sclaudio if (link_state == LINK_STATE_UNKNOWN) 1128c47b7f65Sclaudio return ("unknown"); 1129c47b7f65Sclaudio 1130c47b7f65Sclaudio for (i = 0; ifm_status_valid_list[i] != 0; i++) 1131c47b7f65Sclaudio for (p = ifm_status_descriptions; p->ifms_valid != 0; p++) { 1132c47b7f65Sclaudio if (p->ifms_type != media_type || 1133c47b7f65Sclaudio p->ifms_valid != ifm_status_valid_list[i]) 1134c47b7f65Sclaudio continue; 1135c47b7f65Sclaudio return (p->ifms_string[link_state == LINK_STATE_UP]); 1136c47b7f65Sclaudio } 1137c47b7f65Sclaudio 1138c47b7f65Sclaudio return ("unknown link state"); 1139c47b7f65Sclaudio } 1140c47b7f65Sclaudio 1141c47b7f65Sclaudio void 1142c47b7f65Sclaudio print_baudrate(u_long baudrate) 1143c47b7f65Sclaudio { 1144c47b7f65Sclaudio if (baudrate > IF_Gbps(1)) 1145c47b7f65Sclaudio printf("%lu GBit/s", baudrate / IF_Gbps(1)); 1146c47b7f65Sclaudio else if (baudrate > IF_Mbps(1)) 1147c47b7f65Sclaudio printf("%lu MBit/s", baudrate / IF_Mbps(1)); 1148c47b7f65Sclaudio else if (baudrate > IF_Kbps(1)) 1149c47b7f65Sclaudio printf("%lu KBit/s", baudrate / IF_Kbps(1)); 1150c47b7f65Sclaudio else 1151c47b7f65Sclaudio printf("%lu Bit/s", baudrate); 1152c47b7f65Sclaudio } 1153c47b7f65Sclaudio 1154c47b7f65Sclaudio 1155c47b7f65Sclaudio int 1156c47b7f65Sclaudio show_fib_interface_msg(struct imsg *imsg) 1157c47b7f65Sclaudio { 1158c47b7f65Sclaudio struct kif *k; 1159c47b7f65Sclaudio int ifms_type; 1160c47b7f65Sclaudio 1161c47b7f65Sclaudio switch (imsg->hdr.type) { 11624c561fb6Sclaudio case IMSG_CTL_IFINFO: 1163c47b7f65Sclaudio k = imsg->data; 1164c47b7f65Sclaudio printf("%-15s", k->ifname); 1165c47b7f65Sclaudio printf("%-15s", k->flags & IFF_UP ? "UP" : ""); 1166c47b7f65Sclaudio switch (k->media_type) { 1167c47b7f65Sclaudio case IFT_ETHER: 1168c47b7f65Sclaudio ifms_type = IFM_ETHER; 1169c47b7f65Sclaudio break; 1170c47b7f65Sclaudio case IFT_FDDI: 1171c47b7f65Sclaudio ifms_type = IFM_FDDI; 1172c47b7f65Sclaudio break; 1173c47b7f65Sclaudio case IFT_ISO88025: 1174c47b7f65Sclaudio ifms_type = IFM_TOKEN; 1175c47b7f65Sclaudio break; 1176c47b7f65Sclaudio case IFT_CARP: 1177c47b7f65Sclaudio ifms_type = IFM_CARP; 1178c47b7f65Sclaudio break; 1179c47b7f65Sclaudio default: 1180c47b7f65Sclaudio ifms_type = 0; 1181c47b7f65Sclaudio break; 1182c47b7f65Sclaudio } 1183c47b7f65Sclaudio 1184c47b7f65Sclaudio if (ifms_type) 1185c47b7f65Sclaudio printf("%s, %s", get_media_descr(ifms_type), 1186c47b7f65Sclaudio get_linkstate(ifms_type, k->link_state)); 1187c47b7f65Sclaudio else if (k->link_state == LINK_STATE_UNKNOWN) 1188c47b7f65Sclaudio printf("unknown"); 1189c47b7f65Sclaudio else 1190c47b7f65Sclaudio printf("link state %u", k->link_state); 1191c47b7f65Sclaudio 1192c47b7f65Sclaudio if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { 1193c47b7f65Sclaudio printf(", "); 1194c47b7f65Sclaudio print_baudrate(k->baudrate); 1195c47b7f65Sclaudio } 1196c47b7f65Sclaudio printf("\n"); 1197c47b7f65Sclaudio break; 1198c47b7f65Sclaudio case IMSG_CTL_END: 1199c47b7f65Sclaudio printf("\n"); 1200c47b7f65Sclaudio return (1); 1201c47b7f65Sclaudio default: 1202c47b7f65Sclaudio break; 1203c47b7f65Sclaudio } 1204c47b7f65Sclaudio 1205c47b7f65Sclaudio return (0); 1206c47b7f65Sclaudio } 1207