1*f1b790a5Sclaudio /* $OpenBSD: ospf6ctl.c,v 1.59 2024/11/21 13:38:14 claudio Exp $ */ 28e709cbdSnorby 38e709cbdSnorby /* 48e709cbdSnorby * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 58e709cbdSnorby * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> 68e709cbdSnorby * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> 78e709cbdSnorby * 88e709cbdSnorby * Permission to use, copy, modify, and distribute this software for any 98e709cbdSnorby * purpose with or without fee is hereby granted, provided that the above 108e709cbdSnorby * copyright notice and this permission notice appear in all copies. 118e709cbdSnorby * 128e709cbdSnorby * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 138e709cbdSnorby * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 148e709cbdSnorby * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 158e709cbdSnorby * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 168e709cbdSnorby * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 178e709cbdSnorby * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 188e709cbdSnorby * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 198e709cbdSnorby */ 208e709cbdSnorby 218e709cbdSnorby #include <sys/types.h> 228e709cbdSnorby #include <sys/socket.h> 238e709cbdSnorby #include <sys/un.h> 248e709cbdSnorby #include <netinet/in.h> 258e709cbdSnorby #include <arpa/inet.h> 268e709cbdSnorby #include <net/if_media.h> 278e709cbdSnorby #include <net/if_types.h> 288e709cbdSnorby 298e709cbdSnorby #include <err.h> 30c0dbf5cfSsthen #include <errno.h> 318e709cbdSnorby #include <stdio.h> 328e709cbdSnorby #include <stdlib.h> 338e709cbdSnorby #include <string.h> 348e709cbdSnorby #include <unistd.h> 358e709cbdSnorby 368e709cbdSnorby #include "ospf6.h" 378e709cbdSnorby #include "ospf6d.h" 388e709cbdSnorby #include "ospfe.h" 398e709cbdSnorby #include "parser.h" 408e709cbdSnorby #include "log.h" 418e709cbdSnorby 428e709cbdSnorby __dead void usage(void); 438e709cbdSnorby int show_summary_msg(struct imsg *); 4418ffdd94Sstsp uint64_t get_ifms_type(uint8_t); 458e709cbdSnorby int show_interface_msg(struct imsg *); 468e709cbdSnorby int show_interface_detail_msg(struct imsg *); 478e709cbdSnorby const char *print_link(int); 488e709cbdSnorby const char *fmt_timeframe(time_t t); 498e709cbdSnorby const char *fmt_timeframe_core(time_t t); 508e709cbdSnorby const char *log_id(u_int32_t ); 518e709cbdSnorby const char *log_adv_rtr(u_int32_t); 52cb01fa27Sclaudio void show_database_head(struct in_addr, char *, u_int16_t); 538e709cbdSnorby int show_database_msg(struct imsg *); 544fabe8f9Snorby char *print_ls_type(u_int16_t); 558e709cbdSnorby void show_db_hdr_msg_detail(struct lsa_hdr *); 568e709cbdSnorby char *print_rtr_link_type(u_int8_t); 578e709cbdSnorby const char *print_ospf_flags(u_int8_t); 581aff836dSclaudio const char *print_asext_flags(u_int32_t); 591aff836dSclaudio const char *print_prefix_opt(u_int8_t); 608e709cbdSnorby int show_db_msg_detail(struct imsg *imsg); 618e709cbdSnorby int show_nbr_msg(struct imsg *); 62aff6ccb8Sclaudio const char *print_ospf_options(u_int32_t); 638e709cbdSnorby int show_nbr_detail_msg(struct imsg *); 648e709cbdSnorby int show_rib_msg(struct imsg *); 658e709cbdSnorby void show_rib_head(struct in_addr, u_int8_t, u_int8_t); 668e709cbdSnorby const char *print_ospf_rtr_flags(u_int8_t); 678e709cbdSnorby int show_rib_detail_msg(struct imsg *); 688e709cbdSnorby void show_fib_head(void); 698e709cbdSnorby int show_fib_msg(struct imsg *); 70e5605ae3Sderaadt const char * get_media_descr(uint64_t); 7118ffdd94Sstsp const char * get_linkstate(uint8_t, int); 728e709cbdSnorby void print_baudrate(u_int64_t); 738e709cbdSnorby 748e709cbdSnorby struct imsgbuf *ibuf; 758e709cbdSnorby 768e709cbdSnorby __dead void 778e709cbdSnorby usage(void) 788e709cbdSnorby { 798e709cbdSnorby extern char *__progname; 808e709cbdSnorby 81c2ca8945Ssthen fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n", 82c2ca8945Ssthen __progname); 838e709cbdSnorby exit(1); 848e709cbdSnorby } 858e709cbdSnorby 868e709cbdSnorby int 878e709cbdSnorby main(int argc, char *argv[]) 888e709cbdSnorby { 898e709cbdSnorby struct sockaddr_un sun; 908e709cbdSnorby struct parse_result *res; 918e709cbdSnorby struct imsg imsg; 928e709cbdSnorby unsigned int ifidx = 0; 935d393f89Sremi int ctl_sock, r; 94c3319070Sclaudio int done = 0, verbose = 0; 958e709cbdSnorby int n; 96c2ca8945Ssthen int ch; 97c2ca8945Ssthen char *sockname; 98c2ca8945Ssthen 995d393f89Sremi r = getrtable(); 1005d393f89Sremi if (asprintf(&sockname, "%s.%d", OSPF6D_SOCKET, r) == -1) 1015d393f89Sremi err(1, "asprintf"); 1025d393f89Sremi 103c2ca8945Ssthen while ((ch = getopt(argc, argv, "s:")) != -1) { 104c2ca8945Ssthen switch (ch) { 105c2ca8945Ssthen case 's': 106c2ca8945Ssthen sockname = optarg; 107c2ca8945Ssthen break; 108c2ca8945Ssthen default: 109c2ca8945Ssthen usage(); 110c2ca8945Ssthen /* NOTREACHED */ 111c2ca8945Ssthen } 112c2ca8945Ssthen } 113c2ca8945Ssthen argc -= optind; 114c2ca8945Ssthen argv += optind; 1158e709cbdSnorby 1168e709cbdSnorby /* parse options */ 117c2ca8945Ssthen if ((res = parse(argc, argv)) == NULL) 1188e709cbdSnorby exit(1); 1198e709cbdSnorby 1208e709cbdSnorby /* connect to ospf6d control socket */ 1218e709cbdSnorby if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 1228e709cbdSnorby err(1, "socket"); 1238e709cbdSnorby 1248e709cbdSnorby bzero(&sun, sizeof(sun)); 1258e709cbdSnorby sun.sun_family = AF_UNIX; 126c2ca8945Ssthen strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path)); 1278e709cbdSnorby if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 128c2ca8945Ssthen err(1, "connect: %s", sockname); 1298e709cbdSnorby 130a18c3fe3Sderaadt if (pledge("stdio", NULL) == -1) 131becb4c8cSbenno err(1, "pledge"); 132becb4c8cSbenno 1338e709cbdSnorby if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 1348e709cbdSnorby err(1, NULL); 135*f1b790a5Sclaudio if (imsgbuf_init(ibuf, ctl_sock) == -1) 136*f1b790a5Sclaudio err(1, NULL); 1378e709cbdSnorby done = 0; 1388e709cbdSnorby 1398e709cbdSnorby /* process user request */ 1408e709cbdSnorby switch (res->action) { 1418e709cbdSnorby case NONE: 1428e709cbdSnorby usage(); 1438e709cbdSnorby /* not reached */ 1448e709cbdSnorby case SHOW: 1458e709cbdSnorby case SHOW_SUM: 146f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); 1478e709cbdSnorby break; 1488e709cbdSnorby case SHOW_IFACE: 1491fed8bffSnorby printf("%-11s %-29s %-6s %-10s %-10s %-8s\n", 1508e709cbdSnorby "Interface", "Address", "State", "HelloTimer", "Linkstate", 1511fed8bffSnorby "Uptime"); 152c5ba8b41Sderaadt /*FALLTHROUGH*/ 1538e709cbdSnorby case SHOW_IFACE_DTAIL: 1548e709cbdSnorby if (*res->ifname) { 1558e709cbdSnorby ifidx = if_nametoindex(res->ifname); 1568e709cbdSnorby if (ifidx == 0) 1578e709cbdSnorby errx(1, "no such interface %s", res->ifname); 1588e709cbdSnorby } 159f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 1608e709cbdSnorby &ifidx, sizeof(ifidx)); 1618e709cbdSnorby break; 1628e709cbdSnorby case SHOW_NBR: 163558ada41Snorby printf("%-15s %-3s %-12s %-9s %-11s %s\n", "ID", "Pri", 164558ada41Snorby "State", "DeadTime", "Iface","Uptime"); 165c5ba8b41Sderaadt /*FALLTHROUGH*/ 1668e709cbdSnorby case SHOW_NBR_DTAIL: 167f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 1688e709cbdSnorby break; 1698e709cbdSnorby case SHOW_DB: 170f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0); 1718e709cbdSnorby break; 1728e709cbdSnorby case SHOW_DBBYAREA: 173f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, 17496950f83Sremi &res->area, sizeof(res->area)); 1758e709cbdSnorby break; 1768e709cbdSnorby case SHOW_DBEXT: 177f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0); 1788e709cbdSnorby break; 179aeb06b08Sclaudio case SHOW_DBLINK: 180f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DB_LINK, 0, 0, -1, NULL, 0); 181aeb06b08Sclaudio break; 1828e709cbdSnorby case SHOW_DBNET: 183f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0); 1848e709cbdSnorby break; 1858e709cbdSnorby case SHOW_DBRTR: 186f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0); 1878e709cbdSnorby break; 18841bcac6bSstsp case SHOW_DBINTRA: 189f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DB_INTRA, 0, 0, -1, NULL, 0); 19041bcac6bSstsp break; 1918e709cbdSnorby case SHOW_DBSELF: 192f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0); 1938e709cbdSnorby break; 1948e709cbdSnorby case SHOW_DBSUM: 195f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0); 1968e709cbdSnorby break; 1978e709cbdSnorby case SHOW_DBASBR: 198f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0); 1998e709cbdSnorby break; 2008e709cbdSnorby case SHOW_RIB: 2018e709cbdSnorby printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", 2028e709cbdSnorby "Nexthop", "Path Type", "Type", "Cost", "Uptime"); 203c5ba8b41Sderaadt /*FALLTHROUGH*/ 2048e709cbdSnorby case SHOW_RIB_DTAIL: 205f78850efSeric imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); 2068e709cbdSnorby break; 2078e709cbdSnorby case SHOW_FIB: 2080104e403Sclaudio if (IN6_IS_ADDR_UNSPECIFIED(&res->addr)) 209f78850efSeric imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, 2108e709cbdSnorby &res->flags, sizeof(res->flags)); 2118e709cbdSnorby else 212f78850efSeric imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, 2138e709cbdSnorby &res->addr, sizeof(res->addr)); 2148e709cbdSnorby show_fib_head(); 2158e709cbdSnorby break; 2168e709cbdSnorby case FIB: 2178e709cbdSnorby errx(1, "fib couple|decouple"); 2188e709cbdSnorby break; 2198e709cbdSnorby case FIB_COUPLE: 220f78850efSeric imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0); 2218e709cbdSnorby printf("couple request sent.\n"); 2228e709cbdSnorby done = 1; 2238e709cbdSnorby break; 2248e709cbdSnorby case FIB_DECOUPLE: 225f78850efSeric imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0); 2268e709cbdSnorby printf("decouple request sent.\n"); 2278e709cbdSnorby done = 1; 2288e709cbdSnorby break; 229dd3b9a80Ssthen case FIB_RELOAD: 230dd3b9a80Ssthen imsg_compose(ibuf, IMSG_CTL_FIB_RELOAD, 0, 0, -1, NULL, 0); 231dd3b9a80Ssthen printf("reload request sent.\n"); 232dd3b9a80Ssthen done = 1; 233dd3b9a80Ssthen break; 234c3319070Sclaudio case LOG_VERBOSE: 235c3319070Sclaudio verbose = 1; 236c3319070Sclaudio /* FALLTHROUGH */ 237c3319070Sclaudio case LOG_BRIEF: 238c3319070Sclaudio imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, 239c3319070Sclaudio &verbose, sizeof(verbose)); 240c3319070Sclaudio printf("logging request sent.\n"); 241c3319070Sclaudio done = 1; 242c3319070Sclaudio break; 2438e709cbdSnorby case RELOAD: 2448bf9509aSjca #ifdef notyet 245f78850efSeric imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 2468e709cbdSnorby printf("reload request sent.\n"); 2478e709cbdSnorby done = 1; 2488e709cbdSnorby break; 2498bf9509aSjca #else 2508bf9509aSjca errx(1, "reload not supported"); 2518bf9509aSjca #endif 2528e709cbdSnorby } 2538e709cbdSnorby 254dd7efffeSclaudio if (imsgbuf_flush(ibuf) == -1) 2558e709cbdSnorby err(1, "write error"); 2568e709cbdSnorby 2578e709cbdSnorby while (!done) { 258668e5ba9Sclaudio if ((n = imsgbuf_read(ibuf)) == -1) 259ef2e27a1Sclaudio err(1, "read error"); 2608e709cbdSnorby if (n == 0) 2618e709cbdSnorby errx(1, "pipe closed"); 2628e709cbdSnorby 2638e709cbdSnorby while (!done) { 2648e709cbdSnorby if ((n = imsg_get(ibuf, &imsg)) == -1) 2658e709cbdSnorby errx(1, "imsg_get error"); 2668e709cbdSnorby if (n == 0) 2678e709cbdSnorby break; 2688e709cbdSnorby switch (res->action) { 2698e709cbdSnorby case SHOW: 2708e709cbdSnorby case SHOW_SUM: 2718e709cbdSnorby done = show_summary_msg(&imsg); 2728e709cbdSnorby break; 2738e709cbdSnorby case SHOW_IFACE: 2748e709cbdSnorby done = show_interface_msg(&imsg); 2758e709cbdSnorby break; 2768e709cbdSnorby case SHOW_IFACE_DTAIL: 2778e709cbdSnorby done = show_interface_detail_msg(&imsg); 2788e709cbdSnorby break; 2798e709cbdSnorby case SHOW_NBR: 2808e709cbdSnorby done = show_nbr_msg(&imsg); 2818e709cbdSnorby break; 2828e709cbdSnorby case SHOW_NBR_DTAIL: 2838e709cbdSnorby done = show_nbr_detail_msg(&imsg); 2848e709cbdSnorby break; 2858e709cbdSnorby case SHOW_DB: 2868e709cbdSnorby case SHOW_DBBYAREA: 2878e709cbdSnorby case SHOW_DBSELF: 2888e709cbdSnorby done = show_database_msg(&imsg); 2898e709cbdSnorby break; 2908e709cbdSnorby case SHOW_DBEXT: 291aeb06b08Sclaudio case SHOW_DBLINK: 2928e709cbdSnorby case SHOW_DBNET: 2938e709cbdSnorby case SHOW_DBRTR: 29441bcac6bSstsp case SHOW_DBINTRA: 2958e709cbdSnorby case SHOW_DBSUM: 2968e709cbdSnorby case SHOW_DBASBR: 2978e709cbdSnorby done = show_db_msg_detail(&imsg); 2988e709cbdSnorby break; 2998e709cbdSnorby case SHOW_RIB: 3008e709cbdSnorby done = show_rib_msg(&imsg); 3018e709cbdSnorby break; 3028e709cbdSnorby case SHOW_RIB_DTAIL: 3038e709cbdSnorby done = show_rib_detail_msg(&imsg); 3048e709cbdSnorby break; 3058e709cbdSnorby case SHOW_FIB: 3068e709cbdSnorby done = show_fib_msg(&imsg); 3078e709cbdSnorby break; 3088e709cbdSnorby case NONE: 3098e709cbdSnorby case FIB: 3108e709cbdSnorby case FIB_COUPLE: 3118e709cbdSnorby case FIB_DECOUPLE: 312dd3b9a80Ssthen case FIB_RELOAD: 313c3319070Sclaudio case LOG_VERBOSE: 314c3319070Sclaudio case LOG_BRIEF: 3158e709cbdSnorby case RELOAD: 3168e709cbdSnorby break; 3178e709cbdSnorby } 3188e709cbdSnorby imsg_free(&imsg); 3198e709cbdSnorby } 3208e709cbdSnorby } 3218e709cbdSnorby close(ctl_sock); 3228e709cbdSnorby free(ibuf); 3238e709cbdSnorby 3248e709cbdSnorby return (0); 3258e709cbdSnorby } 3268e709cbdSnorby 3278e709cbdSnorby int 3288e709cbdSnorby show_summary_msg(struct imsg *imsg) 3298e709cbdSnorby { 3308e709cbdSnorby struct ctl_sum *sum; 3318e709cbdSnorby struct ctl_sum_area *sumarea; 3328e709cbdSnorby 3338e709cbdSnorby switch (imsg->hdr.type) { 3348e709cbdSnorby case IMSG_CTL_SHOW_SUM: 3358e709cbdSnorby sum = imsg->data; 3368e709cbdSnorby printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); 3378e709cbdSnorby printf("Uptime: %s\n", fmt_timeframe_core(sum->uptime)); 3388e709cbdSnorby 3398e709cbdSnorby printf("SPF delay is %d sec(s), hold time between two SPFs " 3408e709cbdSnorby "is %d sec(s)\n", sum->spf_delay, sum->spf_hold_time); 3418e709cbdSnorby printf("Number of external LSA(s) %d\n", sum->num_ext_lsa); 3428e709cbdSnorby printf("Number of areas attached to this router: %d\n", 3438e709cbdSnorby sum->num_area); 3448e709cbdSnorby break; 3458e709cbdSnorby case IMSG_CTL_SHOW_SUM_AREA: 3468e709cbdSnorby sumarea = imsg->data; 3478e709cbdSnorby printf("\nArea ID: %s\n", inet_ntoa(sumarea->area)); 3488e709cbdSnorby printf(" Number of interfaces in this area: %d\n", 3498e709cbdSnorby sumarea->num_iface); 3508e709cbdSnorby printf(" Number of fully adjacent neighbors in this " 3518e709cbdSnorby "area: %d\n", sumarea->num_adj_nbr); 3528e709cbdSnorby printf(" SPF algorithm executed %d time(s)\n", 3538e709cbdSnorby sumarea->num_spf_calc); 3548e709cbdSnorby printf(" Number LSA(s) %d\n", sumarea->num_lsa); 3558e709cbdSnorby break; 3568e709cbdSnorby case IMSG_CTL_END: 3578e709cbdSnorby printf("\n"); 3588e709cbdSnorby return (1); 3598e709cbdSnorby default: 3608e709cbdSnorby break; 3618e709cbdSnorby } 3628e709cbdSnorby 3638e709cbdSnorby return (0); 3648e709cbdSnorby } 3658e709cbdSnorby 36618ffdd94Sstsp uint64_t 36718ffdd94Sstsp get_ifms_type(uint8_t if_type) 3688e709cbdSnorby { 36918ffdd94Sstsp switch (if_type) { 3708e709cbdSnorby case IFT_ETHER: 3718e709cbdSnorby return (IFM_ETHER); 3728e709cbdSnorby case IFT_FDDI: 3738e709cbdSnorby return (IFM_FDDI); 3748e709cbdSnorby case IFT_CARP: 3758e709cbdSnorby return (IFM_CARP); 3768e709cbdSnorby case IFT_PPP: 3778e709cbdSnorby return (IFM_TDM); 3788e709cbdSnorby default: 3798e709cbdSnorby return (0); 3808e709cbdSnorby } 3818e709cbdSnorby } 3828e709cbdSnorby 3838e709cbdSnorby int 3848e709cbdSnorby show_interface_msg(struct imsg *imsg) 3858e709cbdSnorby { 3868e709cbdSnorby struct ctl_iface *iface; 3878e709cbdSnorby char *netid; 3888e709cbdSnorby 3898e709cbdSnorby switch (imsg->hdr.type) { 3908e709cbdSnorby case IMSG_CTL_SHOW_INTERFACE: 3918e709cbdSnorby iface = imsg->data; 3928e709cbdSnorby 3938e709cbdSnorby if (asprintf(&netid, "%s", log_in6addr(&iface->addr)) == -1) 3948e709cbdSnorby err(1, NULL); 3951fed8bffSnorby printf("%-11s %-29s %-6s %-10s %-10s %s\n", 3968e709cbdSnorby iface->name, netid, if_state_name(iface->state), 3971dfb70a2Sclaudio iface->hello_timer < 0 ? "-" : 3988e709cbdSnorby fmt_timeframe_core(iface->hello_timer), 39918ffdd94Sstsp get_linkstate(iface->if_type, iface->linkstate), 4000f617141Sclaudio fmt_timeframe_core(iface->uptime)); 4018e709cbdSnorby free(netid); 4028e709cbdSnorby break; 4038e709cbdSnorby case IMSG_CTL_END: 4048e709cbdSnorby printf("\n"); 4058e709cbdSnorby return (1); 4068e709cbdSnorby default: 4078e709cbdSnorby break; 4088e709cbdSnorby } 4098e709cbdSnorby 4108e709cbdSnorby return (0); 4118e709cbdSnorby } 4128e709cbdSnorby 4138e709cbdSnorby int 4148e709cbdSnorby show_interface_detail_msg(struct imsg *imsg) 4158e709cbdSnorby { 4168e709cbdSnorby struct ctl_iface *iface; 4178e709cbdSnorby 4188e709cbdSnorby switch (imsg->hdr.type) { 4198e709cbdSnorby case IMSG_CTL_SHOW_INTERFACE: 4208e709cbdSnorby iface = imsg->data; 4218e709cbdSnorby printf("\n"); 4228e709cbdSnorby printf("Interface %s, line protocol is %s\n", 4238e709cbdSnorby iface->name, print_link(iface->flags)); 424ab5e4d03Sclaudio printf(" Internet address %s Area %s\n", 425ab5e4d03Sclaudio log_in6addr(&iface->addr), inet_ntoa(iface->area)); 42637f8d125Sjca printf(" Link type %s, state %s, mtu %d", 42718ffdd94Sstsp get_media_descr(get_ifms_type(iface->if_type)), 42837f8d125Sjca get_linkstate(iface->if_type, iface->linkstate), 42937f8d125Sjca iface->mtu); 430ab5e4d03Sclaudio if (iface->linkstate != LINK_STATE_DOWN && 431ab5e4d03Sclaudio iface->baudrate > 0) { 432ab5e4d03Sclaudio printf(", "); 433ab5e4d03Sclaudio print_baudrate(iface->baudrate); 434ab5e4d03Sclaudio } 435ab5e4d03Sclaudio printf("\n"); 4368e709cbdSnorby printf(" Router ID %s, network type %s, cost: %d\n", 4378e709cbdSnorby inet_ntoa(iface->rtr_id), 4388e709cbdSnorby if_type_name(iface->type), iface->metric); 4398e709cbdSnorby printf(" Transmit delay is %d sec(s), state %s, priority %d\n", 4408e709cbdSnorby iface->transmit_delay, if_state_name(iface->state), 4418e709cbdSnorby iface->priority); 4427aab4200Snorby printf(" Designated Router (ID) %s\n", 4438e709cbdSnorby inet_ntoa(iface->dr_id)); 4447aab4200Snorby printf(" Interface address %s\n", 4457aab4200Snorby log_in6addr(&iface->dr_addr)); 4467aab4200Snorby printf(" Backup Designated Router (ID) %s\n", 4478e709cbdSnorby inet_ntoa(iface->bdr_id)); 4487aab4200Snorby printf(" Interface address %s\n", 4497aab4200Snorby log_in6addr(&iface->bdr_addr)); 4508e709cbdSnorby printf(" Timer intervals configured, " 4518e709cbdSnorby "hello %d, dead %d, wait %d, retransmit %d\n", 4528e709cbdSnorby iface->hello_interval, iface->dead_interval, 4538e709cbdSnorby iface->dead_interval, iface->rxmt_interval); 4548e709cbdSnorby if (iface->passive) 4558e709cbdSnorby printf(" Passive interface (No Hellos)\n"); 4568e709cbdSnorby else if (iface->hello_timer < 0) 4578e709cbdSnorby printf(" Hello timer not running\n"); 4588e709cbdSnorby else 4598e709cbdSnorby printf(" Hello timer due in %s\n", 4608e709cbdSnorby fmt_timeframe_core(iface->hello_timer)); 4618e709cbdSnorby printf(" Uptime %s\n", fmt_timeframe_core(iface->uptime)); 4628e709cbdSnorby printf(" Neighbor count is %d, adjacent neighbor count is " 4638e709cbdSnorby "%d\n", iface->nbr_cnt, iface->adj_cnt); 4648e709cbdSnorby break; 4658e709cbdSnorby case IMSG_CTL_END: 4668e709cbdSnorby printf("\n"); 4678e709cbdSnorby return (1); 4688e709cbdSnorby default: 4698e709cbdSnorby break; 4708e709cbdSnorby } 4718e709cbdSnorby 4728e709cbdSnorby return (0); 4738e709cbdSnorby } 4748e709cbdSnorby 4758e709cbdSnorby const char * 4768e709cbdSnorby print_link(int state) 4778e709cbdSnorby { 4788e709cbdSnorby if (state & IFF_UP) 4798e709cbdSnorby return ("UP"); 4808e709cbdSnorby else 4818e709cbdSnorby return ("DOWN"); 4828e709cbdSnorby } 4838e709cbdSnorby 4848e709cbdSnorby #define TF_BUFS 8 4858e709cbdSnorby #define TF_LEN 9 4868e709cbdSnorby 4878e709cbdSnorby const char * 4888e709cbdSnorby fmt_timeframe(time_t t) 4898e709cbdSnorby { 4908e709cbdSnorby if (t == 0) 4918e709cbdSnorby return ("Never"); 4928e709cbdSnorby else 4938e709cbdSnorby return (fmt_timeframe_core(time(NULL) - t)); 4948e709cbdSnorby } 4958e709cbdSnorby 4968e709cbdSnorby const char * 4978e709cbdSnorby fmt_timeframe_core(time_t t) 4988e709cbdSnorby { 4998e709cbdSnorby char *buf; 5008e709cbdSnorby static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 5018e709cbdSnorby static int idx = 0; 502db93f2f1Sderaadt unsigned int sec, min, hrs, day, week; 5038e709cbdSnorby 5048e709cbdSnorby if (t == 0) 5058e709cbdSnorby return ("00:00:00"); 5068e709cbdSnorby 5078e709cbdSnorby buf = tfbuf[idx++]; 5088e709cbdSnorby if (idx == TF_BUFS) 5098e709cbdSnorby idx = 0; 5108e709cbdSnorby 5118e709cbdSnorby week = t; 5128e709cbdSnorby 5138e709cbdSnorby sec = week % 60; 5148e709cbdSnorby week /= 60; 5158e709cbdSnorby min = week % 60; 5168e709cbdSnorby week /= 60; 5178e709cbdSnorby hrs = week % 24; 5188e709cbdSnorby week /= 24; 5198e709cbdSnorby day = week % 7; 5208e709cbdSnorby week /= 7; 5218e709cbdSnorby 5228e709cbdSnorby if (week > 0) 5238e709cbdSnorby snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs); 5248e709cbdSnorby else if (day > 0) 5258e709cbdSnorby snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 5268e709cbdSnorby else 5278e709cbdSnorby snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 5288e709cbdSnorby 5298e709cbdSnorby return (buf); 5308e709cbdSnorby } 5318e709cbdSnorby 5328e709cbdSnorby const char * 5338e709cbdSnorby log_id(u_int32_t id) 5348e709cbdSnorby { 5358e709cbdSnorby static char buf[48]; 5368e709cbdSnorby struct in_addr addr; 5378e709cbdSnorby 5388e709cbdSnorby addr.s_addr = id; 5398e709cbdSnorby 5408e709cbdSnorby if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 5418e709cbdSnorby return ("?"); 5428e709cbdSnorby else 5438e709cbdSnorby return (buf); 5448e709cbdSnorby } 5458e709cbdSnorby 5468e709cbdSnorby const char * 5478e709cbdSnorby log_adv_rtr(u_int32_t adv_rtr) 5488e709cbdSnorby { 5498e709cbdSnorby static char buf[48]; 5508e709cbdSnorby struct in_addr addr; 5518e709cbdSnorby 5528e709cbdSnorby addr.s_addr = adv_rtr; 5538e709cbdSnorby 5548e709cbdSnorby if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 5558e709cbdSnorby return ("?"); 5568e709cbdSnorby else 5578e709cbdSnorby return (buf); 5588e709cbdSnorby } 5598e709cbdSnorby 5608e709cbdSnorby void 561cb01fa27Sclaudio show_database_head(struct in_addr aid, char *ifname, u_int16_t type) 5628e709cbdSnorby { 5638e709cbdSnorby char *header, *format; 564cb01fa27Sclaudio int cleanup = 0; 5658e709cbdSnorby 566005d568eSclaudio switch (ntohs(type)) { 5674fabe8f9Snorby case LSA_TYPE_LINK: 5688ea4c735Sclaudio format = "Link (Type-8) Link States"; 5694fabe8f9Snorby break; 5708e709cbdSnorby case LSA_TYPE_ROUTER: 5718e709cbdSnorby format = "Router Link States"; 5728e709cbdSnorby break; 5738e709cbdSnorby case LSA_TYPE_NETWORK: 5748e709cbdSnorby format = "Net Link States"; 5758e709cbdSnorby break; 5764fabe8f9Snorby case LSA_TYPE_INTER_A_PREFIX: 5774fabe8f9Snorby format = "Inter Area Prefix Link States"; 5788e709cbdSnorby break; 5794fabe8f9Snorby case LSA_TYPE_INTER_A_ROUTER: 5804fabe8f9Snorby format = "Inter Area Router Link States"; 5814fabe8f9Snorby break; 5824fabe8f9Snorby case LSA_TYPE_INTRA_A_PREFIX: 5838ec36425Sstsp format = "Intra Area Prefix Link States"; 5848e709cbdSnorby break; 5858e709cbdSnorby case LSA_TYPE_EXTERNAL: 586cb01fa27Sclaudio printf("\n%-15s %s\n\n", "", "Type-5 AS External Link States"); 587cb01fa27Sclaudio return; 5888e709cbdSnorby default: 589cb01fa27Sclaudio if (asprintf(&format, "LSA type %x", ntohs(type)) == -1) 590cb01fa27Sclaudio err(1, NULL); 591cb01fa27Sclaudio cleanup = 1; 592cb01fa27Sclaudio break; 5938e709cbdSnorby } 594cb01fa27Sclaudio if (LSA_IS_SCOPE_AREA(ntohs(type))) { 5958e709cbdSnorby if (asprintf(&header, "%s (Area %s)", format, 5968e709cbdSnorby inet_ntoa(aid)) == -1) 5978e709cbdSnorby err(1, NULL); 598cb01fa27Sclaudio } else if (LSA_IS_SCOPE_LLOCAL(ntohs(type))) { 599cb01fa27Sclaudio if (asprintf(&header, "%s (Area %s Interface %s)", format, 600cb01fa27Sclaudio inet_ntoa(aid), ifname) == -1) 601cb01fa27Sclaudio err(1, NULL); 60273094d71Sbenno } else { 60373094d71Sbenno if (asprintf(&header, "%s", format) == -1) 60473094d71Sbenno err(1, NULL); 605cb01fa27Sclaudio } 6068e709cbdSnorby 6078e709cbdSnorby printf("\n%-15s %s\n\n", "", header); 6088e709cbdSnorby free(header); 609cb01fa27Sclaudio if (cleanup) 610cb01fa27Sclaudio free(format); 6118e709cbdSnorby } 6128e709cbdSnorby 6138e709cbdSnorby int 6148e709cbdSnorby show_database_msg(struct imsg *imsg) 6158e709cbdSnorby { 6168e709cbdSnorby static struct in_addr area_id; 617cb01fa27Sclaudio static char ifname[IF_NAMESIZE]; 6187db04f17Sclaudio static u_int16_t lasttype; 6198e709cbdSnorby struct area *area; 620cb01fa27Sclaudio struct iface *iface; 6218e709cbdSnorby struct lsa_hdr *lsa; 6228e709cbdSnorby 6238e709cbdSnorby switch (imsg->hdr.type) { 6248e709cbdSnorby case IMSG_CTL_SHOW_DATABASE: 6258e709cbdSnorby case IMSG_CTL_SHOW_DB_SELF: 6268e709cbdSnorby lsa = imsg->data; 6278e709cbdSnorby if (lsa->type != lasttype) { 628cb01fa27Sclaudio show_database_head(area_id, ifname, lsa->type); 6298e709cbdSnorby printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID", 6308e709cbdSnorby "Adv Router", "Age", "Seq#", "Checksum"); 6318e709cbdSnorby } 6328e709cbdSnorby printf("%-15s %-15s %-4d 0x%08x 0x%04x\n", 6338e709cbdSnorby log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr), 6348e709cbdSnorby ntohs(lsa->age), ntohl(lsa->seq_num), 6358e709cbdSnorby ntohs(lsa->ls_chksum)); 6368e709cbdSnorby lasttype = lsa->type; 6378e709cbdSnorby break; 6388e709cbdSnorby case IMSG_CTL_AREA: 6398e709cbdSnorby area = imsg->data; 6408e709cbdSnorby area_id = area->id; 6418e709cbdSnorby lasttype = 0; 6428e709cbdSnorby break; 643cb01fa27Sclaudio case IMSG_CTL_IFACE: 644cb01fa27Sclaudio iface = imsg->data; 645cb01fa27Sclaudio strlcpy(ifname, iface->name, sizeof(ifname)); 646cb01fa27Sclaudio lasttype = 0; 647cb01fa27Sclaudio break; 6488e709cbdSnorby case IMSG_CTL_END: 6498e709cbdSnorby printf("\n"); 6508e709cbdSnorby return (1); 6518e709cbdSnorby default: 6528e709cbdSnorby break; 6538e709cbdSnorby } 6548e709cbdSnorby 6558e709cbdSnorby return (0); 6568e709cbdSnorby } 6578e709cbdSnorby 6588e709cbdSnorby char * 6594fabe8f9Snorby print_ls_type(u_int16_t type) 6608e709cbdSnorby { 661005d568eSclaudio switch (ntohs(type)) { 6624fabe8f9Snorby case LSA_TYPE_LINK: 6634fabe8f9Snorby return ("Link"); 6648e709cbdSnorby case LSA_TYPE_ROUTER: 6658e709cbdSnorby return ("Router"); 6668e709cbdSnorby case LSA_TYPE_NETWORK: 6678e709cbdSnorby return ("Network"); 6684fabe8f9Snorby case LSA_TYPE_INTER_A_PREFIX: 6694fabe8f9Snorby return ("Inter Area (Prefix)"); 6704fabe8f9Snorby case LSA_TYPE_INTER_A_ROUTER: 6714fabe8f9Snorby return ("Inter Area (Router)"); 6724fabe8f9Snorby case LSA_TYPE_INTRA_A_PREFIX: 6734fabe8f9Snorby return ("Intra Area (Prefix)"); 6748e709cbdSnorby case LSA_TYPE_EXTERNAL: 6758e709cbdSnorby return ("AS External"); 6768e709cbdSnorby default: 6778e709cbdSnorby return ("Unknown"); 6788e709cbdSnorby } 6798e709cbdSnorby } 6808e709cbdSnorby 6818e709cbdSnorby void 6828e709cbdSnorby show_db_hdr_msg_detail(struct lsa_hdr *lsa) 6838e709cbdSnorby { 6848e709cbdSnorby printf("LS age: %d\n", ntohs(lsa->age)); 6858e709cbdSnorby printf("LS Type: %s\n", print_ls_type(lsa->type)); 6868e709cbdSnorby 687005d568eSclaudio switch (ntohs(lsa->type)) { 68889f180e4Sstsp case LSA_TYPE_ROUTER: 68989f180e4Sstsp case LSA_TYPE_INTER_A_PREFIX: 69089f180e4Sstsp case LSA_TYPE_INTER_A_ROUTER: 69189f180e4Sstsp case LSA_TYPE_INTRA_A_PREFIX: 69289f180e4Sstsp case LSA_TYPE_EXTERNAL: 6934fabe8f9Snorby printf("Link State ID: %s\n", log_id(lsa->ls_id)); 6944fabe8f9Snorby break; 69589f180e4Sstsp case LSA_TYPE_LINK: 69689f180e4Sstsp printf("Link State ID: %s (Interface ID of Advertising " 69789f180e4Sstsp "Router)\n", log_id(lsa->ls_id)); 6988e709cbdSnorby break; 6998e709cbdSnorby case LSA_TYPE_NETWORK: 70089f180e4Sstsp printf("Link State ID: %s (Interface ID of Designated " 70189f180e4Sstsp "Router)\n", log_id(lsa->ls_id)); 7028e709cbdSnorby break; 7038e709cbdSnorby } 7048e709cbdSnorby 7058e709cbdSnorby printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr)); 7068e709cbdSnorby printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num)); 7078e709cbdSnorby printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum)); 7088e709cbdSnorby printf("Length: %d\n", ntohs(lsa->len)); 7098e709cbdSnorby } 7108e709cbdSnorby 7118e709cbdSnorby char * 7128e709cbdSnorby print_rtr_link_type(u_int8_t type) 7138e709cbdSnorby { 7148e709cbdSnorby switch (type) { 7158e709cbdSnorby case LINK_TYPE_POINTTOPOINT: 7168e709cbdSnorby return ("Point-to-Point"); 7178e709cbdSnorby case LINK_TYPE_TRANSIT_NET: 7188e709cbdSnorby return ("Transit Network"); 719005d568eSclaudio case LINK_TYPE_RESERVED: 720005d568eSclaudio return ("Reserved"); 7218e709cbdSnorby case LINK_TYPE_VIRTUAL: 7228e709cbdSnorby return ("Virtual Link"); 7238e709cbdSnorby default: 7248e709cbdSnorby return ("Unknown"); 7258e709cbdSnorby } 7268e709cbdSnorby } 7278e709cbdSnorby 7288e709cbdSnorby const char * 7298e709cbdSnorby print_ospf_flags(u_int8_t opts) 7308e709cbdSnorby { 7318e709cbdSnorby static char optbuf[32]; 7328e709cbdSnorby 733aff6ccb8Sclaudio snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s", 7348e709cbdSnorby opts & OSPF_RTR_V ? "V" : "-", 7358e709cbdSnorby opts & OSPF_RTR_E ? "E" : "-", 7368e709cbdSnorby opts & OSPF_RTR_B ? "B" : "-"); 7378e709cbdSnorby return (optbuf); 7388e709cbdSnorby } 7398e709cbdSnorby 7401aff836dSclaudio const char * 7411aff836dSclaudio print_asext_flags(u_int32_t opts) 7421aff836dSclaudio { 7431aff836dSclaudio static char optbuf[32]; 7441aff836dSclaudio 7451aff836dSclaudio snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s", 7461aff836dSclaudio opts & LSA_ASEXT_E_FLAG ? "E" : "-", 7471aff836dSclaudio opts & LSA_ASEXT_F_FLAG ? "F" : "-", 7481aff836dSclaudio opts & LSA_ASEXT_T_FLAG ? "T" : "-"); 7491aff836dSclaudio return (optbuf); 7501aff836dSclaudio } 7511aff836dSclaudio 7521aff836dSclaudio const char * 7531aff836dSclaudio print_prefix_opt(u_int8_t opts) 7541aff836dSclaudio { 7551aff836dSclaudio static char optbuf[32]; 7561aff836dSclaudio 7571aff836dSclaudio if (opts) { 7581aff836dSclaudio snprintf(optbuf, sizeof(optbuf), 7591aff836dSclaudio " Options: *|*|*|%s|%s|x|%s|%s", 7601aff836dSclaudio opts & OSPF_PREFIX_DN ? "DN" : "-", 7611aff836dSclaudio opts & OSPF_PREFIX_P ? "P" : "-", 7621aff836dSclaudio opts & OSPF_PREFIX_LA ? "LA" : "-", 7631aff836dSclaudio opts & OSPF_PREFIX_NU ? "NU" : "-"); 7641aff836dSclaudio return (optbuf); 7651aff836dSclaudio } 7661aff836dSclaudio return (""); 7671aff836dSclaudio } 7681aff836dSclaudio 7698e709cbdSnorby int 7708e709cbdSnorby show_db_msg_detail(struct imsg *imsg) 7718e709cbdSnorby { 7728e709cbdSnorby static struct in_addr area_id; 773cb01fa27Sclaudio static char ifname[IF_NAMESIZE]; 774005d568eSclaudio static u_int16_t lasttype; 7751aff836dSclaudio struct in6_addr ia6; 7768e709cbdSnorby struct in_addr addr, data; 7778e709cbdSnorby struct area *area; 778cb01fa27Sclaudio struct iface *iface; 7798e709cbdSnorby struct lsa *lsa; 7808e709cbdSnorby struct lsa_rtr_link *rtr_link; 7810f96e20cSstsp struct lsa_net_link *net_link; 782aeb06b08Sclaudio struct lsa_prefix *prefix; 7838e709cbdSnorby struct lsa_asext *asext; 7841aff836dSclaudio u_int32_t ext_tag; 7858e709cbdSnorby u_int16_t i, nlinks, off; 7868e709cbdSnorby 7878e709cbdSnorby /* XXX sanity checks! */ 7888e709cbdSnorby 7898e709cbdSnorby switch (imsg->hdr.type) { 7908e709cbdSnorby case IMSG_CTL_SHOW_DB_EXT: 7918e709cbdSnorby lsa = imsg->data; 7928e709cbdSnorby if (lsa->hdr.type != lasttype) 793cb01fa27Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 7948e709cbdSnorby show_db_hdr_msg_detail(&lsa->hdr); 7958e709cbdSnorby 7968e709cbdSnorby asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr)); 7978e709cbdSnorby 7981aff836dSclaudio printf(" Flags: %s\n", 7991aff836dSclaudio print_asext_flags(ntohl(lsa->data.asext.metric))); 8001aff836dSclaudio printf(" Metric: %d Type: ", ntohl(asext->metric) 8011aff836dSclaudio & LSA_METRIC_MASK); 8028e709cbdSnorby if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) 8038e709cbdSnorby printf("2\n"); 8048e709cbdSnorby else 8058e709cbdSnorby printf("1\n"); 8068e709cbdSnorby 8071aff836dSclaudio prefix = &asext->prefix; 8081aff836dSclaudio bzero(&ia6, sizeof(ia6)); 8091aff836dSclaudio bcopy(prefix + 1, &ia6, LSA_PREFIXSIZE(prefix->prefixlen)); 8101aff836dSclaudio printf(" Prefix: %s/%d%s\n", log_in6addr(&ia6), 8111aff836dSclaudio prefix->prefixlen, print_prefix_opt(prefix->options)); 8121aff836dSclaudio 8131aff836dSclaudio off = sizeof(*asext) + LSA_PREFIXSIZE(prefix->prefixlen); 8141aff836dSclaudio if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_F_FLAG) { 8151aff836dSclaudio bcopy((char *)asext + off, &ia6, sizeof(ia6)); 8161aff836dSclaudio printf(" Forwarding Address: %s\n", 8171aff836dSclaudio log_in6addr(&ia6)); 8181aff836dSclaudio off += sizeof(ia6); 8191aff836dSclaudio } 8201aff836dSclaudio if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_T_FLAG) { 8211aff836dSclaudio bcopy((char *)asext + off, &ext_tag, sizeof(ext_tag)); 8221aff836dSclaudio printf(" External Route Tag: %d\n", ntohl(ext_tag)); 8231aff836dSclaudio } 8241aff836dSclaudio printf("\n"); 8258e709cbdSnorby lasttype = lsa->hdr.type; 8268e709cbdSnorby break; 827aeb06b08Sclaudio case IMSG_CTL_SHOW_DB_LINK: 828aeb06b08Sclaudio lsa = imsg->data; 829aeb06b08Sclaudio if (lsa->hdr.type != lasttype) 830aeb06b08Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 831aeb06b08Sclaudio show_db_hdr_msg_detail(&lsa->hdr); 8325a54ac3cSclaudio printf("Options: %s\n", print_ospf_options(LSA_24_GETLO( 8335a54ac3cSclaudio ntohl(lsa->data.link.opts)))); 8345a54ac3cSclaudio printf("Link Local Address: %s\n", 8355a54ac3cSclaudio log_in6addr(&lsa->data.link.lladdr)); 836aeb06b08Sclaudio 837aeb06b08Sclaudio nlinks = ntohl(lsa->data.link.numprefix); 838aeb06b08Sclaudio printf("Number of Prefixes: %d\n", nlinks); 839aeb06b08Sclaudio off = sizeof(lsa->hdr) + sizeof(struct lsa_link); 840aeb06b08Sclaudio 841aeb06b08Sclaudio for (i = 0; i < nlinks; i++) { 842aeb06b08Sclaudio prefix = (struct lsa_prefix *)((char *)lsa + off); 8435a54ac3cSclaudio bzero(&ia6, sizeof(ia6)); 8445a54ac3cSclaudio bcopy(prefix + 1, &ia6, 8455a54ac3cSclaudio LSA_PREFIXSIZE(prefix->prefixlen)); 846aeb06b08Sclaudio 8471aff836dSclaudio printf(" Prefix: %s/%d%s\n", log_in6addr(&ia6), 8481aff836dSclaudio prefix->prefixlen, 8491aff836dSclaudio print_prefix_opt(prefix->options)); 850aeb06b08Sclaudio 85108720e8dSstsp off += sizeof(struct lsa_prefix) 85208720e8dSstsp + LSA_PREFIXSIZE(prefix->prefixlen); 853aeb06b08Sclaudio } 854aeb06b08Sclaudio 855aeb06b08Sclaudio printf("\n"); 856aeb06b08Sclaudio lasttype = lsa->hdr.type; 857aeb06b08Sclaudio break; 8588e709cbdSnorby case IMSG_CTL_SHOW_DB_NET: 8598e709cbdSnorby lsa = imsg->data; 8608e709cbdSnorby if (lsa->hdr.type != lasttype) 861cb01fa27Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 8628e709cbdSnorby show_db_hdr_msg_detail(&lsa->hdr); 8630bc8b661Sclaudio printf("Options: %s\n", 8640bc8b661Sclaudio print_ospf_options(LSA_24_GETLO(ntohl(lsa->data.net.opts)))); 8658e709cbdSnorby 8660f96e20cSstsp nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) - 8670f96e20cSstsp sizeof(struct lsa_net)) / sizeof(struct lsa_net_link); 8680f96e20cSstsp net_link = (struct lsa_net_link *)((char *)lsa + 8690f96e20cSstsp sizeof(lsa->hdr) + sizeof(lsa->data.net)); 870aeb06b08Sclaudio printf("Number of Routers: %d\n", nlinks); 8718e709cbdSnorby 8728e709cbdSnorby for (i = 0; i < nlinks; i++) { 8730f96e20cSstsp addr.s_addr = net_link->att_rtr; 8748e709cbdSnorby printf(" Attached Router: %s\n", inet_ntoa(addr)); 8750f96e20cSstsp net_link++; 8768e709cbdSnorby } 8778e709cbdSnorby 8788e709cbdSnorby printf("\n"); 8798e709cbdSnorby lasttype = lsa->hdr.type; 8808e709cbdSnorby break; 8818e709cbdSnorby case IMSG_CTL_SHOW_DB_RTR: 8828e709cbdSnorby lsa = imsg->data; 8838e709cbdSnorby if (lsa->hdr.type != lasttype) 884cb01fa27Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 8858e709cbdSnorby show_db_hdr_msg_detail(&lsa->hdr); 8869d28d229Sclaudio printf("Flags: %s\n", 887aff6ccb8Sclaudio print_ospf_flags(LSA_24_GETHI(ntohl(lsa->data.rtr.opts)))); 8889d28d229Sclaudio printf("Options: %s\n", 889aff6ccb8Sclaudio print_ospf_options(LSA_24_GETLO(ntohl(lsa->data.rtr.opts)))); 8909d28d229Sclaudio 8919d28d229Sclaudio nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) 8929d28d229Sclaudio - sizeof(u_int32_t)) / sizeof(struct lsa_rtr_link); 8934091c104Sbluhm printf("Number of Links: %d\n\n", nlinks); 8948e709cbdSnorby 8958e709cbdSnorby off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr); 8968e709cbdSnorby 8978e709cbdSnorby for (i = 0; i < nlinks; i++) { 8988e709cbdSnorby rtr_link = (struct lsa_rtr_link *)((char *)lsa + off); 8998e709cbdSnorby 9003ded35dfSstsp printf(" Link (Interface ID %s) connected to: %s\n", 9013ded35dfSstsp log_id(rtr_link->iface_id), 9028e709cbdSnorby print_rtr_link_type(rtr_link->type)); 9038e709cbdSnorby 904005d568eSclaudio addr.s_addr = rtr_link->nbr_rtr_id; 9053ded35dfSstsp data.s_addr = rtr_link->nbr_iface_id; 9068e709cbdSnorby 9078e709cbdSnorby switch (rtr_link->type) { 9088e709cbdSnorby case LINK_TYPE_POINTTOPOINT: 9098e709cbdSnorby case LINK_TYPE_VIRTUAL: 910005d568eSclaudio printf(" Router ID: %s\n", inet_ntoa(addr)); 911005d568eSclaudio printf(" Interface ID: %s\n", 912005d568eSclaudio inet_ntoa(data)); 9138e709cbdSnorby break; 9148e709cbdSnorby case LINK_TYPE_TRANSIT_NET: 915005d568eSclaudio printf(" Designated Router ID: %s\n", 9168e709cbdSnorby inet_ntoa(addr)); 917005d568eSclaudio printf(" DR Interface ID: %s\n", 9188e709cbdSnorby inet_ntoa(data)); 9198e709cbdSnorby break; 9208e709cbdSnorby default: 921005d568eSclaudio printf(" Link ID (Unknown type %d): %s\n", 922005d568eSclaudio rtr_link->type, inet_ntoa(addr)); 9238e709cbdSnorby printf(" Link Data (Unknown): %s\n", 9248e709cbdSnorby inet_ntoa(data)); 9258e709cbdSnorby break; 9268e709cbdSnorby } 9278e709cbdSnorby 9288e709cbdSnorby printf(" Metric: %d\n\n", ntohs(rtr_link->metric)); 9298e709cbdSnorby 930005d568eSclaudio off += sizeof(struct lsa_rtr_link); 9318e709cbdSnorby } 9328e709cbdSnorby 9338e709cbdSnorby lasttype = lsa->hdr.type; 9348e709cbdSnorby break; 93541bcac6bSstsp case IMSG_CTL_SHOW_DB_INTRA: 93641bcac6bSstsp lsa = imsg->data; 93741bcac6bSstsp if (lsa->hdr.type != lasttype) 93841bcac6bSstsp show_database_head(area_id, ifname, lsa->hdr.type); 93941bcac6bSstsp show_db_hdr_msg_detail(&lsa->hdr); 94041bcac6bSstsp printf("Referenced LS Type: %s\n", 94141bcac6bSstsp print_ls_type(lsa->data.pref_intra.ref_type)); 942e0e6f381Sclaudio addr.s_addr = lsa->data.pref_intra.ref_ls_id; 94341bcac6bSstsp printf("Referenced Link State ID: %s\n", inet_ntoa(addr)); 94441bcac6bSstsp addr.s_addr = lsa->data.pref_intra.ref_adv_rtr; 94541bcac6bSstsp printf("Referenced Advertising Router: %s\n", inet_ntoa(addr)); 94641bcac6bSstsp nlinks = ntohs(lsa->data.pref_intra.numprefix); 94741bcac6bSstsp printf("Number of Prefixes: %d\n", nlinks); 94841bcac6bSstsp 94941bcac6bSstsp off = sizeof(lsa->hdr) + sizeof(struct lsa_intra_prefix); 95041bcac6bSstsp 95141bcac6bSstsp for (i = 0; i < nlinks; i++) { 95241bcac6bSstsp prefix = (struct lsa_prefix *)((char *)lsa + off); 95341bcac6bSstsp bzero(&ia6, sizeof(ia6)); 95441bcac6bSstsp bcopy(prefix + 1, &ia6, 95541bcac6bSstsp LSA_PREFIXSIZE(prefix->prefixlen)); 95641bcac6bSstsp 9578e35e101Sremi printf(" Prefix: %s/%d%s Metric: %d\n", 9588e35e101Sremi log_in6addr(&ia6), prefix->prefixlen, 9598e35e101Sremi print_prefix_opt(prefix->options), 9608e35e101Sremi ntohs(prefix->metric)); 96141bcac6bSstsp 96208720e8dSstsp off += sizeof(struct lsa_prefix) 96308720e8dSstsp + LSA_PREFIXSIZE(prefix->prefixlen); 96441bcac6bSstsp } 9659415b30cSstsp 9669415b30cSstsp printf("\n"); 9679415b30cSstsp lasttype = lsa->hdr.type; 96841bcac6bSstsp break; 9698e709cbdSnorby case IMSG_CTL_SHOW_DB_SUM: 9708e709cbdSnorby lsa = imsg->data; 9718e709cbdSnorby if (lsa->hdr.type != lasttype) 972cb01fa27Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 9738e709cbdSnorby show_db_hdr_msg_detail(&lsa->hdr); 974cb01fa27Sclaudio printf("Prefix: XXX\n"); 975aeb06b08Sclaudio printf("Metric: %d\n", ntohl(lsa->data.pref_sum.metric) & 9768e709cbdSnorby LSA_METRIC_MASK); 9778e709cbdSnorby lasttype = lsa->hdr.type; 9788e709cbdSnorby break; 979cb01fa27Sclaudio case IMSG_CTL_SHOW_DB_ASBR: 980cb01fa27Sclaudio lsa = imsg->data; 981cb01fa27Sclaudio if (lsa->hdr.type != lasttype) 982cb01fa27Sclaudio show_database_head(area_id, ifname, lsa->hdr.type); 983cb01fa27Sclaudio show_db_hdr_msg_detail(&lsa->hdr); 984cb01fa27Sclaudio 985cb01fa27Sclaudio addr.s_addr = lsa->data.rtr_sum.dest_rtr_id; 986cb01fa27Sclaudio printf("Destination Router ID: %s\n", inet_ntoa(addr)); 987cb01fa27Sclaudio printf("Options: %s\n", 988aeb06b08Sclaudio print_ospf_options(ntohl(lsa->data.rtr_sum.opts))); 989cb01fa27Sclaudio printf("Metric: %d\n\n", ntohl(lsa->data.rtr_sum.metric) & 990cb01fa27Sclaudio LSA_METRIC_MASK); 9918e709cbdSnorby case IMSG_CTL_AREA: 9928e709cbdSnorby area = imsg->data; 9938e709cbdSnorby area_id = area->id; 9948e709cbdSnorby lasttype = 0; 9958e709cbdSnorby break; 996cb01fa27Sclaudio case IMSG_CTL_IFACE: 997cb01fa27Sclaudio iface = imsg->data; 998cb01fa27Sclaudio strlcpy(ifname, iface->name, sizeof(ifname)); 999cb01fa27Sclaudio lasttype = 0; 1000cb01fa27Sclaudio break; 10018e709cbdSnorby case IMSG_CTL_END: 10028e709cbdSnorby return (1); 10038e709cbdSnorby default: 10048e709cbdSnorby break; 10058e709cbdSnorby } 10068e709cbdSnorby 10078e709cbdSnorby return (0); 10088e709cbdSnorby } 10098e709cbdSnorby 10108e709cbdSnorby int 10118e709cbdSnorby show_nbr_msg(struct imsg *imsg) 10128e709cbdSnorby { 10138e709cbdSnorby struct ctl_nbr *nbr; 10148e709cbdSnorby char *state; 10158e709cbdSnorby 10168e709cbdSnorby switch (imsg->hdr.type) { 10178e709cbdSnorby case IMSG_CTL_SHOW_NBR: 10188e709cbdSnorby nbr = imsg->data; 10198e709cbdSnorby if (asprintf(&state, "%s/%s", nbr_state_name(nbr->nbr_state), 10208e709cbdSnorby if_state_name(nbr->iface_state)) == -1) 10218e709cbdSnorby err(1, NULL); 1022558ada41Snorby printf("%-15s %-3d %-12s %-10s", inet_ntoa(nbr->id), 10238e709cbdSnorby nbr->priority, state, fmt_timeframe_core(nbr->dead_timer)); 1024558ada41Snorby printf("%-11s %s\n", nbr->name, 10258e709cbdSnorby nbr->uptime == 0 ? "-" : fmt_timeframe_core(nbr->uptime)); 10268e709cbdSnorby free(state); 10278e709cbdSnorby break; 10288e709cbdSnorby case IMSG_CTL_END: 10298e709cbdSnorby printf("\n"); 10308e709cbdSnorby return (1); 10318e709cbdSnorby default: 10328e709cbdSnorby break; 10338e709cbdSnorby } 10348e709cbdSnorby 10358e709cbdSnorby return (0); 10368e709cbdSnorby } 10378e709cbdSnorby 10388e709cbdSnorby const char * 1039aff6ccb8Sclaudio print_ospf_options(u_int32_t opts) 10408e709cbdSnorby { 10418e709cbdSnorby static char optbuf[32]; 10428e709cbdSnorby 1043aff6ccb8Sclaudio snprintf(optbuf, sizeof(optbuf), "*|*|%s|%s|%s|*|%s|%s", 10448e709cbdSnorby opts & OSPF_OPTION_DC ? "DC" : "-", 10458e709cbdSnorby opts & OSPF_OPTION_R ? "R" : "-", 10468e709cbdSnorby opts & OSPF_OPTION_N ? "N" : "-", 10478e709cbdSnorby opts & OSPF_OPTION_E ? "E" : "-", 10488e709cbdSnorby opts & OSPF_OPTION_V6 ? "V6" : "-"); 10498e709cbdSnorby return (optbuf); 10508e709cbdSnorby } 10518e709cbdSnorby 10528e709cbdSnorby int 10538e709cbdSnorby show_nbr_detail_msg(struct imsg *imsg) 10548e709cbdSnorby { 10558e709cbdSnorby struct ctl_nbr *nbr; 10568e709cbdSnorby 10578e709cbdSnorby switch (imsg->hdr.type) { 10588e709cbdSnorby case IMSG_CTL_SHOW_NBR: 10598e709cbdSnorby nbr = imsg->data; 10608e709cbdSnorby printf("\nNeighbor %s, ", inet_ntoa(nbr->id)); 10618e709cbdSnorby printf("interface address %s\n", log_in6addr(&nbr->addr)); 10628e709cbdSnorby printf(" Area %s, interface %s\n", inet_ntoa(nbr->area), 10638e709cbdSnorby nbr->name); 10648e709cbdSnorby printf(" Neighbor priority is %d, " 10658e709cbdSnorby "State is %s, %d state changes\n", 10668e709cbdSnorby nbr->priority, nbr_state_name(nbr->nbr_state), 10678e709cbdSnorby nbr->state_chng_cnt); 10688e709cbdSnorby printf(" DR is %s, ", inet_ntoa(nbr->dr)); 10698e709cbdSnorby printf("BDR is %s\n", inet_ntoa(nbr->bdr)); 10708e709cbdSnorby printf(" Options %s\n", print_ospf_options(nbr->options)); 10718e709cbdSnorby printf(" Dead timer due in %s\n", 10728e709cbdSnorby fmt_timeframe_core(nbr->dead_timer)); 10738e709cbdSnorby printf(" Uptime %s\n", fmt_timeframe_core(nbr->uptime)); 10748e709cbdSnorby printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt); 10758e709cbdSnorby printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt); 10768e709cbdSnorby printf(" Link State Retransmission List %d\n", 10778e709cbdSnorby nbr->ls_retrans_lst_cnt); 10788e709cbdSnorby break; 10798e709cbdSnorby case IMSG_CTL_END: 10808e709cbdSnorby printf("\n"); 10818e709cbdSnorby return (1); 10828e709cbdSnorby default: 10838e709cbdSnorby break; 10848e709cbdSnorby } 10858e709cbdSnorby 10868e709cbdSnorby return (0); 10878e709cbdSnorby } 10888e709cbdSnorby 10898e709cbdSnorby int 10908e709cbdSnorby show_rib_msg(struct imsg *imsg) 10918e709cbdSnorby { 10928e709cbdSnorby struct ctl_rt *rt; 10938e709cbdSnorby char *dstnet; 10948e709cbdSnorby 10958e709cbdSnorby switch (imsg->hdr.type) { 10968e709cbdSnorby case IMSG_CTL_SHOW_RIB: 10978e709cbdSnorby rt = imsg->data; 10988e709cbdSnorby switch (rt->d_type) { 10998e709cbdSnorby case DT_NET: 11000104e403Sclaudio if (asprintf(&dstnet, "%s/%d", log_in6addr(&rt->prefix), 11018e709cbdSnorby rt->prefixlen) == -1) 11028e709cbdSnorby err(1, NULL); 11038e709cbdSnorby break; 11048e709cbdSnorby case DT_RTR: 11058e709cbdSnorby if (asprintf(&dstnet, "%s", 11060104e403Sclaudio log_in6addr(&rt->prefix)) == -1) 11078e709cbdSnorby err(1, NULL); 11088e709cbdSnorby break; 11098e709cbdSnorby default: 11108e709cbdSnorby errx(1, "Invalid route type"); 11118e709cbdSnorby } 11128e709cbdSnorby 111355dcbf22Sdenis printf("%-20s %-16s%s %-12s %-9s %-7d %s\n", dstnet, 11140a08a1b1Sclaudio log_in6addr_scope(&rt->nexthop, rt->ifindex), 111555dcbf22Sdenis rt->connected ? "C" : " ", path_type_name(rt->p_type), 111655dcbf22Sdenis dst_type_name(rt->d_type), rt->cost, 11178e709cbdSnorby rt->uptime == 0 ? "-" : fmt_timeframe_core(rt->uptime)); 11188e709cbdSnorby free(dstnet); 11198e709cbdSnorby break; 11208e709cbdSnorby case IMSG_CTL_END: 11218e709cbdSnorby printf("\n"); 11228e709cbdSnorby return (1); 11238e709cbdSnorby default: 11248e709cbdSnorby break; 11258e709cbdSnorby } 11268e709cbdSnorby 11278e709cbdSnorby return (0); 11288e709cbdSnorby } 11298e709cbdSnorby 11308e709cbdSnorby void 11318e709cbdSnorby show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) 11328e709cbdSnorby { 11338e709cbdSnorby char *header, *format, *format2; 11348e709cbdSnorby 11358e709cbdSnorby switch (p_type) { 11368e709cbdSnorby case PT_INTRA_AREA: 11378e709cbdSnorby case PT_INTER_AREA: 11388e709cbdSnorby switch (d_type) { 11398e709cbdSnorby case DT_NET: 11408e709cbdSnorby format = "Network Routing Table"; 11418e709cbdSnorby format2 = ""; 11428e709cbdSnorby break; 11438e709cbdSnorby case DT_RTR: 11448e709cbdSnorby format = "Router Routing Table"; 11458e709cbdSnorby format2 = "Type"; 11468e709cbdSnorby break; 11478e709cbdSnorby default: 11488e709cbdSnorby errx(1, "unknown route type"); 11498e709cbdSnorby } 11508e709cbdSnorby break; 11518e709cbdSnorby case PT_TYPE1_EXT: 11528e709cbdSnorby case PT_TYPE2_EXT: 11538e709cbdSnorby format = NULL; 11548e709cbdSnorby format2 = "Cost 2"; 11558e709cbdSnorby if ((header = strdup("External Routing Table")) == NULL) 11568e709cbdSnorby err(1, NULL); 11578e709cbdSnorby break; 11588e709cbdSnorby default: 11598e709cbdSnorby errx(1, "unknown route type"); 11608e709cbdSnorby } 11618e709cbdSnorby 11628e709cbdSnorby if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) 11638e709cbdSnorby if (asprintf(&header, "%s (Area %s)", format, 11648e709cbdSnorby inet_ntoa(aid)) == -1) 11658e709cbdSnorby err(1, NULL); 11668e709cbdSnorby 11678e709cbdSnorby printf("\n%-18s %s\n", "", header); 11688e709cbdSnorby free(header); 11698e709cbdSnorby 11708e709cbdSnorby printf("\n%-18s %-15s %-15s %-12s %-7s %-7s\n", "Destination", 11718e709cbdSnorby "Nexthop", "Adv Router", "Path type", "Cost", format2); 11728e709cbdSnorby } 11738e709cbdSnorby 11748e709cbdSnorby const char * 11758e709cbdSnorby print_ospf_rtr_flags(u_int8_t opts) 11768e709cbdSnorby { 11778e709cbdSnorby static char optbuf[32]; 11788e709cbdSnorby 11798e709cbdSnorby snprintf(optbuf, sizeof(optbuf), "%s%s%s", 11808e709cbdSnorby opts & OSPF_RTR_E ? "AS" : "", 11818e709cbdSnorby opts & OSPF_RTR_E && opts & OSPF_RTR_B ? "+" : "", 11828e709cbdSnorby opts & OSPF_RTR_B ? "ABR" : ""); 11838e709cbdSnorby return (optbuf); 11848e709cbdSnorby } 11858e709cbdSnorby 11868e709cbdSnorby int 11878e709cbdSnorby show_rib_detail_msg(struct imsg *imsg) 11888e709cbdSnorby { 11898e709cbdSnorby struct ctl_rt *rt; 11908e709cbdSnorby char *dstnet; 11918e709cbdSnorby static u_int8_t lasttype; 11928e709cbdSnorby 11938e709cbdSnorby switch (imsg->hdr.type) { 11948e709cbdSnorby case IMSG_CTL_SHOW_RIB: 11958e709cbdSnorby rt = imsg->data; 11968e709cbdSnorby 11978e709cbdSnorby switch (rt->p_type) { 11988e709cbdSnorby case PT_INTRA_AREA: 11998e709cbdSnorby case PT_INTER_AREA: 12008e709cbdSnorby switch (rt->d_type) { 12018e709cbdSnorby case DT_NET: 12028e709cbdSnorby if (lasttype != RIB_NET) 12038e709cbdSnorby show_rib_head(rt->area, rt->d_type, 12048e709cbdSnorby rt->p_type); 12058e709cbdSnorby if (asprintf(&dstnet, "%s/%d", 12060104e403Sclaudio log_in6addr(&rt->prefix), 12070104e403Sclaudio rt->prefixlen) == -1) 12088e709cbdSnorby err(1, NULL); 12098e709cbdSnorby lasttype = RIB_NET; 12108e709cbdSnorby break; 12118e709cbdSnorby case DT_RTR: 12128e709cbdSnorby if (lasttype != RIB_RTR) 12138e709cbdSnorby show_rib_head(rt->area, rt->d_type, 12148e709cbdSnorby rt->p_type); 12158e709cbdSnorby if (asprintf(&dstnet, "%s", 12160104e403Sclaudio log_in6addr(&rt->prefix)) == -1) 12178e709cbdSnorby err(1, NULL); 12188e709cbdSnorby lasttype = RIB_RTR; 12198e709cbdSnorby break; 12208e709cbdSnorby default: 12218e709cbdSnorby errx(1, "unknown route type"); 12228e709cbdSnorby } 12230104e403Sclaudio printf("%-18s %-15s ", dstnet, 12245d8c2b7fSclaudio log_in6addr_scope(&rt->nexthop, rt->ifindex)); 12258e709cbdSnorby printf("%-15s %-12s %-7d", inet_ntoa(rt->adv_rtr), 12268e709cbdSnorby path_type_name(rt->p_type), rt->cost); 12278e709cbdSnorby free(dstnet); 12288e709cbdSnorby 12298e709cbdSnorby if (rt->d_type == DT_RTR) 12308e709cbdSnorby printf(" %-7s", 12318e709cbdSnorby print_ospf_rtr_flags(rt->flags)); 12328e709cbdSnorby 12338e709cbdSnorby printf("\n"); 12348e709cbdSnorby break; 12358e709cbdSnorby case PT_TYPE1_EXT: 12368e709cbdSnorby case PT_TYPE2_EXT: 12378e709cbdSnorby if (lasttype != RIB_EXT) 12388e709cbdSnorby show_rib_head(rt->area, rt->d_type, rt->p_type); 12398e709cbdSnorby 12408e709cbdSnorby if (asprintf(&dstnet, "%s/%d", 12410104e403Sclaudio log_in6addr(&rt->prefix), rt->prefixlen) == -1) 12428e709cbdSnorby err(1, NULL); 12438e709cbdSnorby 12440104e403Sclaudio printf("%-18s %-15s ", dstnet, 12455d8c2b7fSclaudio log_in6addr_scope(&rt->nexthop, rt->ifindex)); 12468e709cbdSnorby printf("%-15s %-12s %-7d %-7d\n", 12478e709cbdSnorby inet_ntoa(rt->adv_rtr), path_type_name(rt->p_type), 12488e709cbdSnorby rt->cost, rt->cost2); 12498957b20dSstsp free(dstnet); 12508e709cbdSnorby 12518e709cbdSnorby lasttype = RIB_EXT; 12528e709cbdSnorby break; 12538e709cbdSnorby default: 12548e709cbdSnorby errx(1, "unknown route type"); 12558e709cbdSnorby } 12568e709cbdSnorby break; 12578e709cbdSnorby case IMSG_CTL_AREA: 12588e709cbdSnorby break; 12598e709cbdSnorby case IMSG_CTL_END: 12608e709cbdSnorby printf("\n"); 12618e709cbdSnorby return (1); 12628e709cbdSnorby default: 12638e709cbdSnorby break; 12648e709cbdSnorby } 12658e709cbdSnorby 12668e709cbdSnorby return (0); 12678e709cbdSnorby } 12688e709cbdSnorby 12698e709cbdSnorby void 12708e709cbdSnorby show_fib_head(void) 12718e709cbdSnorby { 12728e709cbdSnorby printf("flags: * = valid, O = OSPF, C = Connected, S = Static\n"); 1273afd0ab5dSfriehm printf("%-6s %-4s %-20s %-17s\n", 1274afd0ab5dSfriehm "Flags", "Prio", "Destination", "Nexthop"); 12758e709cbdSnorby } 12768e709cbdSnorby 12778e709cbdSnorby int 12788e709cbdSnorby show_fib_msg(struct imsg *imsg) 12798e709cbdSnorby { 12808e709cbdSnorby struct kroute *k; 12818e709cbdSnorby char *p; 12828e709cbdSnorby 12838e709cbdSnorby switch (imsg->hdr.type) { 12848e709cbdSnorby case IMSG_CTL_KROUTE: 12858e709cbdSnorby if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) 12868e709cbdSnorby errx(1, "wrong imsg len"); 12878e709cbdSnorby k = imsg->data; 12888e709cbdSnorby 12898e709cbdSnorby if (k->flags & F_DOWN) 12908e709cbdSnorby printf(" "); 12918e709cbdSnorby else 12928e709cbdSnorby printf("*"); 12938e709cbdSnorby 12948e709cbdSnorby if (!(k->flags & F_KERNEL)) 12958e709cbdSnorby printf("O"); 12968e709cbdSnorby else if (k->flags & F_CONNECTED) 12978e709cbdSnorby printf("C"); 12988e709cbdSnorby else if (k->flags & F_STATIC) 12998e709cbdSnorby printf("S"); 13008e709cbdSnorby else 13018e709cbdSnorby printf(" "); 13028e709cbdSnorby 13038e709cbdSnorby printf(" "); 1304afd0ab5dSfriehm printf("%4d ", k->priority); 13050104e403Sclaudio if (asprintf(&p, "%s/%u", log_in6addr(&k->prefix), 13060104e403Sclaudio k->prefixlen) == -1) 13078e709cbdSnorby err(1, NULL); 13088e709cbdSnorby printf("%-20s ", p); 13098e709cbdSnorby free(p); 13108e709cbdSnorby 13110104e403Sclaudio if (!IN6_IS_ADDR_UNSPECIFIED(&k->nexthop)) 13125d8c2b7fSclaudio printf("%s", log_in6addr_scope(&k->nexthop, k->scope)); 13138e709cbdSnorby else if (k->flags & F_CONNECTED) 13148e709cbdSnorby printf("link#%u", k->ifindex); 13158e709cbdSnorby printf("\n"); 13168e709cbdSnorby 13178e709cbdSnorby break; 13188e709cbdSnorby case IMSG_CTL_END: 13198e709cbdSnorby printf("\n"); 13208e709cbdSnorby return (1); 13218e709cbdSnorby default: 13228e709cbdSnorby break; 13238e709cbdSnorby } 13248e709cbdSnorby 13258e709cbdSnorby return (0); 13268e709cbdSnorby } 13278e709cbdSnorby 13280f617141Sclaudio const struct if_status_description 13290f617141Sclaudio if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; 13308e709cbdSnorby const struct ifmedia_description 13318e709cbdSnorby ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; 13328e709cbdSnorby 13338e709cbdSnorby const char * 1334e5605ae3Sderaadt get_media_descr(uint64_t media_type) 13358e709cbdSnorby { 13368e709cbdSnorby const struct ifmedia_description *p; 13378e709cbdSnorby 13388e709cbdSnorby for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) 13398e709cbdSnorby if (media_type == p->ifmt_word) 13408e709cbdSnorby return (p->ifmt_string); 13418e709cbdSnorby 13428e709cbdSnorby return ("unknown"); 13438e709cbdSnorby } 13448e709cbdSnorby 13458e709cbdSnorby const char * 134618ffdd94Sstsp get_linkstate(uint8_t if_type, int link_state) 13478e709cbdSnorby { 13480f617141Sclaudio const struct if_status_description *p; 13490f617141Sclaudio static char buf[8]; 13508e709cbdSnorby 13510f617141Sclaudio for (p = if_status_descriptions; p->ifs_string != NULL; p++) { 135218ffdd94Sstsp if (LINK_STATE_DESC_MATCH(p, if_type, link_state)) 13530f617141Sclaudio return (p->ifs_string); 13548e709cbdSnorby } 13550f617141Sclaudio snprintf(buf, sizeof(buf), "[#%d]", link_state); 13560f617141Sclaudio return (buf); 13578e709cbdSnorby } 13588e709cbdSnorby 13598e709cbdSnorby void 13608e709cbdSnorby print_baudrate(u_int64_t baudrate) 13618e709cbdSnorby { 13628e709cbdSnorby if (baudrate > IF_Gbps(1)) 13638e709cbdSnorby printf("%llu GBit/s", baudrate / IF_Gbps(1)); 13648e709cbdSnorby else if (baudrate > IF_Mbps(1)) 13658e709cbdSnorby printf("%llu MBit/s", baudrate / IF_Mbps(1)); 13668e709cbdSnorby else if (baudrate > IF_Kbps(1)) 13678e709cbdSnorby printf("%llu KBit/s", baudrate / IF_Kbps(1)); 13688e709cbdSnorby else 13698e709cbdSnorby printf("%llu Bit/s", baudrate); 13708e709cbdSnorby } 1371