1*7f472484Spyr /* $OpenBSD: ospfctl.c,v 1.47 2009/06/05 21:19:11 pyr 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 40cbb557dbShenning __dead void usage(void); 4159df52c7Snorby int show_summary_msg(struct imsg *); 423caca30dSnorby int get_ifms_type(int); 43b49634deSclaudio int show_interface_msg(struct imsg *); 4412bb42a0Snorby int show_interface_detail_msg(struct imsg *); 45b49634deSclaudio const char *print_link(int); 46b49634deSclaudio const char *fmt_timeframe(time_t t); 47b49634deSclaudio const char *fmt_timeframe_core(time_t t); 48b49634deSclaudio const char *log_id(u_int32_t ); 49b49634deSclaudio const char *log_adv_rtr(u_int32_t); 50b49634deSclaudio void show_database_head(struct in_addr, u_int8_t); 51b49634deSclaudio int show_database_msg(struct imsg *); 5232286112Snorby char *print_ls_type(u_int8_t); 5332286112Snorby void show_db_hdr_msg_detail(struct lsa_hdr *); 5432286112Snorby char *print_rtr_link_type(u_int8_t); 5532286112Snorby const char *print_ospf_flags(u_int8_t); 5632286112Snorby int show_db_msg_detail(struct imsg *imsg); 57b49634deSclaudio int show_nbr_msg(struct imsg *); 58b49634deSclaudio const char *print_ospf_options(u_int8_t); 59b49634deSclaudio int show_nbr_detail_msg(struct imsg *); 6037355230Snorby int show_rib_msg(struct imsg *); 6137355230Snorby void show_rib_head(struct in_addr, u_int8_t, u_int8_t); 6291e3b0aeSnorby const char *print_ospf_rtr_flags(u_int8_t); 6337355230Snorby int show_rib_detail_msg(struct imsg *); 64c47b7f65Sclaudio void show_fib_head(void); 65c47b7f65Sclaudio int show_fib_msg(struct imsg *); 66c47b7f65Sclaudio void show_interface_head(void); 67c47b7f65Sclaudio const char * get_media_descr(int); 68c47b7f65Sclaudio const char * get_linkstate(int, int); 6956babc06Sclaudio void print_baudrate(u_int64_t); 70c47b7f65Sclaudio int show_fib_interface_msg(struct imsg *); 71b49634deSclaudio 72b49634deSclaudio struct imsgbuf *ibuf; 73b49634deSclaudio 74cbb557dbShenning __dead void 75b49634deSclaudio usage(void) 76b49634deSclaudio { 77b49634deSclaudio extern char *__progname; 78b49634deSclaudio 79d1b94773Sreyk fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n", 80d1b94773Sreyk __progname); 81b49634deSclaudio exit(1); 82b49634deSclaudio } 83b49634deSclaudio 84b49634deSclaudio int 85b49634deSclaudio main(int argc, char *argv[]) 86b49634deSclaudio { 87b49634deSclaudio struct sockaddr_un sun; 88b49634deSclaudio struct parse_result *res; 89b49634deSclaudio struct imsg imsg; 90b49634deSclaudio unsigned int ifidx = 0; 91b49634deSclaudio int ctl_sock; 92b49634deSclaudio int done = 0; 93b49634deSclaudio int n; 94d1b94773Sreyk int ch; 95d1b94773Sreyk char *sockname; 96d1b94773Sreyk 97d1b94773Sreyk sockname = OSPFD_SOCKET; 98d1b94773Sreyk while ((ch = getopt(argc, argv, "s:")) != -1) { 99d1b94773Sreyk switch (ch) { 100d1b94773Sreyk case 's': 101d1b94773Sreyk sockname = optarg; 102d1b94773Sreyk break; 103d1b94773Sreyk default: 104d1b94773Sreyk usage(); 105d1b94773Sreyk /* NOTREACHED */ 106d1b94773Sreyk } 107d1b94773Sreyk } 108d1b94773Sreyk argc -= optind; 109d1b94773Sreyk argv += optind; 110b49634deSclaudio 111b49634deSclaudio /* parse options */ 112d1b94773Sreyk if ((res = parse(argc, argv)) == NULL) 113b49634deSclaudio exit(1); 114b49634deSclaudio 115b49634deSclaudio /* connect to ospfd control socket */ 116b49634deSclaudio if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 117b49634deSclaudio err(1, "socket"); 118b49634deSclaudio 119b49634deSclaudio bzero(&sun, sizeof(sun)); 120b49634deSclaudio sun.sun_family = AF_UNIX; 121d1b94773Sreyk 122d1b94773Sreyk strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path)); 123b49634deSclaudio if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 124d1b94773Sreyk err(1, "connect: %s", sockname); 125b49634deSclaudio 126b49634deSclaudio if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 127d2141824Sstevesk err(1, NULL); 128b49634deSclaudio imsg_init(ibuf, ctl_sock, NULL); 129b49634deSclaudio done = 0; 130b49634deSclaudio 131b49634deSclaudio /* process user request */ 132b49634deSclaudio switch (res->action) { 133b49634deSclaudio case NONE: 134b49634deSclaudio usage(); 135b49634deSclaudio /* not reached */ 136b49634deSclaudio case SHOW: 13759df52c7Snorby case SHOW_SUM: 138*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); 139b49634deSclaudio break; 140b49634deSclaudio case SHOW_IFACE: 14112bb42a0Snorby printf("%-11s %-18s %-6s %-10s %-10s %-8s %3s %3s\n", 14212bb42a0Snorby "Interface", "Address", "State", "HelloTimer", "Linkstate", 14312bb42a0Snorby "Uptime", "nc", "ac"); 144c5ba8b41Sderaadt /*FALLTHROUGH*/ 14512bb42a0Snorby case SHOW_IFACE_DTAIL: 146b49634deSclaudio if (*res->ifname) { 147b49634deSclaudio ifidx = if_nametoindex(res->ifname); 148b49634deSclaudio if (ifidx == 0) 149b49634deSclaudio errx(1, "no such interface %s", res->ifname); 150b49634deSclaudio } 151*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 152b49634deSclaudio &ifidx, sizeof(ifidx)); 153b49634deSclaudio break; 154b49634deSclaudio case SHOW_NBR: 155129e6b5fSnorby printf("%-15s %-3s %-12s %-8s %-15s %-9s %s\n", "ID", "Pri", 156129e6b5fSnorby "State", "DeadTime", "Address", "Iface","Uptime"); 157c5ba8b41Sderaadt /*FALLTHROUGH*/ 158b49634deSclaudio case SHOW_NBR_DTAIL: 159*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 160b49634deSclaudio break; 161b49634deSclaudio case SHOW_DB: 162*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0); 163b49634deSclaudio break; 164b49634deSclaudio case SHOW_DBBYAREA: 165*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, 166b49634deSclaudio &res->addr, sizeof(res->addr)); 167b49634deSclaudio break; 16832286112Snorby case SHOW_DBEXT: 169*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0); 17032286112Snorby break; 17132286112Snorby case SHOW_DBNET: 172*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0); 17332286112Snorby break; 17432286112Snorby case SHOW_DBRTR: 175*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0); 17632286112Snorby break; 17732286112Snorby case SHOW_DBSELF: 178*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0); 17932286112Snorby break; 18032286112Snorby case SHOW_DBSUM: 181*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0); 18232286112Snorby break; 18332286112Snorby case SHOW_DBASBR: 184*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0); 18532286112Snorby break; 18637355230Snorby case SHOW_RIB: 1877aa44f3cSnorby printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", 1887aa44f3cSnorby "Nexthop", "Path Type", "Type", "Cost", "Uptime"); 189c5ba8b41Sderaadt /*FALLTHROUGH*/ 19037355230Snorby case SHOW_RIB_DTAIL: 191*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); 19237355230Snorby break; 193c47b7f65Sclaudio case SHOW_FIB: 194c47b7f65Sclaudio if (!res->addr.s_addr) 195*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, 196c47b7f65Sclaudio &res->flags, sizeof(res->flags)); 197c47b7f65Sclaudio else 198*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, 199c47b7f65Sclaudio &res->addr, sizeof(res->addr)); 200c47b7f65Sclaudio show_fib_head(); 201c47b7f65Sclaudio break; 202c47b7f65Sclaudio case SHOW_FIB_IFACE: 2034c561fb6Sclaudio if (*res->ifname) 204*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, 2054c561fb6Sclaudio res->ifname, sizeof(res->ifname)); 2064c561fb6Sclaudio else 207*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0); 208c47b7f65Sclaudio show_interface_head(); 209c47b7f65Sclaudio break; 21073a141beSclaudio case FIB: 21173a141beSclaudio errx(1, "fib couple|decouple"); 21273a141beSclaudio break; 21373a141beSclaudio case FIB_COUPLE: 214*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0); 21573a141beSclaudio printf("couple request sent.\n"); 21673a141beSclaudio done = 1; 21773a141beSclaudio break; 21873a141beSclaudio case FIB_DECOUPLE: 219*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0); 22073a141beSclaudio printf("decouple request sent.\n"); 22173a141beSclaudio done = 1; 22273a141beSclaudio break; 223b49634deSclaudio case RELOAD: 224*7f472484Spyr imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 225b49634deSclaudio printf("reload request sent.\n"); 226b49634deSclaudio done = 1; 227b49634deSclaudio break; 228b49634deSclaudio } 229b49634deSclaudio 230b49634deSclaudio while (ibuf->w.queued) 231b49634deSclaudio if (msgbuf_write(&ibuf->w) < 0) 232b49634deSclaudio err(1, "write error"); 233b49634deSclaudio 234b49634deSclaudio while (!done) { 235b49634deSclaudio if ((n = imsg_read(ibuf)) == -1) 236b49634deSclaudio errx(1, "imsg_read error"); 237b49634deSclaudio if (n == 0) 238b49634deSclaudio errx(1, "pipe closed"); 239b49634deSclaudio 240b49634deSclaudio while (!done) { 241b49634deSclaudio if ((n = imsg_get(ibuf, &imsg)) == -1) 242b49634deSclaudio errx(1, "imsg_get error"); 243b49634deSclaudio if (n == 0) 244b49634deSclaudio break; 245b49634deSclaudio switch (res->action) { 246b49634deSclaudio case SHOW: 24759df52c7Snorby case SHOW_SUM: 24859df52c7Snorby done = show_summary_msg(&imsg); 249b49634deSclaudio break; 250b49634deSclaudio case SHOW_IFACE: 251b49634deSclaudio done = show_interface_msg(&imsg); 252b49634deSclaudio break; 25312bb42a0Snorby case SHOW_IFACE_DTAIL: 25412bb42a0Snorby done = show_interface_detail_msg(&imsg); 25512bb42a0Snorby break; 256b49634deSclaudio case SHOW_NBR: 257b49634deSclaudio done = show_nbr_msg(&imsg); 258b49634deSclaudio break; 259b49634deSclaudio case SHOW_NBR_DTAIL: 260b49634deSclaudio done = show_nbr_detail_msg(&imsg); 261b49634deSclaudio break; 262b49634deSclaudio case SHOW_DB: 263b49634deSclaudio case SHOW_DBBYAREA: 26432286112Snorby case SHOW_DBSELF: 265b49634deSclaudio done = show_database_msg(&imsg); 266b49634deSclaudio break; 26732286112Snorby case SHOW_DBEXT: 26832286112Snorby case SHOW_DBNET: 26932286112Snorby case SHOW_DBRTR: 27032286112Snorby case SHOW_DBSUM: 27132286112Snorby case SHOW_DBASBR: 27232286112Snorby done = show_db_msg_detail(&imsg); 27332286112Snorby break; 27437355230Snorby case SHOW_RIB: 27537355230Snorby done = show_rib_msg(&imsg); 27637355230Snorby break; 27737355230Snorby case SHOW_RIB_DTAIL: 27837355230Snorby done = show_rib_detail_msg(&imsg); 27937355230Snorby break; 280c47b7f65Sclaudio case SHOW_FIB: 281c47b7f65Sclaudio done = show_fib_msg(&imsg); 282c47b7f65Sclaudio break; 283c47b7f65Sclaudio case SHOW_FIB_IFACE: 284c47b7f65Sclaudio done = show_fib_interface_msg(&imsg); 285c47b7f65Sclaudio break; 286b49634deSclaudio case NONE: 28773a141beSclaudio case FIB: 28873a141beSclaudio case FIB_COUPLE: 28973a141beSclaudio case FIB_DECOUPLE: 290b49634deSclaudio case RELOAD: 291b49634deSclaudio break; 292b49634deSclaudio } 293b49634deSclaudio imsg_free(&imsg); 294b49634deSclaudio } 295b49634deSclaudio } 296b49634deSclaudio close(ctl_sock); 297b49634deSclaudio free(ibuf); 298b49634deSclaudio 299b49634deSclaudio return (0); 300b49634deSclaudio } 301b49634deSclaudio 302b49634deSclaudio int 30359df52c7Snorby show_summary_msg(struct imsg *imsg) 304b49634deSclaudio { 30559df52c7Snorby struct ctl_sum *sum; 30659df52c7Snorby struct ctl_sum_area *sumarea; 30759df52c7Snorby 30859df52c7Snorby switch (imsg->hdr.type) { 30959df52c7Snorby case IMSG_CTL_SHOW_SUM: 31059df52c7Snorby sum = imsg->data; 31159df52c7Snorby printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); 31211c16ffaSnorby printf("Uptime: %s\n", fmt_timeframe_core(sum->uptime)); 31359df52c7Snorby printf("RFC1583 compatibility flag is "); 31459df52c7Snorby if (sum->rfc1583compat) 31559df52c7Snorby printf("enabled\n"); 31659df52c7Snorby else 31759df52c7Snorby printf("disabled\n"); 31859df52c7Snorby 31959df52c7Snorby printf("SPF delay is %d sec(s), hold time between two SPFs " 32059df52c7Snorby "is %d sec(s)\n", sum->spf_delay, sum->spf_hold_time); 32159df52c7Snorby printf("Number of external LSA(s) %d\n", sum->num_ext_lsa); 32259df52c7Snorby printf("Number of areas attached to this router: %d\n", 32359df52c7Snorby sum->num_area); 32459df52c7Snorby break; 32559df52c7Snorby case IMSG_CTL_SHOW_SUM_AREA: 32659df52c7Snorby sumarea = imsg->data; 32759df52c7Snorby printf("\nArea ID: %s\n", inet_ntoa(sumarea->area)); 32859df52c7Snorby printf(" Number of interfaces in this area: %d\n", 32959df52c7Snorby sumarea->num_iface); 33059df52c7Snorby printf(" Number of fully adjacent neighbors in this " 33159df52c7Snorby "area: %d\n", sumarea->num_adj_nbr); 33259df52c7Snorby printf(" SPF algorithm executed %d time(s)\n", 33359df52c7Snorby sumarea->num_spf_calc); 33459df52c7Snorby printf(" Number LSA(s) %d\n", sumarea->num_lsa); 33559df52c7Snorby break; 33659df52c7Snorby case IMSG_CTL_END: 33759df52c7Snorby printf("\n"); 33859df52c7Snorby return (1); 33959df52c7Snorby default: 34059df52c7Snorby break; 34159df52c7Snorby } 342b49634deSclaudio 343b49634deSclaudio return (0); 344b49634deSclaudio } 345b49634deSclaudio 346b49634deSclaudio int 3473caca30dSnorby get_ifms_type(int mediatype) 3483caca30dSnorby { 3493caca30dSnorby switch (mediatype) { 3503caca30dSnorby case IFT_ETHER: 3513caca30dSnorby return (IFM_ETHER); 3523caca30dSnorby case IFT_FDDI: 3533caca30dSnorby return (IFM_FDDI); 3543caca30dSnorby case IFT_CARP: 3553caca30dSnorby return (IFM_CARP); 356a5bcf77aSclaudio case IFT_PPP: 357a5bcf77aSclaudio return (IFM_TDM); 3583caca30dSnorby default: 3593caca30dSnorby return (0); 3603caca30dSnorby } 3613caca30dSnorby } 3623caca30dSnorby 3633caca30dSnorby int 364b49634deSclaudio show_interface_msg(struct imsg *imsg) 365b49634deSclaudio { 366b49634deSclaudio struct ctl_iface *iface; 36712bb42a0Snorby char *netid; 36812bb42a0Snorby 36912bb42a0Snorby switch (imsg->hdr.type) { 37012bb42a0Snorby case IMSG_CTL_SHOW_INTERFACE: 37112bb42a0Snorby iface = imsg->data; 37212bb42a0Snorby 37312bb42a0Snorby if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), 37412bb42a0Snorby mask2prefixlen(iface->mask.s_addr)) == -1) 37512bb42a0Snorby err(1, NULL); 37612bb42a0Snorby printf("%-11s %-18s %-6s %-10s %-10s %s %3d %3d\n", 37712bb42a0Snorby iface->name, netid, if_state_name(iface->state), 3780cfd0ba2Sclaudio iface->hello_timer < 0 ? "-" : 37912bb42a0Snorby fmt_timeframe_core(iface->hello_timer), 3803caca30dSnorby get_linkstate(get_ifms_type(iface->mediatype), 38111c16ffaSnorby iface->linkstate), fmt_timeframe_core(iface->uptime), 38211c16ffaSnorby iface->nbr_cnt, iface->adj_cnt); 38312bb42a0Snorby free(netid); 38412bb42a0Snorby break; 38512bb42a0Snorby case IMSG_CTL_END: 38612bb42a0Snorby printf("\n"); 38712bb42a0Snorby return (1); 38812bb42a0Snorby default: 38912bb42a0Snorby break; 39012bb42a0Snorby } 39112bb42a0Snorby 39212bb42a0Snorby return (0); 39312bb42a0Snorby } 39412bb42a0Snorby 39512bb42a0Snorby int 39612bb42a0Snorby show_interface_detail_msg(struct imsg *imsg) 39712bb42a0Snorby { 39812bb42a0Snorby struct ctl_iface *iface; 399b49634deSclaudio 400b49634deSclaudio switch (imsg->hdr.type) { 401b49634deSclaudio case IMSG_CTL_SHOW_INTERFACE: 402b49634deSclaudio iface = imsg->data; 403b49634deSclaudio printf("\n"); 4043caca30dSnorby printf("Interface %s, line protocol is %s\n", 4053caca30dSnorby iface->name, print_link(iface->flags)); 406b49634deSclaudio printf(" Internet address %s/%d, ", 407b49634deSclaudio inet_ntoa(iface->addr), 4083ec0d80eSclaudio mask2prefixlen(iface->mask.s_addr)); 409b49634deSclaudio printf("Area %s\n", inet_ntoa(iface->area)); 4103caca30dSnorby printf(" Linkstate %s\n", 4113caca30dSnorby get_linkstate(get_ifms_type(iface->mediatype), 4123caca30dSnorby iface->linkstate)); 413b49634deSclaudio printf(" Router ID %s, network type %s, cost: %d\n", 414b49634deSclaudio inet_ntoa(iface->rtr_id), 4159ac7929fSclaudio if_type_name(iface->type), iface->metric); 41659df52c7Snorby printf(" Transmit delay is %d sec(s), state %s, priority %d\n", 4179ac7929fSclaudio iface->transmit_delay, if_state_name(iface->state), 418b49634deSclaudio iface->priority); 419b49634deSclaudio printf(" Designated Router (ID) %s, ", 420b49634deSclaudio inet_ntoa(iface->dr_id)); 421b49634deSclaudio printf("interface address %s\n", inet_ntoa(iface->dr_addr)); 422b49634deSclaudio printf(" Backup Designated Router (ID) %s, ", 423b49634deSclaudio inet_ntoa(iface->bdr_id)); 424b49634deSclaudio printf("interface address %s\n", inet_ntoa(iface->bdr_addr)); 425b49634deSclaudio printf(" Timer intervals configured, " 426b49634deSclaudio "hello %d, dead %d, wait %d, retransmit %d\n", 427b49634deSclaudio iface->hello_interval, iface->dead_interval, 428b49634deSclaudio iface->dead_interval, iface->rxmt_interval); 429a68e4c86Sstevesk if (iface->passive) 430a68e4c86Sstevesk printf(" Passive interface (No Hellos)\n"); 431a68e4c86Sstevesk else if (iface->hello_timer < 0) 432b49634deSclaudio printf(" Hello timer not running\n"); 433b49634deSclaudio else 434b49634deSclaudio printf(" Hello timer due in %s\n", 435b49634deSclaudio fmt_timeframe_core(iface->hello_timer)); 43611c16ffaSnorby printf(" Uptime %s\n", fmt_timeframe_core(iface->uptime)); 437b49634deSclaudio printf(" Neighbor count is %d, adjacent neighbor count is " 438b49634deSclaudio "%d\n", iface->nbr_cnt, iface->adj_cnt); 439a4aef966Smsf if (iface->auth_type > 0) { 440a4aef966Smsf switch (iface->auth_type) { 441a4aef966Smsf case AUTH_SIMPLE: 442a4aef966Smsf printf(" Simple password authentication " 443a4aef966Smsf "enabled\n"); 4449b01acb5Sstevesk break; 445a4aef966Smsf case AUTH_CRYPT: 446a4aef966Smsf printf(" Message digest authentication " 447a4aef966Smsf "enabled\n"); 448a4aef966Smsf printf(" Primary key id is %d\n", 449a4aef966Smsf iface->auth_keyid); 4509b01acb5Sstevesk break; 451a4aef966Smsf default: 452a4aef966Smsf break; 453a4aef966Smsf } 454a4aef966Smsf } 455b49634deSclaudio break; 456b49634deSclaudio case IMSG_CTL_END: 457b49634deSclaudio printf("\n"); 458b49634deSclaudio return (1); 459b49634deSclaudio default: 460b49634deSclaudio break; 461b49634deSclaudio } 462b49634deSclaudio 463b49634deSclaudio return (0); 464b49634deSclaudio } 465b49634deSclaudio 466b49634deSclaudio const char * 467b49634deSclaudio print_link(int state) 468b49634deSclaudio { 469b49634deSclaudio if (state & IFF_UP) 470b49634deSclaudio return ("UP"); 471b49634deSclaudio else 472b49634deSclaudio return ("DOWN"); 473b49634deSclaudio } 474b49634deSclaudio 475b49634deSclaudio #define TF_BUFS 8 476b49634deSclaudio #define TF_LEN 9 477b49634deSclaudio 478b49634deSclaudio const char * 479b49634deSclaudio fmt_timeframe(time_t t) 480b49634deSclaudio { 481b49634deSclaudio if (t == 0) 482b49634deSclaudio return ("Never"); 483b49634deSclaudio else 484b49634deSclaudio return (fmt_timeframe_core(time(NULL) - t)); 485b49634deSclaudio } 486b49634deSclaudio 487b49634deSclaudio const char * 488b49634deSclaudio fmt_timeframe_core(time_t t) 489b49634deSclaudio { 490b49634deSclaudio char *buf; 491b49634deSclaudio static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 492b49634deSclaudio static int idx = 0; 493db93f2f1Sderaadt unsigned int sec, min, hrs, day, week; 494b49634deSclaudio 495b49634deSclaudio if (t == 0) 49611c16ffaSnorby return ("00:00:00"); 497b49634deSclaudio 498b49634deSclaudio buf = tfbuf[idx++]; 499b49634deSclaudio if (idx == TF_BUFS) 500b49634deSclaudio idx = 0; 501b49634deSclaudio 502b49634deSclaudio week = t; 503b49634deSclaudio 504b49634deSclaudio sec = week % 60; 505b49634deSclaudio week /= 60; 506b49634deSclaudio min = week % 60; 507b49634deSclaudio week /= 60; 508b49634deSclaudio hrs = week % 24; 509b49634deSclaudio week /= 24; 510b49634deSclaudio day = week % 7; 511b49634deSclaudio week /= 7; 512b49634deSclaudio 513b49634deSclaudio if (week > 0) 514b49634deSclaudio snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs); 515b49634deSclaudio else if (day > 0) 516b49634deSclaudio snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 517b49634deSclaudio else 518b49634deSclaudio snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 519b49634deSclaudio 520b49634deSclaudio return (buf); 521b49634deSclaudio } 522b49634deSclaudio 523b49634deSclaudio const char * 524b49634deSclaudio log_id(u_int32_t id) 525b49634deSclaudio { 526b49634deSclaudio static char buf[48]; 527b49634deSclaudio struct in_addr addr; 528b49634deSclaudio 529b49634deSclaudio addr.s_addr = id; 530b49634deSclaudio 531b49634deSclaudio if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 532b49634deSclaudio return ("?"); 533b49634deSclaudio else 534b49634deSclaudio return (buf); 535b49634deSclaudio } 536b49634deSclaudio 537b49634deSclaudio const char * 538b49634deSclaudio log_adv_rtr(u_int32_t adv_rtr) 539b49634deSclaudio { 540b49634deSclaudio static char buf[48]; 541b49634deSclaudio struct in_addr addr; 542b49634deSclaudio 543b49634deSclaudio addr.s_addr = adv_rtr; 544b49634deSclaudio 545b49634deSclaudio if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 546b49634deSclaudio return ("?"); 547b49634deSclaudio else 548b49634deSclaudio return (buf); 549b49634deSclaudio } 550b49634deSclaudio 5513ec0d80eSclaudio /* prototype defined in ospfd.h and shared with the kroute.c version */ 552b49634deSclaudio u_int8_t 5533ec0d80eSclaudio mask2prefixlen(in_addr_t ina) 554b49634deSclaudio { 5553ec0d80eSclaudio if (ina == 0) 556b49634deSclaudio return (0); 557b49634deSclaudio else 5583ec0d80eSclaudio return (33 - ffs(ntohl(ina))); 559b49634deSclaudio } 560b49634deSclaudio 561b49634deSclaudio void 562b49634deSclaudio show_database_head(struct in_addr aid, u_int8_t type) 563b49634deSclaudio { 564b49634deSclaudio char *header, *format; 565b49634deSclaudio 566b49634deSclaudio switch (type) { 567b49634deSclaudio case LSA_TYPE_ROUTER: 568b49634deSclaudio format = "Router Link States"; 569b49634deSclaudio break; 570b49634deSclaudio case LSA_TYPE_NETWORK: 571b49634deSclaudio format = "Net Link States"; 572b49634deSclaudio break; 573b49634deSclaudio case LSA_TYPE_SUM_NETWORK: 574b49634deSclaudio format = "Summary Net Link States"; 575b49634deSclaudio break; 576b49634deSclaudio case LSA_TYPE_SUM_ROUTER: 577b49634deSclaudio format = "Summary Router Link States"; 578b49634deSclaudio break; 579b49634deSclaudio case LSA_TYPE_EXTERNAL: 580b49634deSclaudio format = NULL; 581b49634deSclaudio if ((header = strdup("Type-5 AS External Link States")) == NULL) 582b49634deSclaudio err(1, NULL); 583b49634deSclaudio break; 584b49634deSclaudio default: 585b49634deSclaudio errx(1, "unknown LSA type"); 586b49634deSclaudio } 587b49634deSclaudio if (type != LSA_TYPE_EXTERNAL) 588b49634deSclaudio if (asprintf(&header, "%s (Area %s)", format, 589b49634deSclaudio inet_ntoa(aid)) == -1) 590b49634deSclaudio err(1, NULL); 591b49634deSclaudio 59232286112Snorby printf("\n%-15s %s\n\n", "", header); 593b49634deSclaudio free(header); 594b49634deSclaudio } 595b49634deSclaudio 596b49634deSclaudio int 597b49634deSclaudio show_database_msg(struct imsg *imsg) 598b49634deSclaudio { 599b49634deSclaudio static struct in_addr area_id; 600b49634deSclaudio static u_int8_t lasttype; 601b49634deSclaudio struct area *area; 602b49634deSclaudio struct lsa_hdr *lsa; 603b49634deSclaudio 604b49634deSclaudio switch (imsg->hdr.type) { 605b49634deSclaudio case IMSG_CTL_SHOW_DATABASE: 60632286112Snorby case IMSG_CTL_SHOW_DB_SELF: 607b49634deSclaudio lsa = imsg->data; 60832286112Snorby if (lsa->type != lasttype) { 609b49634deSclaudio show_database_head(area_id, lsa->type); 61032286112Snorby printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID", 61132286112Snorby "Adv Router", "Age", "Seq#", "Checksum"); 61232286112Snorby } 613b49634deSclaudio printf("%-15s %-15s %-4d 0x%08x 0x%04x\n", 614b49634deSclaudio log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr), 615b49634deSclaudio ntohs(lsa->age), ntohl(lsa->seq_num), 616b49634deSclaudio ntohs(lsa->ls_chksum)); 617b49634deSclaudio lasttype = lsa->type; 618b49634deSclaudio break; 619b49634deSclaudio case IMSG_CTL_AREA: 620b49634deSclaudio area = imsg->data; 621b49634deSclaudio area_id = area->id; 62243dbf367Snorby lasttype = 0; 623b49634deSclaudio break; 624b49634deSclaudio case IMSG_CTL_END: 62532286112Snorby printf("\n"); 62632286112Snorby return (1); 62732286112Snorby default: 62832286112Snorby break; 62932286112Snorby } 63032286112Snorby 63132286112Snorby return (0); 63232286112Snorby } 63332286112Snorby 63432286112Snorby char * 63532286112Snorby print_ls_type(u_int8_t type) 63632286112Snorby { 63732286112Snorby switch (type) { 63832286112Snorby case LSA_TYPE_ROUTER: 63932286112Snorby return ("Router"); 64032286112Snorby case LSA_TYPE_NETWORK: 64132286112Snorby return ("Network"); 64232286112Snorby case LSA_TYPE_SUM_NETWORK: 64332286112Snorby return ("Summary (Network)"); 64432286112Snorby case LSA_TYPE_SUM_ROUTER: 64532286112Snorby return ("Summary (Router)"); 64632286112Snorby case LSA_TYPE_EXTERNAL: 64732286112Snorby return ("AS External"); 64832286112Snorby default: 64932286112Snorby return ("Unknown"); 65032286112Snorby } 65132286112Snorby } 65232286112Snorby 65332286112Snorby void 65432286112Snorby show_db_hdr_msg_detail(struct lsa_hdr *lsa) 65532286112Snorby { 65632286112Snorby printf("LS age: %d\n", ntohs(lsa->age)); 65732286112Snorby printf("Options: %s\n", print_ospf_options(lsa->opts)); 65832286112Snorby printf("LS Type: %s\n", print_ls_type(lsa->type)); 65932286112Snorby 66032286112Snorby switch (lsa->type) { 66132286112Snorby case LSA_TYPE_ROUTER: 66232286112Snorby printf("Link State ID: %s\n", log_id(lsa->ls_id)); 66332286112Snorby break; 66432286112Snorby case LSA_TYPE_NETWORK: 66532286112Snorby printf("Link State ID: %s (address of Designated Router)\n", 66632286112Snorby log_id(lsa->ls_id)); 66732286112Snorby break; 66832286112Snorby case LSA_TYPE_SUM_NETWORK: 66932286112Snorby printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id)); 67032286112Snorby break; 67132286112Snorby case LSA_TYPE_SUM_ROUTER: 67232286112Snorby printf("Link State ID: %s (ASBR Router ID)\n", 67332286112Snorby log_id(lsa->ls_id)); 67432286112Snorby break; 67532286112Snorby case LSA_TYPE_EXTERNAL: 67632286112Snorby printf("Link State ID: %s (External Network Number)\n", 67732286112Snorby log_id(lsa->ls_id)); 67832286112Snorby break; 67932286112Snorby } 68032286112Snorby 68132286112Snorby printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr)); 68232286112Snorby printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num)); 68332286112Snorby printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum)); 68432286112Snorby printf("Length: %d\n", ntohs(lsa->len)); 68532286112Snorby } 68632286112Snorby 68732286112Snorby char * 68832286112Snorby print_rtr_link_type(u_int8_t type) 68932286112Snorby { 69032286112Snorby switch (type) { 69132286112Snorby case LINK_TYPE_POINTTOPOINT: 69232286112Snorby return ("Point-to-Point"); 69332286112Snorby case LINK_TYPE_TRANSIT_NET: 69432286112Snorby return ("Transit Network"); 69532286112Snorby case LINK_TYPE_STUB_NET: 69632286112Snorby return ("Stub Network"); 69732286112Snorby case LINK_TYPE_VIRTUAL: 69832286112Snorby return ("Virtual Link"); 69932286112Snorby default: 70032286112Snorby return ("Unknown"); 70132286112Snorby } 70232286112Snorby } 70332286112Snorby 70432286112Snorby const char * 70532286112Snorby print_ospf_flags(u_int8_t opts) 70632286112Snorby { 70732286112Snorby static char optbuf[32]; 70832286112Snorby 70932286112Snorby snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s", 71032286112Snorby opts & OSPF_RTR_V ? "V" : "-", 71132286112Snorby opts & OSPF_RTR_E ? "E" : "-", 71232286112Snorby opts & OSPF_RTR_B ? "B" : "-"); 71332286112Snorby return (optbuf); 71432286112Snorby } 71532286112Snorby 71632286112Snorby int 71732286112Snorby show_db_msg_detail(struct imsg *imsg) 71832286112Snorby { 71932286112Snorby static struct in_addr area_id; 72032286112Snorby static u_int8_t lasttype; 72132286112Snorby struct in_addr addr, data; 72232286112Snorby struct area *area; 72332286112Snorby struct lsa *lsa; 72432286112Snorby struct lsa_rtr_link *rtr_link; 72532286112Snorby struct lsa_asext *asext; 72632286112Snorby u_int16_t i, nlinks, off; 72732286112Snorby 72832286112Snorby /* XXX sanity checks! */ 72932286112Snorby 73032286112Snorby switch (imsg->hdr.type) { 73132286112Snorby case IMSG_CTL_SHOW_DB_EXT: 73232286112Snorby lsa = imsg->data; 73332286112Snorby if (lsa->hdr.type != lasttype) 73432286112Snorby show_database_head(area_id, lsa->hdr.type); 73532286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 73632286112Snorby addr.s_addr = lsa->data.asext.mask; 73732286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 73832286112Snorby 73932286112Snorby asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr)); 74032286112Snorby 74132286112Snorby printf(" Metric type: "); 74232286112Snorby if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) 74332286112Snorby printf("2\n"); 74432286112Snorby else 74532286112Snorby printf("1\n"); 74632286112Snorby printf(" Metric: %d\n", ntohl(asext->metric) 74732286112Snorby & LSA_METRIC_MASK); 74832286112Snorby addr.s_addr = asext->fw_addr; 74932286112Snorby printf(" Forwarding Address: %s\n", inet_ntoa(addr)); 75032286112Snorby printf(" External Route Tag: %d\n\n", ntohl(asext->ext_tag)); 75132286112Snorby 75232286112Snorby lasttype = lsa->hdr.type; 75332286112Snorby break; 75432286112Snorby case IMSG_CTL_SHOW_DB_NET: 75532286112Snorby lsa = imsg->data; 75632286112Snorby if (lsa->hdr.type != lasttype) 75732286112Snorby show_database_head(area_id, lsa->hdr.type); 75832286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 75932286112Snorby addr.s_addr = lsa->data.net.mask; 76032286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 76132286112Snorby 76232286112Snorby nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) 76332286112Snorby - sizeof(u_int32_t)) / sizeof(struct lsa_net_link); 76432286112Snorby off = sizeof(lsa->hdr) + sizeof(u_int32_t); 76532286112Snorby 76632286112Snorby for (i = 0; i < nlinks; i++) { 76732286112Snorby addr.s_addr = lsa->data.net.att_rtr[i]; 76832286112Snorby printf(" Attached Router: %s\n", inet_ntoa(addr)); 76932286112Snorby } 77032286112Snorby 77132286112Snorby printf("\n"); 77232286112Snorby lasttype = lsa->hdr.type; 77332286112Snorby break; 77432286112Snorby case IMSG_CTL_SHOW_DB_RTR: 77532286112Snorby lsa = imsg->data; 77632286112Snorby if (lsa->hdr.type != lasttype) 77732286112Snorby show_database_head(area_id, lsa->hdr.type); 77832286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 77932286112Snorby printf("Flags: %s\n", print_ospf_flags(lsa->data.rtr.flags)); 78032286112Snorby nlinks = ntohs(lsa->data.rtr.nlinks); 78132286112Snorby printf("Number of Links: %d\n\n", nlinks); 78232286112Snorby 78332286112Snorby off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr); 78432286112Snorby 78532286112Snorby for (i = 0; i < nlinks; i++) { 78632286112Snorby rtr_link = (struct lsa_rtr_link *)((char *)lsa + off); 78732286112Snorby 78832286112Snorby printf(" Link connected to: %s\n", 78932286112Snorby print_rtr_link_type(rtr_link->type)); 79032286112Snorby 79132286112Snorby addr.s_addr = rtr_link->id; 79232286112Snorby data.s_addr = rtr_link->data; 79332286112Snorby 79432286112Snorby switch (rtr_link->type) { 79532286112Snorby case LINK_TYPE_POINTTOPOINT: 79632286112Snorby case LINK_TYPE_VIRTUAL: 79732286112Snorby printf(" Link ID (Neighbors Router ID):" 79832286112Snorby " %s\n", inet_ntoa(addr)); 79932286112Snorby printf(" Link Data (Router Interface " 80032286112Snorby "address): %s\n", inet_ntoa(data)); 80132286112Snorby break; 80232286112Snorby case LINK_TYPE_TRANSIT_NET: 80332286112Snorby printf(" Link ID (Designated Router " 80432286112Snorby "address): %s\n", inet_ntoa(addr)); 80532286112Snorby printf(" Link Data (Router Interface " 80632286112Snorby "address): %s\n", inet_ntoa(data)); 80732286112Snorby break; 80832286112Snorby case LINK_TYPE_STUB_NET: 80932286112Snorby printf(" Link ID (Network ID): %s\n", 81032286112Snorby inet_ntoa(addr)); 81132286112Snorby printf(" Link Data (Network Mask): %s\n", 81232286112Snorby inet_ntoa(data)); 81332286112Snorby break; 81432286112Snorby default: 81532286112Snorby printf(" Link ID (Unknown): %s\n", 81632286112Snorby inet_ntoa(addr)); 81732286112Snorby printf(" Link Data (Unknown): %s\n", 81832286112Snorby inet_ntoa(data)); 81932286112Snorby break; 82032286112Snorby } 82132286112Snorby 82232286112Snorby printf(" Metric: %d\n\n", ntohs(rtr_link->metric)); 82332286112Snorby 82432286112Snorby off += sizeof(struct lsa_rtr_link) + 82532286112Snorby rtr_link->num_tos * sizeof(u_int32_t); 82632286112Snorby } 82732286112Snorby 82832286112Snorby lasttype = lsa->hdr.type; 82932286112Snorby break; 83032286112Snorby case IMSG_CTL_SHOW_DB_SUM: 83132286112Snorby case IMSG_CTL_SHOW_DB_ASBR: 83232286112Snorby lsa = imsg->data; 83332286112Snorby if (lsa->hdr.type != lasttype) 83432286112Snorby show_database_head(area_id, lsa->hdr.type); 83532286112Snorby show_db_hdr_msg_detail(&lsa->hdr); 83632286112Snorby addr.s_addr = lsa->data.sum.mask; 83732286112Snorby printf("Network Mask: %s\n", inet_ntoa(addr)); 83832286112Snorby printf("Metric: %d\n\n", ntohl(lsa->data.sum.metric) & 83932286112Snorby LSA_METRIC_MASK); 84032286112Snorby lasttype = lsa->hdr.type; 84132286112Snorby break; 84232286112Snorby case IMSG_CTL_AREA: 84332286112Snorby area = imsg->data; 84432286112Snorby area_id = area->id; 84515904804Snorby lasttype = 0; 84632286112Snorby break; 84732286112Snorby case IMSG_CTL_END: 848b49634deSclaudio return (1); 849b49634deSclaudio default: 850b49634deSclaudio break; 851b49634deSclaudio } 852b49634deSclaudio 853b49634deSclaudio return (0); 854b49634deSclaudio } 855b49634deSclaudio 856b49634deSclaudio int 857b49634deSclaudio show_nbr_msg(struct imsg *imsg) 858b49634deSclaudio { 859b49634deSclaudio struct ctl_nbr *nbr; 860b49634deSclaudio char *state; 861b49634deSclaudio 862b49634deSclaudio switch (imsg->hdr.type) { 863b49634deSclaudio case IMSG_CTL_SHOW_NBR: 864b49634deSclaudio nbr = imsg->data; 8659ac7929fSclaudio if (asprintf(&state, "%s/%s", nbr_state_name(nbr->nbr_state), 8669ac7929fSclaudio if_state_name(nbr->iface_state)) == -1) 867b49634deSclaudio err(1, NULL); 868129e6b5fSnorby printf("%-15s %-3d %-12s %-9s", inet_ntoa(nbr->id), 869b49634deSclaudio nbr->priority, state, fmt_timeframe_core(nbr->dead_timer)); 870129e6b5fSnorby printf("%-15s %-9s %s\n", inet_ntoa(nbr->addr), nbr->name, 871129e6b5fSnorby nbr->uptime == 0 ? "-" : fmt_timeframe_core(nbr->uptime)); 872b49634deSclaudio free(state); 873b49634deSclaudio break; 874b49634deSclaudio case IMSG_CTL_END: 875b49634deSclaudio printf("\n"); 876b49634deSclaudio return (1); 877b49634deSclaudio default: 878b49634deSclaudio break; 879b49634deSclaudio } 880b49634deSclaudio 881b49634deSclaudio return (0); 882b49634deSclaudio } 883b49634deSclaudio 884b49634deSclaudio const char * 885b49634deSclaudio print_ospf_options(u_int8_t opts) 886b49634deSclaudio { 887b49634deSclaudio static char optbuf[32]; 888b49634deSclaudio 889b49634deSclaudio snprintf(optbuf, sizeof(optbuf), "*|*|%s|%s|%s|%s|%s|*", 890b49634deSclaudio opts & OSPF_OPTION_DC ? "DC" : "-", 891b49634deSclaudio opts & OSPF_OPTION_EA ? "EA" : "-", 892b49634deSclaudio opts & OSPF_OPTION_NP ? "N/P" : "-", 893b49634deSclaudio opts & OSPF_OPTION_MC ? "MC" : "-", 894b49634deSclaudio opts & OSPF_OPTION_E ? "E" : "-"); 895b49634deSclaudio return (optbuf); 896b49634deSclaudio } 897b49634deSclaudio 898b49634deSclaudio int 899b49634deSclaudio show_nbr_detail_msg(struct imsg *imsg) 900b49634deSclaudio { 901b49634deSclaudio struct ctl_nbr *nbr; 902b49634deSclaudio 903b49634deSclaudio switch (imsg->hdr.type) { 904b49634deSclaudio case IMSG_CTL_SHOW_NBR: 905b49634deSclaudio nbr = imsg->data; 906b49634deSclaudio printf("\nNeighbor %s, ", inet_ntoa(nbr->id)); 907b49634deSclaudio printf("interface address %s\n", inet_ntoa(nbr->addr)); 90852580a1cSnorby printf(" Area %s, interface %s\n", inet_ntoa(nbr->area), 90952580a1cSnorby nbr->name); 910b49634deSclaudio printf(" Neighbor priority is %d, " 911b49634deSclaudio "State is %s, %d state changes\n", 9129ac7929fSclaudio nbr->priority, nbr_state_name(nbr->nbr_state), 913b49634deSclaudio nbr->state_chng_cnt); 914b49634deSclaudio printf(" DR is %s, ", inet_ntoa(nbr->dr)); 915b49634deSclaudio printf("BDR is %s\n", inet_ntoa(nbr->bdr)); 91652580a1cSnorby printf(" Options %s\n", print_ospf_options(nbr->options)); 917b49634deSclaudio printf(" Dead timer due in %s\n", 918b49634deSclaudio fmt_timeframe_core(nbr->dead_timer)); 919a9686be3Snorby printf(" Uptime %s\n", fmt_timeframe_core(nbr->uptime)); 920b49634deSclaudio printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt); 921b49634deSclaudio printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt); 922b49634deSclaudio printf(" Link State Retransmission List %d\n", 923b49634deSclaudio nbr->ls_retrans_lst_cnt); 924b49634deSclaudio break; 925b49634deSclaudio case IMSG_CTL_END: 926b49634deSclaudio printf("\n"); 927b49634deSclaudio return (1); 928b49634deSclaudio default: 929b49634deSclaudio break; 930b49634deSclaudio } 931b49634deSclaudio 932b49634deSclaudio return (0); 933b49634deSclaudio } 93437355230Snorby 93537355230Snorby int 93637355230Snorby show_rib_msg(struct imsg *imsg) 93737355230Snorby { 93837355230Snorby struct ctl_rt *rt; 93937355230Snorby char *dstnet; 94037355230Snorby 94137355230Snorby switch (imsg->hdr.type) { 94237355230Snorby case IMSG_CTL_SHOW_RIB: 94337355230Snorby rt = imsg->data; 94437355230Snorby switch (rt->d_type) { 94537355230Snorby case DT_NET: 94637355230Snorby if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), 94737355230Snorby rt->prefixlen) == -1) 94837355230Snorby err(1, NULL); 94937355230Snorby break; 95037355230Snorby case DT_RTR: 95137355230Snorby if (asprintf(&dstnet, "%s", 95237355230Snorby inet_ntoa(rt->prefix)) == -1) 95337355230Snorby err(1, NULL); 95437355230Snorby break; 95537355230Snorby default: 95637355230Snorby errx(1, "Invalid route type"); 95737355230Snorby } 95837355230Snorby 9597aa44f3cSnorby printf("%-20s %-17s %-12s %-9s %-7d %s\n", dstnet, 9609ac7929fSclaudio inet_ntoa(rt->nexthop), path_type_name(rt->p_type), 9619ac7929fSclaudio dst_type_name(rt->d_type), rt->cost, 9627aa44f3cSnorby rt->uptime == 0 ? "-" : fmt_timeframe_core(rt->uptime)); 96337355230Snorby free(dstnet); 96437355230Snorby break; 96537355230Snorby case IMSG_CTL_END: 96637355230Snorby printf("\n"); 96737355230Snorby return (1); 96837355230Snorby default: 96937355230Snorby break; 97037355230Snorby } 97137355230Snorby 97237355230Snorby return (0); 97337355230Snorby } 97437355230Snorby 97537355230Snorby void 97637355230Snorby show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) 97737355230Snorby { 97891e3b0aeSnorby char *header, *format, *format2; 97937355230Snorby 98037355230Snorby switch (p_type) { 98137355230Snorby case PT_INTRA_AREA: 98237355230Snorby case PT_INTER_AREA: 98337355230Snorby switch (d_type) { 98437355230Snorby case DT_NET: 98537355230Snorby format = "Network Routing Table"; 98691e3b0aeSnorby format2 = ""; 98737355230Snorby break; 98837355230Snorby case DT_RTR: 98937355230Snorby format = "Router Routing Table"; 99091e3b0aeSnorby format2 = "Type"; 99137355230Snorby break; 99237355230Snorby default: 99337355230Snorby errx(1, "unknown route type"); 99437355230Snorby } 99537355230Snorby break; 99637355230Snorby case PT_TYPE1_EXT: 99737355230Snorby case PT_TYPE2_EXT: 99837355230Snorby format = NULL; 99991e3b0aeSnorby format2 = "Cost 2"; 100037355230Snorby if ((header = strdup("External Routing Table")) == NULL) 100137355230Snorby err(1, NULL); 100237355230Snorby break; 100337355230Snorby default: 100437355230Snorby errx(1, "unknown route type"); 100537355230Snorby } 100637355230Snorby 100737355230Snorby if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) 100837355230Snorby if (asprintf(&header, "%s (Area %s)", format, 100937355230Snorby inet_ntoa(aid)) == -1) 101037355230Snorby err(1, NULL); 101137355230Snorby 101291e3b0aeSnorby printf("\n%-18s %s\n", "", header); 101337355230Snorby free(header); 101437355230Snorby 101591e3b0aeSnorby printf("\n%-18s %-15s %-15s %-12s %-7s %-7s\n", "Destination", 101691e3b0aeSnorby "Nexthop", "Adv Router", "Path type", "Cost", format2); 101791e3b0aeSnorby } 101837355230Snorby 101991e3b0aeSnorby const char * 102091e3b0aeSnorby print_ospf_rtr_flags(u_int8_t opts) 102191e3b0aeSnorby { 102291e3b0aeSnorby static char optbuf[32]; 102391e3b0aeSnorby 102491e3b0aeSnorby snprintf(optbuf, sizeof(optbuf), "%s%s%s", 102591e3b0aeSnorby opts & OSPF_RTR_E ? "AS" : "", 102691e3b0aeSnorby opts & OSPF_RTR_E && opts & OSPF_RTR_B ? "+" : "", 102791e3b0aeSnorby opts & OSPF_RTR_B ? "ABR" : ""); 102891e3b0aeSnorby return (optbuf); 102937355230Snorby } 103037355230Snorby 103137355230Snorby int 103237355230Snorby show_rib_detail_msg(struct imsg *imsg) 103337355230Snorby { 103437355230Snorby static struct in_addr area_id; 103537355230Snorby struct ctl_rt *rt; 103637355230Snorby struct area *area; 103737355230Snorby char *dstnet; 103837355230Snorby static u_int8_t lasttype; 103937355230Snorby 104037355230Snorby switch (imsg->hdr.type) { 104137355230Snorby case IMSG_CTL_SHOW_RIB: 104237355230Snorby rt = imsg->data; 104337355230Snorby 104437355230Snorby switch (rt->p_type) { 104537355230Snorby case PT_INTRA_AREA: 104637355230Snorby case PT_INTER_AREA: 104737355230Snorby switch (rt->d_type) { 104837355230Snorby case DT_NET: 104937355230Snorby if (lasttype != RIB_NET) 105037355230Snorby show_rib_head(rt->area, rt->d_type, 105137355230Snorby rt->p_type); 105237355230Snorby if (asprintf(&dstnet, "%s/%d", 105337355230Snorby inet_ntoa(rt->prefix), rt->prefixlen) == -1) 105437355230Snorby err(1, NULL); 105537355230Snorby lasttype = RIB_NET; 105637355230Snorby break; 105737355230Snorby case DT_RTR: 105837355230Snorby if (lasttype != RIB_RTR) 105937355230Snorby show_rib_head(rt->area, rt->d_type, 106037355230Snorby rt->p_type); 106137355230Snorby if (asprintf(&dstnet, "%s", 106237355230Snorby inet_ntoa(rt->prefix)) == -1) 106337355230Snorby err(1, NULL); 106437355230Snorby lasttype = RIB_RTR; 106537355230Snorby break; 106637355230Snorby default: 106737355230Snorby errx(1, "unknown route type"); 106837355230Snorby } 106991e3b0aeSnorby printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); 107091e3b0aeSnorby printf("%-15s %-12s %-7d", inet_ntoa(rt->adv_rtr), 10719ac7929fSclaudio path_type_name(rt->p_type), rt->cost); 107237355230Snorby free(dstnet); 107391e3b0aeSnorby 107491e3b0aeSnorby if (rt->d_type == DT_RTR) 107591e3b0aeSnorby printf(" %-7s", 107691e3b0aeSnorby print_ospf_rtr_flags(rt->flags)); 107791e3b0aeSnorby 107891e3b0aeSnorby printf("\n"); 107937355230Snorby break; 108037355230Snorby case PT_TYPE1_EXT: 108137355230Snorby case PT_TYPE2_EXT: 108291e3b0aeSnorby if (lasttype != RIB_EXT) 108391e3b0aeSnorby show_rib_head(rt->area, rt->d_type, rt->p_type); 108491e3b0aeSnorby 108591e3b0aeSnorby if (asprintf(&dstnet, "%s/%d", 108691e3b0aeSnorby inet_ntoa(rt->prefix), rt->prefixlen) == -1) 108791e3b0aeSnorby err(1, NULL); 108891e3b0aeSnorby 108991e3b0aeSnorby printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop)); 109091e3b0aeSnorby printf("%-15s %-12s %-7d %-7d\n", 10919ac7929fSclaudio inet_ntoa(rt->adv_rtr), path_type_name(rt->p_type), 109291e3b0aeSnorby rt->cost, rt->cost2); 10931c1dafb4Snorby free(dstnet); 109491e3b0aeSnorby 109591e3b0aeSnorby lasttype = RIB_EXT; 109637355230Snorby break; 109737355230Snorby default: 109837355230Snorby errx(1, "unknown route type"); 109937355230Snorby } 110037355230Snorby break; 110137355230Snorby case IMSG_CTL_AREA: 110237355230Snorby area = imsg->data; 110337355230Snorby area_id = area->id; 110437355230Snorby break; 110537355230Snorby case IMSG_CTL_END: 110637355230Snorby printf("\n"); 110737355230Snorby return (1); 110837355230Snorby default: 110937355230Snorby break; 111037355230Snorby } 111137355230Snorby 111237355230Snorby return (0); 111337355230Snorby } 1114c47b7f65Sclaudio 1115c47b7f65Sclaudio void 1116c47b7f65Sclaudio show_fib_head(void) 1117c47b7f65Sclaudio { 1118c47b7f65Sclaudio printf("flags: * = valid, O = OSPF, C = Connected, S = Static\n"); 1119253df265Sclaudio printf("%-6s %-4s %-20s %-17s\n", "Flags", "Prio", "Destination", "Nexthop"); 1120c47b7f65Sclaudio } 1121c47b7f65Sclaudio 1122c47b7f65Sclaudio int 1123c47b7f65Sclaudio show_fib_msg(struct imsg *imsg) 1124c47b7f65Sclaudio { 1125c47b7f65Sclaudio struct kroute *k; 1126c47b7f65Sclaudio char *p; 1127c47b7f65Sclaudio 1128c47b7f65Sclaudio switch (imsg->hdr.type) { 1129c47b7f65Sclaudio case IMSG_CTL_KROUTE: 1130c47b7f65Sclaudio if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) 1131c47b7f65Sclaudio errx(1, "wrong imsg len"); 1132c47b7f65Sclaudio k = imsg->data; 1133c47b7f65Sclaudio 1134c47b7f65Sclaudio if (k->flags & F_DOWN) 1135c47b7f65Sclaudio printf(" "); 1136c47b7f65Sclaudio else 1137c47b7f65Sclaudio printf("*"); 1138c47b7f65Sclaudio 1139347b5019Sclaudio if (!(k->flags & F_KERNEL)) 1140c47b7f65Sclaudio printf("O"); 1141c47b7f65Sclaudio else if (k->flags & F_CONNECTED) 1142c47b7f65Sclaudio printf("C"); 1143fc1549e1Sclaudio else if (k->flags & F_STATIC) 1144c47b7f65Sclaudio printf("S"); 1145c47b7f65Sclaudio else 1146c47b7f65Sclaudio printf(" "); 1147c47b7f65Sclaudio 1148c47b7f65Sclaudio printf(" "); 1149253df265Sclaudio printf("%4d ", k->priority); 1150c47b7f65Sclaudio if (asprintf(&p, "%s/%u", inet_ntoa(k->prefix), k->prefixlen) == 1151c47b7f65Sclaudio -1) 1152c47b7f65Sclaudio err(1, NULL); 1153c47b7f65Sclaudio printf("%-20s ", p); 1154c47b7f65Sclaudio free(p); 1155c47b7f65Sclaudio 1156c47b7f65Sclaudio if (k->nexthop.s_addr) 1157c47b7f65Sclaudio printf("%s", inet_ntoa(k->nexthop)); 1158c47b7f65Sclaudio else if (k->flags & F_CONNECTED) 1159c47b7f65Sclaudio printf("link#%u", k->ifindex); 1160c47b7f65Sclaudio printf("\n"); 1161c47b7f65Sclaudio 1162c47b7f65Sclaudio break; 1163c47b7f65Sclaudio case IMSG_CTL_END: 1164c47b7f65Sclaudio printf("\n"); 1165c47b7f65Sclaudio return (1); 1166c47b7f65Sclaudio default: 1167c47b7f65Sclaudio break; 1168c47b7f65Sclaudio } 1169c47b7f65Sclaudio 1170c47b7f65Sclaudio return (0); 1171c47b7f65Sclaudio } 1172c47b7f65Sclaudio 1173c47b7f65Sclaudio void 1174c47b7f65Sclaudio show_interface_head(void) 1175c47b7f65Sclaudio { 11764c561fb6Sclaudio printf("%-15s%-15s%s\n", "Interface", "Flags", 1177c47b7f65Sclaudio "Link state"); 1178c47b7f65Sclaudio } 1179c47b7f65Sclaudio 1180c47b7f65Sclaudio const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST; 1181c47b7f65Sclaudio const struct ifmedia_status_description 1182c47b7f65Sclaudio ifm_status_descriptions[] = IFM_STATUS_DESCRIPTIONS; 1183c47b7f65Sclaudio const struct ifmedia_description 1184c47b7f65Sclaudio ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; 1185c47b7f65Sclaudio 1186c47b7f65Sclaudio const char * 1187c47b7f65Sclaudio get_media_descr(int media_type) 1188c47b7f65Sclaudio { 1189c47b7f65Sclaudio const struct ifmedia_description *p; 1190c47b7f65Sclaudio 1191c47b7f65Sclaudio for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) 1192c47b7f65Sclaudio if (media_type == p->ifmt_word) 1193c47b7f65Sclaudio return (p->ifmt_string); 1194c47b7f65Sclaudio 1195a5bcf77aSclaudio return ("unknown"); 1196c47b7f65Sclaudio } 1197c47b7f65Sclaudio 1198c47b7f65Sclaudio const char * 1199c47b7f65Sclaudio get_linkstate(int media_type, int link_state) 1200c47b7f65Sclaudio { 1201c47b7f65Sclaudio const struct ifmedia_status_description *p; 1202c47b7f65Sclaudio int i; 1203c47b7f65Sclaudio 1204c47b7f65Sclaudio if (link_state == LINK_STATE_UNKNOWN) 1205c47b7f65Sclaudio return ("unknown"); 1206c47b7f65Sclaudio 1207c47b7f65Sclaudio for (i = 0; ifm_status_valid_list[i] != 0; i++) 1208c47b7f65Sclaudio for (p = ifm_status_descriptions; p->ifms_valid != 0; p++) { 1209c47b7f65Sclaudio if (p->ifms_type != media_type || 1210c47b7f65Sclaudio p->ifms_valid != ifm_status_valid_list[i]) 1211c47b7f65Sclaudio continue; 121230762738Sreyk if (LINK_STATE_IS_UP(link_state)) 121330762738Sreyk return (p->ifms_string[1]); 121430762738Sreyk return (p->ifms_string[0]); 1215c47b7f65Sclaudio } 1216c47b7f65Sclaudio 1217a5bcf77aSclaudio return ("unknown"); 1218c47b7f65Sclaudio } 1219c47b7f65Sclaudio 1220c47b7f65Sclaudio void 122156babc06Sclaudio print_baudrate(u_int64_t baudrate) 1222c47b7f65Sclaudio { 1223c47b7f65Sclaudio if (baudrate > IF_Gbps(1)) 122456babc06Sclaudio printf("%llu GBit/s", baudrate / IF_Gbps(1)); 1225c47b7f65Sclaudio else if (baudrate > IF_Mbps(1)) 122656babc06Sclaudio printf("%llu MBit/s", baudrate / IF_Mbps(1)); 1227c47b7f65Sclaudio else if (baudrate > IF_Kbps(1)) 122856babc06Sclaudio printf("%llu KBit/s", baudrate / IF_Kbps(1)); 1229c47b7f65Sclaudio else 123056babc06Sclaudio printf("%llu Bit/s", baudrate); 1231c47b7f65Sclaudio } 1232c47b7f65Sclaudio 1233c47b7f65Sclaudio int 1234c47b7f65Sclaudio show_fib_interface_msg(struct imsg *imsg) 1235c47b7f65Sclaudio { 1236c47b7f65Sclaudio struct kif *k; 1237c47b7f65Sclaudio int ifms_type; 1238c47b7f65Sclaudio 1239c47b7f65Sclaudio switch (imsg->hdr.type) { 12404c561fb6Sclaudio case IMSG_CTL_IFINFO: 1241c47b7f65Sclaudio k = imsg->data; 1242c47b7f65Sclaudio printf("%-15s", k->ifname); 1243c47b7f65Sclaudio printf("%-15s", k->flags & IFF_UP ? "UP" : ""); 1244c47b7f65Sclaudio switch (k->media_type) { 1245c47b7f65Sclaudio case IFT_ETHER: 1246c47b7f65Sclaudio ifms_type = IFM_ETHER; 1247c47b7f65Sclaudio break; 1248c47b7f65Sclaudio case IFT_FDDI: 1249c47b7f65Sclaudio ifms_type = IFM_FDDI; 1250c47b7f65Sclaudio break; 1251c47b7f65Sclaudio case IFT_CARP: 1252c47b7f65Sclaudio ifms_type = IFM_CARP; 1253c47b7f65Sclaudio break; 1254c47b7f65Sclaudio default: 1255c47b7f65Sclaudio ifms_type = 0; 1256c47b7f65Sclaudio break; 1257c47b7f65Sclaudio } 1258c47b7f65Sclaudio 1259c47b7f65Sclaudio if (ifms_type) 1260c47b7f65Sclaudio printf("%s, %s", get_media_descr(ifms_type), 1261c47b7f65Sclaudio get_linkstate(ifms_type, k->link_state)); 1262c47b7f65Sclaudio else if (k->link_state == LINK_STATE_UNKNOWN) 1263c47b7f65Sclaudio printf("unknown"); 1264c47b7f65Sclaudio else 1265c47b7f65Sclaudio printf("link state %u", k->link_state); 1266c47b7f65Sclaudio 1267c47b7f65Sclaudio if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { 1268c47b7f65Sclaudio printf(", "); 1269c47b7f65Sclaudio print_baudrate(k->baudrate); 1270c47b7f65Sclaudio } 1271c47b7f65Sclaudio printf("\n"); 1272c47b7f65Sclaudio break; 1273c47b7f65Sclaudio case IMSG_CTL_END: 1274c47b7f65Sclaudio printf("\n"); 1275c47b7f65Sclaudio return (1); 1276c47b7f65Sclaudio default: 1277c47b7f65Sclaudio break; 1278c47b7f65Sclaudio } 1279c47b7f65Sclaudio 1280c47b7f65Sclaudio return (0); 1281c47b7f65Sclaudio } 1282