1*4fabe8f9Snorby /* $OpenBSD: ospf6ctl.c,v 1.8 2007/10/16 12:07:58 norby 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> 308e709cbdSnorby #include <stdio.h> 318e709cbdSnorby #include <stdlib.h> 328e709cbdSnorby #include <string.h> 338e709cbdSnorby #include <unistd.h> 348e709cbdSnorby 358e709cbdSnorby #include "ospf6.h" 368e709cbdSnorby #include "ospf6d.h" 378e709cbdSnorby #include "ospfe.h" 388e709cbdSnorby #include "parser.h" 398e709cbdSnorby #include "log.h" 408e709cbdSnorby 418e709cbdSnorby __dead void usage(void); 428e709cbdSnorby int show_summary_msg(struct imsg *); 438e709cbdSnorby int get_ifms_type(int); 448e709cbdSnorby int show_interface_msg(struct imsg *); 458e709cbdSnorby int show_interface_detail_msg(struct imsg *); 468e709cbdSnorby const char *print_link(int); 478e709cbdSnorby const char *fmt_timeframe(time_t t); 488e709cbdSnorby const char *fmt_timeframe_core(time_t t); 498e709cbdSnorby const char *log_id(u_int32_t ); 508e709cbdSnorby const char *log_adv_rtr(u_int32_t); 51*4fabe8f9Snorby void show_database_head(struct in_addr, u_int16_t); 528e709cbdSnorby int show_database_msg(struct imsg *); 53*4fabe8f9Snorby char *print_ls_type(u_int16_t); 548e709cbdSnorby void show_db_hdr_msg_detail(struct lsa_hdr *); 558e709cbdSnorby char *print_rtr_link_type(u_int8_t); 568e709cbdSnorby const char *print_ospf_flags(u_int8_t); 578e709cbdSnorby int show_db_msg_detail(struct imsg *imsg); 588e709cbdSnorby int show_nbr_msg(struct imsg *); 598e709cbdSnorby const char *print_ospf_options(u_int8_t); 608e709cbdSnorby int show_nbr_detail_msg(struct imsg *); 618e709cbdSnorby int show_rib_msg(struct imsg *); 628e709cbdSnorby void show_rib_head(struct in_addr, u_int8_t, u_int8_t); 638e709cbdSnorby const char *print_ospf_rtr_flags(u_int8_t); 648e709cbdSnorby int show_rib_detail_msg(struct imsg *); 658e709cbdSnorby void show_fib_head(void); 668e709cbdSnorby int show_fib_msg(struct imsg *); 678e709cbdSnorby void show_interface_head(void); 688e709cbdSnorby const char * get_media_descr(int); 698e709cbdSnorby const char * get_linkstate(int, int); 708e709cbdSnorby void print_baudrate(u_int64_t); 718e709cbdSnorby int show_fib_interface_msg(struct imsg *); 728e709cbdSnorby 738e709cbdSnorby struct imsgbuf *ibuf; 748e709cbdSnorby 758e709cbdSnorby __dead void 768e709cbdSnorby usage(void) 778e709cbdSnorby { 788e709cbdSnorby extern char *__progname; 798e709cbdSnorby 808e709cbdSnorby fprintf(stderr, "usage: %s <command> [arg [...]]\n", __progname); 818e709cbdSnorby exit(1); 828e709cbdSnorby } 838e709cbdSnorby 848e709cbdSnorby /* dummy function so that ospf6ctl does not need libevent */ 858e709cbdSnorby void 868e709cbdSnorby imsg_event_add(struct imsgbuf *i) 878e709cbdSnorby { 888e709cbdSnorby /* nothing */ 898e709cbdSnorby } 908e709cbdSnorby 918e709cbdSnorby int 928e709cbdSnorby main(int argc, char *argv[]) 938e709cbdSnorby { 948e709cbdSnorby struct sockaddr_un sun; 958e709cbdSnorby struct parse_result *res; 968e709cbdSnorby struct imsg imsg; 978e709cbdSnorby unsigned int ifidx = 0; 988e709cbdSnorby int ctl_sock; 998e709cbdSnorby int done = 0; 1008e709cbdSnorby int n; 1018e709cbdSnorby 1028e709cbdSnorby /* parse options */ 1038e709cbdSnorby if ((res = parse(argc - 1, argv + 1)) == NULL) 1048e709cbdSnorby exit(1); 1058e709cbdSnorby 1068e709cbdSnorby /* connect to ospf6d control socket */ 1078e709cbdSnorby if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 1088e709cbdSnorby err(1, "socket"); 1098e709cbdSnorby 1108e709cbdSnorby bzero(&sun, sizeof(sun)); 1118e709cbdSnorby sun.sun_family = AF_UNIX; 1128e709cbdSnorby strlcpy(sun.sun_path, OSPF6D_SOCKET, sizeof(sun.sun_path)); 1138e709cbdSnorby if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 1148e709cbdSnorby err(1, "connect: %s", OSPF6D_SOCKET); 1158e709cbdSnorby 1168e709cbdSnorby if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 1178e709cbdSnorby err(1, NULL); 1188e709cbdSnorby imsg_init(ibuf, ctl_sock, NULL); 1198e709cbdSnorby done = 0; 1208e709cbdSnorby 1218e709cbdSnorby /* process user request */ 1228e709cbdSnorby switch (res->action) { 1238e709cbdSnorby case NONE: 1248e709cbdSnorby usage(); 1258e709cbdSnorby /* not reached */ 1268e709cbdSnorby case SHOW: 1278e709cbdSnorby case SHOW_SUM: 1288e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, NULL, 0); 1298e709cbdSnorby break; 1308e709cbdSnorby case SHOW_IFACE: 1311fed8bffSnorby printf("%-11s %-29s %-6s %-10s %-10s %-8s\n", 1328e709cbdSnorby "Interface", "Address", "State", "HelloTimer", "Linkstate", 1331fed8bffSnorby "Uptime"); 134c5ba8b41Sderaadt /*FALLTHROUGH*/ 1358e709cbdSnorby case SHOW_IFACE_DTAIL: 1368e709cbdSnorby if (*res->ifname) { 1378e709cbdSnorby ifidx = if_nametoindex(res->ifname); 1388e709cbdSnorby if (ifidx == 0) 1398e709cbdSnorby errx(1, "no such interface %s", res->ifname); 1408e709cbdSnorby } 1418e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, 1428e709cbdSnorby &ifidx, sizeof(ifidx)); 1438e709cbdSnorby break; 1448e709cbdSnorby case SHOW_NBR: 145558ada41Snorby printf("%-15s %-3s %-12s %-9s %-11s %s\n", "ID", "Pri", 146558ada41Snorby "State", "DeadTime", "Iface","Uptime"); 147c5ba8b41Sderaadt /*FALLTHROUGH*/ 1488e709cbdSnorby case SHOW_NBR_DTAIL: 1498e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, NULL, 0); 1508e709cbdSnorby break; 1518e709cbdSnorby case SHOW_DB: 1528e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, NULL, 0); 1538e709cbdSnorby break; 1548e709cbdSnorby case SHOW_DBBYAREA: 1558e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, 1568e709cbdSnorby &res->addr, sizeof(res->addr)); 1578e709cbdSnorby break; 1588e709cbdSnorby case SHOW_DBEXT: 1598e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, NULL, 0); 1608e709cbdSnorby break; 1618e709cbdSnorby case SHOW_DBNET: 1628e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, NULL, 0); 1638e709cbdSnorby break; 1648e709cbdSnorby case SHOW_DBRTR: 1658e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, NULL, 0); 1668e709cbdSnorby break; 1678e709cbdSnorby case SHOW_DBSELF: 1688e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, NULL, 0); 1698e709cbdSnorby break; 1708e709cbdSnorby case SHOW_DBSUM: 1718e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, NULL, 0); 1728e709cbdSnorby break; 1738e709cbdSnorby case SHOW_DBASBR: 1748e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, NULL, 0); 1758e709cbdSnorby break; 1768e709cbdSnorby case SHOW_RIB: 1778e709cbdSnorby printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", 1788e709cbdSnorby "Nexthop", "Path Type", "Type", "Cost", "Uptime"); 179c5ba8b41Sderaadt /*FALLTHROUGH*/ 1808e709cbdSnorby case SHOW_RIB_DTAIL: 1818e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, NULL, 0); 1828e709cbdSnorby break; 1838e709cbdSnorby case SHOW_FIB: 1840104e403Sclaudio if (IN6_IS_ADDR_UNSPECIFIED(&res->addr)) 1858e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, 1868e709cbdSnorby &res->flags, sizeof(res->flags)); 1878e709cbdSnorby else 1888e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, 1898e709cbdSnorby &res->addr, sizeof(res->addr)); 1908e709cbdSnorby show_fib_head(); 1918e709cbdSnorby break; 1928e709cbdSnorby case SHOW_FIB_IFACE: 1938e709cbdSnorby if (*res->ifname) 1948e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, 1958e709cbdSnorby res->ifname, sizeof(res->ifname)); 1968e709cbdSnorby else 1978e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, NULL, 0); 1988e709cbdSnorby show_interface_head(); 1998e709cbdSnorby break; 2008e709cbdSnorby case FIB: 2018e709cbdSnorby errx(1, "fib couple|decouple"); 2028e709cbdSnorby break; 2038e709cbdSnorby case FIB_COUPLE: 2048e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, NULL, 0); 2058e709cbdSnorby printf("couple request sent.\n"); 2068e709cbdSnorby done = 1; 2078e709cbdSnorby break; 2088e709cbdSnorby case FIB_DECOUPLE: 2098e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, NULL, 0); 2108e709cbdSnorby printf("decouple request sent.\n"); 2118e709cbdSnorby done = 1; 2128e709cbdSnorby break; 2138e709cbdSnorby case RELOAD: 2148e709cbdSnorby imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, NULL, 0); 2158e709cbdSnorby printf("reload request sent.\n"); 2168e709cbdSnorby done = 1; 2178e709cbdSnorby break; 2188e709cbdSnorby } 2198e709cbdSnorby 2208e709cbdSnorby while (ibuf->w.queued) 2218e709cbdSnorby if (msgbuf_write(&ibuf->w) < 0) 2228e709cbdSnorby err(1, "write error"); 2238e709cbdSnorby 2248e709cbdSnorby while (!done) { 2258e709cbdSnorby if ((n = imsg_read(ibuf)) == -1) 2268e709cbdSnorby errx(1, "imsg_read error"); 2278e709cbdSnorby if (n == 0) 2288e709cbdSnorby errx(1, "pipe closed"); 2298e709cbdSnorby 2308e709cbdSnorby while (!done) { 2318e709cbdSnorby if ((n = imsg_get(ibuf, &imsg)) == -1) 2328e709cbdSnorby errx(1, "imsg_get error"); 2338e709cbdSnorby if (n == 0) 2348e709cbdSnorby break; 2358e709cbdSnorby switch (res->action) { 2368e709cbdSnorby case SHOW: 2378e709cbdSnorby case SHOW_SUM: 2388e709cbdSnorby done = show_summary_msg(&imsg); 2398e709cbdSnorby break; 2408e709cbdSnorby case SHOW_IFACE: 2418e709cbdSnorby done = show_interface_msg(&imsg); 2428e709cbdSnorby break; 2438e709cbdSnorby case SHOW_IFACE_DTAIL: 2448e709cbdSnorby done = show_interface_detail_msg(&imsg); 2458e709cbdSnorby break; 2468e709cbdSnorby case SHOW_NBR: 2478e709cbdSnorby done = show_nbr_msg(&imsg); 2488e709cbdSnorby break; 2498e709cbdSnorby case SHOW_NBR_DTAIL: 2508e709cbdSnorby done = show_nbr_detail_msg(&imsg); 2518e709cbdSnorby break; 2528e709cbdSnorby case SHOW_DB: 2538e709cbdSnorby case SHOW_DBBYAREA: 2548e709cbdSnorby case SHOW_DBSELF: 2558e709cbdSnorby done = show_database_msg(&imsg); 2568e709cbdSnorby break; 2578e709cbdSnorby case SHOW_DBEXT: 2588e709cbdSnorby case SHOW_DBNET: 2598e709cbdSnorby case SHOW_DBRTR: 2608e709cbdSnorby case SHOW_DBSUM: 2618e709cbdSnorby case SHOW_DBASBR: 2628e709cbdSnorby done = show_db_msg_detail(&imsg); 2638e709cbdSnorby break; 2648e709cbdSnorby case SHOW_RIB: 2658e709cbdSnorby done = show_rib_msg(&imsg); 2668e709cbdSnorby break; 2678e709cbdSnorby case SHOW_RIB_DTAIL: 2688e709cbdSnorby done = show_rib_detail_msg(&imsg); 2698e709cbdSnorby break; 2708e709cbdSnorby case SHOW_FIB: 2718e709cbdSnorby done = show_fib_msg(&imsg); 2728e709cbdSnorby break; 2738e709cbdSnorby case SHOW_FIB_IFACE: 2748e709cbdSnorby done = show_fib_interface_msg(&imsg); 2758e709cbdSnorby break; 2768e709cbdSnorby case NONE: 2778e709cbdSnorby case FIB: 2788e709cbdSnorby case FIB_COUPLE: 2798e709cbdSnorby case FIB_DECOUPLE: 2808e709cbdSnorby case RELOAD: 2818e709cbdSnorby break; 2828e709cbdSnorby } 2838e709cbdSnorby imsg_free(&imsg); 2848e709cbdSnorby } 2858e709cbdSnorby } 2868e709cbdSnorby close(ctl_sock); 2878e709cbdSnorby free(ibuf); 2888e709cbdSnorby 2898e709cbdSnorby return (0); 2908e709cbdSnorby } 2918e709cbdSnorby 2928e709cbdSnorby int 2938e709cbdSnorby show_summary_msg(struct imsg *imsg) 2948e709cbdSnorby { 2958e709cbdSnorby struct ctl_sum *sum; 2968e709cbdSnorby struct ctl_sum_area *sumarea; 2978e709cbdSnorby 2988e709cbdSnorby switch (imsg->hdr.type) { 2998e709cbdSnorby case IMSG_CTL_SHOW_SUM: 3008e709cbdSnorby sum = imsg->data; 3018e709cbdSnorby printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); 3028e709cbdSnorby printf("Uptime: %s\n", fmt_timeframe_core(sum->uptime)); 3038e709cbdSnorby 3048e709cbdSnorby printf("SPF delay is %d sec(s), hold time between two SPFs " 3058e709cbdSnorby "is %d sec(s)\n", sum->spf_delay, sum->spf_hold_time); 3068e709cbdSnorby printf("Number of external LSA(s) %d\n", sum->num_ext_lsa); 3078e709cbdSnorby printf("Number of areas attached to this router: %d\n", 3088e709cbdSnorby sum->num_area); 3098e709cbdSnorby break; 3108e709cbdSnorby case IMSG_CTL_SHOW_SUM_AREA: 3118e709cbdSnorby sumarea = imsg->data; 3128e709cbdSnorby printf("\nArea ID: %s\n", inet_ntoa(sumarea->area)); 3138e709cbdSnorby printf(" Number of interfaces in this area: %d\n", 3148e709cbdSnorby sumarea->num_iface); 3158e709cbdSnorby printf(" Number of fully adjacent neighbors in this " 3168e709cbdSnorby "area: %d\n", sumarea->num_adj_nbr); 3178e709cbdSnorby printf(" SPF algorithm executed %d time(s)\n", 3188e709cbdSnorby sumarea->num_spf_calc); 3198e709cbdSnorby printf(" Number LSA(s) %d\n", sumarea->num_lsa); 3208e709cbdSnorby break; 3218e709cbdSnorby case IMSG_CTL_END: 3228e709cbdSnorby printf("\n"); 3238e709cbdSnorby return (1); 3248e709cbdSnorby default: 3258e709cbdSnorby break; 3268e709cbdSnorby } 3278e709cbdSnorby 3288e709cbdSnorby return (0); 3298e709cbdSnorby } 3308e709cbdSnorby 3318e709cbdSnorby int 3328e709cbdSnorby get_ifms_type(int mediatype) 3338e709cbdSnorby { 3348e709cbdSnorby switch (mediatype) { 3358e709cbdSnorby case IFT_ETHER: 3368e709cbdSnorby return (IFM_ETHER); 3378e709cbdSnorby case IFT_FDDI: 3388e709cbdSnorby return (IFM_FDDI); 3398e709cbdSnorby case IFT_CARP: 3408e709cbdSnorby return (IFM_CARP); 3418e709cbdSnorby case IFT_PPP: 3428e709cbdSnorby return (IFM_TDM); 3438e709cbdSnorby default: 3448e709cbdSnorby return (0); 3458e709cbdSnorby } 3468e709cbdSnorby } 3478e709cbdSnorby 3488e709cbdSnorby int 3498e709cbdSnorby show_interface_msg(struct imsg *imsg) 3508e709cbdSnorby { 3518e709cbdSnorby struct ctl_iface *iface; 3528e709cbdSnorby char *netid; 3538e709cbdSnorby 3548e709cbdSnorby switch (imsg->hdr.type) { 3558e709cbdSnorby case IMSG_CTL_SHOW_INTERFACE: 3568e709cbdSnorby iface = imsg->data; 3578e709cbdSnorby 3588e709cbdSnorby if (asprintf(&netid, "%s", log_in6addr(&iface->addr)) == -1) 3598e709cbdSnorby err(1, NULL); 3601fed8bffSnorby printf("%-11s %-29s %-6s %-10s %-10s %s\n", 3618e709cbdSnorby iface->name, netid, if_state_name(iface->state), 3628e709cbdSnorby fmt_timeframe_core(iface->hello_timer), 3638e709cbdSnorby get_linkstate(get_ifms_type(iface->mediatype), 3641fed8bffSnorby iface->linkstate), fmt_timeframe_core(iface->uptime)); 3658e709cbdSnorby free(netid); 3668e709cbdSnorby break; 3678e709cbdSnorby case IMSG_CTL_END: 3688e709cbdSnorby printf("\n"); 3698e709cbdSnorby return (1); 3708e709cbdSnorby default: 3718e709cbdSnorby break; 3728e709cbdSnorby } 3738e709cbdSnorby 3748e709cbdSnorby return (0); 3758e709cbdSnorby } 3768e709cbdSnorby 3778e709cbdSnorby int 3788e709cbdSnorby show_interface_detail_msg(struct imsg *imsg) 3798e709cbdSnorby { 3808e709cbdSnorby struct ctl_iface *iface; 3818e709cbdSnorby 3828e709cbdSnorby switch (imsg->hdr.type) { 3838e709cbdSnorby case IMSG_CTL_SHOW_INTERFACE: 3848e709cbdSnorby iface = imsg->data; 3858e709cbdSnorby printf("\n"); 3868e709cbdSnorby printf("Interface %s, line protocol is %s\n", 3878e709cbdSnorby iface->name, print_link(iface->flags)); 3887aab4200Snorby printf(" Internet address %s ", 3898e709cbdSnorby log_in6addr(&iface->addr)); 3908e709cbdSnorby printf("Area %s\n", inet_ntoa(iface->area)); 3918e709cbdSnorby printf(" Linkstate %s\n", 3928e709cbdSnorby get_linkstate(get_ifms_type(iface->mediatype), 3938e709cbdSnorby iface->linkstate)); 3948e709cbdSnorby printf(" Router ID %s, network type %s, cost: %d\n", 3958e709cbdSnorby inet_ntoa(iface->rtr_id), 3968e709cbdSnorby if_type_name(iface->type), iface->metric); 3978e709cbdSnorby printf(" Transmit delay is %d sec(s), state %s, priority %d\n", 3988e709cbdSnorby iface->transmit_delay, if_state_name(iface->state), 3998e709cbdSnorby iface->priority); 4007aab4200Snorby printf(" Designated Router (ID) %s\n", 4018e709cbdSnorby inet_ntoa(iface->dr_id)); 4027aab4200Snorby printf(" Interface address %s\n", 4037aab4200Snorby log_in6addr(&iface->dr_addr)); 4047aab4200Snorby printf(" Backup Designated Router (ID) %s\n", 4058e709cbdSnorby inet_ntoa(iface->bdr_id)); 4067aab4200Snorby printf(" Interface address %s\n", 4077aab4200Snorby log_in6addr(&iface->bdr_addr)); 4088e709cbdSnorby printf(" Timer intervals configured, " 4098e709cbdSnorby "hello %d, dead %d, wait %d, retransmit %d\n", 4108e709cbdSnorby iface->hello_interval, iface->dead_interval, 4118e709cbdSnorby iface->dead_interval, iface->rxmt_interval); 4128e709cbdSnorby if (iface->passive) 4138e709cbdSnorby printf(" Passive interface (No Hellos)\n"); 4148e709cbdSnorby else if (iface->hello_timer < 0) 4158e709cbdSnorby printf(" Hello timer not running\n"); 4168e709cbdSnorby else 4178e709cbdSnorby printf(" Hello timer due in %s\n", 4188e709cbdSnorby fmt_timeframe_core(iface->hello_timer)); 4198e709cbdSnorby printf(" Uptime %s\n", fmt_timeframe_core(iface->uptime)); 4208e709cbdSnorby printf(" Neighbor count is %d, adjacent neighbor count is " 4218e709cbdSnorby "%d\n", iface->nbr_cnt, iface->adj_cnt); 4228e709cbdSnorby break; 4238e709cbdSnorby case IMSG_CTL_END: 4248e709cbdSnorby printf("\n"); 4258e709cbdSnorby return (1); 4268e709cbdSnorby default: 4278e709cbdSnorby break; 4288e709cbdSnorby } 4298e709cbdSnorby 4308e709cbdSnorby return (0); 4318e709cbdSnorby } 4328e709cbdSnorby 4338e709cbdSnorby const char * 4348e709cbdSnorby print_link(int state) 4358e709cbdSnorby { 4368e709cbdSnorby if (state & IFF_UP) 4378e709cbdSnorby return ("UP"); 4388e709cbdSnorby else 4398e709cbdSnorby return ("DOWN"); 4408e709cbdSnorby } 4418e709cbdSnorby 4428e709cbdSnorby #define TF_BUFS 8 4438e709cbdSnorby #define TF_LEN 9 4448e709cbdSnorby 4458e709cbdSnorby const char * 4468e709cbdSnorby fmt_timeframe(time_t t) 4478e709cbdSnorby { 4488e709cbdSnorby if (t == 0) 4498e709cbdSnorby return ("Never"); 4508e709cbdSnorby else 4518e709cbdSnorby return (fmt_timeframe_core(time(NULL) - t)); 4528e709cbdSnorby } 4538e709cbdSnorby 4548e709cbdSnorby const char * 4558e709cbdSnorby fmt_timeframe_core(time_t t) 4568e709cbdSnorby { 4578e709cbdSnorby char *buf; 4588e709cbdSnorby static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 4598e709cbdSnorby static int idx = 0; 460db93f2f1Sderaadt unsigned int sec, min, hrs, day, week; 4618e709cbdSnorby 4628e709cbdSnorby if (t == 0) 4638e709cbdSnorby return ("00:00:00"); 4648e709cbdSnorby 4658e709cbdSnorby buf = tfbuf[idx++]; 4668e709cbdSnorby if (idx == TF_BUFS) 4678e709cbdSnorby idx = 0; 4688e709cbdSnorby 4698e709cbdSnorby week = t; 4708e709cbdSnorby 4718e709cbdSnorby sec = week % 60; 4728e709cbdSnorby week /= 60; 4738e709cbdSnorby min = week % 60; 4748e709cbdSnorby week /= 60; 4758e709cbdSnorby hrs = week % 24; 4768e709cbdSnorby week /= 24; 4778e709cbdSnorby day = week % 7; 4788e709cbdSnorby week /= 7; 4798e709cbdSnorby 4808e709cbdSnorby if (week > 0) 4818e709cbdSnorby snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs); 4828e709cbdSnorby else if (day > 0) 4838e709cbdSnorby snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 4848e709cbdSnorby else 4858e709cbdSnorby snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 4868e709cbdSnorby 4878e709cbdSnorby return (buf); 4888e709cbdSnorby } 4898e709cbdSnorby 4908e709cbdSnorby const char * 4918e709cbdSnorby log_id(u_int32_t id) 4928e709cbdSnorby { 4938e709cbdSnorby static char buf[48]; 4948e709cbdSnorby struct in_addr addr; 4958e709cbdSnorby 4968e709cbdSnorby addr.s_addr = id; 4978e709cbdSnorby 4988e709cbdSnorby if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 4998e709cbdSnorby return ("?"); 5008e709cbdSnorby else 5018e709cbdSnorby return (buf); 5028e709cbdSnorby } 5038e709cbdSnorby 5048e709cbdSnorby const char * 5058e709cbdSnorby log_adv_rtr(u_int32_t adv_rtr) 5068e709cbdSnorby { 5078e709cbdSnorby static char buf[48]; 5088e709cbdSnorby struct in_addr addr; 5098e709cbdSnorby 5108e709cbdSnorby addr.s_addr = adv_rtr; 5118e709cbdSnorby 5128e709cbdSnorby if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL) 5138e709cbdSnorby return ("?"); 5148e709cbdSnorby else 5158e709cbdSnorby return (buf); 5168e709cbdSnorby } 5178e709cbdSnorby 5188e709cbdSnorby void 519*4fabe8f9Snorby show_database_head(struct in_addr aid, u_int16_t type) 5208e709cbdSnorby { 5218e709cbdSnorby char *header, *format; 5228e709cbdSnorby 5238e709cbdSnorby switch (type) { 524*4fabe8f9Snorby case LSA_TYPE_LINK: 525*4fabe8f9Snorby format = "Link Link States"; 526*4fabe8f9Snorby break; 5278e709cbdSnorby case LSA_TYPE_ROUTER: 5288e709cbdSnorby format = "Router Link States"; 5298e709cbdSnorby break; 5308e709cbdSnorby case LSA_TYPE_NETWORK: 5318e709cbdSnorby format = "Net Link States"; 5328e709cbdSnorby break; 533*4fabe8f9Snorby case LSA_TYPE_INTER_A_PREFIX: 534*4fabe8f9Snorby format = "Inter Area Prefix Link States"; 5358e709cbdSnorby break; 536*4fabe8f9Snorby case LSA_TYPE_INTER_A_ROUTER: 537*4fabe8f9Snorby format = "Inter Area Router Link States"; 538*4fabe8f9Snorby break; 539*4fabe8f9Snorby case LSA_TYPE_INTRA_A_PREFIX: 540*4fabe8f9Snorby format = "Router Link States"; 5418e709cbdSnorby break; 5428e709cbdSnorby case LSA_TYPE_EXTERNAL: 5438e709cbdSnorby format = NULL; 5448e709cbdSnorby if ((header = strdup("Type-5 AS External Link States")) == NULL) 5458e709cbdSnorby err(1, NULL); 5468e709cbdSnorby break; 5478e709cbdSnorby default: 5488e709cbdSnorby errx(1, "unknown LSA type"); 5498e709cbdSnorby } 5508e709cbdSnorby if (type != LSA_TYPE_EXTERNAL) 5518e709cbdSnorby if (asprintf(&header, "%s (Area %s)", format, 5528e709cbdSnorby inet_ntoa(aid)) == -1) 5538e709cbdSnorby err(1, NULL); 5548e709cbdSnorby 5558e709cbdSnorby printf("\n%-15s %s\n\n", "", header); 5568e709cbdSnorby free(header); 5578e709cbdSnorby } 5588e709cbdSnorby 5598e709cbdSnorby int 5608e709cbdSnorby show_database_msg(struct imsg *imsg) 5618e709cbdSnorby { 5628e709cbdSnorby static struct in_addr area_id; 5638e709cbdSnorby static u_int8_t lasttype; 5648e709cbdSnorby struct area *area; 5658e709cbdSnorby struct lsa_hdr *lsa; 5668e709cbdSnorby 5678e709cbdSnorby switch (imsg->hdr.type) { 5688e709cbdSnorby case IMSG_CTL_SHOW_DATABASE: 5698e709cbdSnorby case IMSG_CTL_SHOW_DB_SELF: 5708e709cbdSnorby lsa = imsg->data; 5718e709cbdSnorby if (lsa->type != lasttype) { 5728e709cbdSnorby show_database_head(area_id, lsa->type); 5738e709cbdSnorby printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID", 5748e709cbdSnorby "Adv Router", "Age", "Seq#", "Checksum"); 5758e709cbdSnorby } 5768e709cbdSnorby printf("%-15s %-15s %-4d 0x%08x 0x%04x\n", 5778e709cbdSnorby log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr), 5788e709cbdSnorby ntohs(lsa->age), ntohl(lsa->seq_num), 5798e709cbdSnorby ntohs(lsa->ls_chksum)); 5808e709cbdSnorby lasttype = lsa->type; 5818e709cbdSnorby break; 5828e709cbdSnorby case IMSG_CTL_AREA: 5838e709cbdSnorby area = imsg->data; 5848e709cbdSnorby area_id = area->id; 5858e709cbdSnorby lasttype = 0; 5868e709cbdSnorby break; 5878e709cbdSnorby case IMSG_CTL_END: 5888e709cbdSnorby printf("\n"); 5898e709cbdSnorby return (1); 5908e709cbdSnorby default: 5918e709cbdSnorby break; 5928e709cbdSnorby } 5938e709cbdSnorby 5948e709cbdSnorby return (0); 5958e709cbdSnorby } 5968e709cbdSnorby 5978e709cbdSnorby char * 598*4fabe8f9Snorby print_ls_type(u_int16_t type) 5998e709cbdSnorby { 6008e709cbdSnorby switch (type) { 601*4fabe8f9Snorby case LSA_TYPE_LINK: 602*4fabe8f9Snorby return ("Link"); 6038e709cbdSnorby case LSA_TYPE_ROUTER: 6048e709cbdSnorby return ("Router"); 6058e709cbdSnorby case LSA_TYPE_NETWORK: 6068e709cbdSnorby return ("Network"); 607*4fabe8f9Snorby case LSA_TYPE_INTER_A_PREFIX: 608*4fabe8f9Snorby return ("Inter Area (Prefix)"); 609*4fabe8f9Snorby case LSA_TYPE_INTER_A_ROUTER: 610*4fabe8f9Snorby return ("Inter Area (Router)"); 611*4fabe8f9Snorby case LSA_TYPE_INTRA_A_PREFIX: 612*4fabe8f9Snorby return ("Intra Area (Prefix)"); 6138e709cbdSnorby case LSA_TYPE_EXTERNAL: 6148e709cbdSnorby return ("AS External"); 6158e709cbdSnorby default: 6168e709cbdSnorby return ("Unknown"); 6178e709cbdSnorby } 6188e709cbdSnorby } 6198e709cbdSnorby 6208e709cbdSnorby void 6218e709cbdSnorby show_db_hdr_msg_detail(struct lsa_hdr *lsa) 6228e709cbdSnorby { 6238e709cbdSnorby printf("LS age: %d\n", ntohs(lsa->age)); 6248e709cbdSnorby //XXX printf("Options: %s\n", print_ospf_options(lsa->opts)); 6258e709cbdSnorby printf("LS Type: %s\n", print_ls_type(lsa->type)); 6268e709cbdSnorby 6278e709cbdSnorby switch (lsa->type) { 628*4fabe8f9Snorby case LSA_TYPE_LINK: 629*4fabe8f9Snorby printf("Link State ID: %s\n", log_id(lsa->ls_id)); 630*4fabe8f9Snorby break; 6318e709cbdSnorby case LSA_TYPE_ROUTER: 6328e709cbdSnorby printf("Link State ID: %s\n", log_id(lsa->ls_id)); 6338e709cbdSnorby break; 6348e709cbdSnorby case LSA_TYPE_NETWORK: 6358e709cbdSnorby printf("Link State ID: %s (address of Designated Router)\n", 6368e709cbdSnorby log_id(lsa->ls_id)); 6378e709cbdSnorby break; 638*4fabe8f9Snorby case LSA_TYPE_INTER_A_PREFIX: 6398e709cbdSnorby printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id)); 6408e709cbdSnorby break; 641*4fabe8f9Snorby case LSA_TYPE_INTER_A_ROUTER: 6428e709cbdSnorby printf("Link State ID: %s (ASBR Router ID)\n", 6438e709cbdSnorby log_id(lsa->ls_id)); 6448e709cbdSnorby break; 645*4fabe8f9Snorby case LSA_TYPE_INTRA_A_PREFIX: 646*4fabe8f9Snorby printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id)); 647*4fabe8f9Snorby break; 6488e709cbdSnorby case LSA_TYPE_EXTERNAL: 6498e709cbdSnorby printf("Link State ID: %s (External Network Number)\n", 6508e709cbdSnorby log_id(lsa->ls_id)); 6518e709cbdSnorby break; 6528e709cbdSnorby } 6538e709cbdSnorby 6548e709cbdSnorby printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr)); 6558e709cbdSnorby printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num)); 6568e709cbdSnorby printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum)); 6578e709cbdSnorby printf("Length: %d\n", ntohs(lsa->len)); 6588e709cbdSnorby } 6598e709cbdSnorby 6608e709cbdSnorby char * 6618e709cbdSnorby print_rtr_link_type(u_int8_t type) 6628e709cbdSnorby { 6638e709cbdSnorby switch (type) { 6648e709cbdSnorby case LINK_TYPE_POINTTOPOINT: 6658e709cbdSnorby return ("Point-to-Point"); 6668e709cbdSnorby case LINK_TYPE_TRANSIT_NET: 6678e709cbdSnorby return ("Transit Network"); 6688e709cbdSnorby case LINK_TYPE_STUB_NET: 6698e709cbdSnorby return ("Stub Network"); 6708e709cbdSnorby case LINK_TYPE_VIRTUAL: 6718e709cbdSnorby return ("Virtual Link"); 6728e709cbdSnorby default: 6738e709cbdSnorby return ("Unknown"); 6748e709cbdSnorby } 6758e709cbdSnorby } 6768e709cbdSnorby 6778e709cbdSnorby const char * 6788e709cbdSnorby print_ospf_flags(u_int8_t opts) 6798e709cbdSnorby { 6808e709cbdSnorby static char optbuf[32]; 6818e709cbdSnorby 6828e709cbdSnorby snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s", 6838e709cbdSnorby opts & OSPF_RTR_V ? "V" : "-", 6848e709cbdSnorby opts & OSPF_RTR_E ? "E" : "-", 6858e709cbdSnorby opts & OSPF_RTR_B ? "B" : "-"); 6868e709cbdSnorby return (optbuf); 6878e709cbdSnorby } 6888e709cbdSnorby 6898e709cbdSnorby int 6908e709cbdSnorby show_db_msg_detail(struct imsg *imsg) 6918e709cbdSnorby { 6928e709cbdSnorby static struct in_addr area_id; 6938e709cbdSnorby static u_int8_t lasttype; 6948e709cbdSnorby struct in_addr addr, data; 6958e709cbdSnorby struct area *area; 6968e709cbdSnorby struct lsa *lsa; 6978e709cbdSnorby struct lsa_rtr_link *rtr_link; 6988e709cbdSnorby struct lsa_asext *asext; 6998e709cbdSnorby u_int16_t i, nlinks, off; 7008e709cbdSnorby 7018e709cbdSnorby /* XXX sanity checks! */ 7028e709cbdSnorby 7038e709cbdSnorby switch (imsg->hdr.type) { 7048e709cbdSnorby case IMSG_CTL_SHOW_DB_EXT: 7058e709cbdSnorby lsa = imsg->data; 7068e709cbdSnorby if (lsa->hdr.type != lasttype) 7078e709cbdSnorby show_database_head(area_id, lsa->hdr.type); 7088e709cbdSnorby show_db_hdr_msg_detail(&lsa->hdr); 7098e709cbdSnorby addr.s_addr = lsa->data.asext.mask; 7108e709cbdSnorby printf("Network Mask: %s\n", inet_ntoa(addr)); 7118e709cbdSnorby 7128e709cbdSnorby asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr)); 7138e709cbdSnorby 7148e709cbdSnorby printf(" Metric type: "); 7158e709cbdSnorby if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG) 7168e709cbdSnorby printf("2\n"); 7178e709cbdSnorby else 7188e709cbdSnorby printf("1\n"); 7198e709cbdSnorby printf(" Metric: %d\n", ntohl(asext->metric) 7208e709cbdSnorby & LSA_METRIC_MASK); 7218e709cbdSnorby addr.s_addr = asext->fw_addr; 7228e709cbdSnorby printf(" Forwarding Address: %s\n", inet_ntoa(addr)); 7238e709cbdSnorby printf(" External Route Tag: %d\n\n", ntohl(asext->ext_tag)); 7248e709cbdSnorby 7258e709cbdSnorby lasttype = lsa->hdr.type; 7268e709cbdSnorby break; 7278e709cbdSnorby case IMSG_CTL_SHOW_DB_NET: 7288e709cbdSnorby lsa = imsg->data; 7298e709cbdSnorby if (lsa->hdr.type != lasttype) 7308e709cbdSnorby show_database_head(area_id, lsa->hdr.type); 7318e709cbdSnorby show_db_hdr_msg_detail(&lsa->hdr); 7328e709cbdSnorby addr.s_addr = lsa->data.net.mask; 7338e709cbdSnorby printf("Network Mask: %s\n", inet_ntoa(addr)); 7348e709cbdSnorby 7358e709cbdSnorby nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr) 7368e709cbdSnorby - sizeof(u_int32_t)) / sizeof(struct lsa_net_link); 7378e709cbdSnorby off = sizeof(lsa->hdr) + sizeof(u_int32_t); 7388e709cbdSnorby 7398e709cbdSnorby for (i = 0; i < nlinks; i++) { 7408e709cbdSnorby addr.s_addr = lsa->data.net.att_rtr[i]; 7418e709cbdSnorby printf(" Attached Router: %s\n", inet_ntoa(addr)); 7428e709cbdSnorby } 7438e709cbdSnorby 7448e709cbdSnorby printf("\n"); 7458e709cbdSnorby lasttype = lsa->hdr.type; 7468e709cbdSnorby break; 7478e709cbdSnorby case IMSG_CTL_SHOW_DB_RTR: 7488e709cbdSnorby lsa = imsg->data; 7498e709cbdSnorby if (lsa->hdr.type != lasttype) 7508e709cbdSnorby show_database_head(area_id, lsa->hdr.type); 7518e709cbdSnorby show_db_hdr_msg_detail(&lsa->hdr); 7528e709cbdSnorby printf("Flags: %s\n", print_ospf_flags(lsa->data.rtr.flags)); 7538e709cbdSnorby nlinks = ntohs(lsa->data.rtr.nlinks); 7548e709cbdSnorby printf("Number of Links: %d\n\n", nlinks); 7558e709cbdSnorby 7568e709cbdSnorby off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr); 7578e709cbdSnorby 7588e709cbdSnorby for (i = 0; i < nlinks; i++) { 7598e709cbdSnorby rtr_link = (struct lsa_rtr_link *)((char *)lsa + off); 7608e709cbdSnorby 7618e709cbdSnorby printf(" Link connected to: %s\n", 7628e709cbdSnorby print_rtr_link_type(rtr_link->type)); 7638e709cbdSnorby 7648e709cbdSnorby addr.s_addr = rtr_link->id; 7658e709cbdSnorby data.s_addr = rtr_link->data; 7668e709cbdSnorby 7678e709cbdSnorby switch (rtr_link->type) { 7688e709cbdSnorby case LINK_TYPE_POINTTOPOINT: 7698e709cbdSnorby case LINK_TYPE_VIRTUAL: 7708e709cbdSnorby printf(" Link ID (Neighbors Router ID):" 7718e709cbdSnorby " %s\n", inet_ntoa(addr)); 7728e709cbdSnorby printf(" Link Data (Router Interface " 7738e709cbdSnorby "address): %s\n", inet_ntoa(data)); 7748e709cbdSnorby break; 7758e709cbdSnorby case LINK_TYPE_TRANSIT_NET: 7768e709cbdSnorby printf(" Link ID (Designated Router " 7778e709cbdSnorby "address): %s\n", inet_ntoa(addr)); 7788e709cbdSnorby printf(" Link Data (Router Interface " 7798e709cbdSnorby "address): %s\n", inet_ntoa(data)); 7808e709cbdSnorby break; 7818e709cbdSnorby case LINK_TYPE_STUB_NET: 7828e709cbdSnorby printf(" Link ID (Network ID): %s\n", 7838e709cbdSnorby inet_ntoa(addr)); 7848e709cbdSnorby printf(" Link Data (Network Mask): %s\n", 7858e709cbdSnorby inet_ntoa(data)); 7868e709cbdSnorby break; 7878e709cbdSnorby default: 7888e709cbdSnorby printf(" Link ID (Unknown): %s\n", 7898e709cbdSnorby inet_ntoa(addr)); 7908e709cbdSnorby printf(" Link Data (Unknown): %s\n", 7918e709cbdSnorby inet_ntoa(data)); 7928e709cbdSnorby break; 7938e709cbdSnorby } 7948e709cbdSnorby 7958e709cbdSnorby printf(" Metric: %d\n\n", ntohs(rtr_link->metric)); 7968e709cbdSnorby 7978e709cbdSnorby off += sizeof(struct lsa_rtr_link) + 7988e709cbdSnorby rtr_link->num_tos * sizeof(u_int32_t); 7998e709cbdSnorby } 8008e709cbdSnorby 8018e709cbdSnorby lasttype = lsa->hdr.type; 8028e709cbdSnorby break; 8038e709cbdSnorby case IMSG_CTL_SHOW_DB_SUM: 8048e709cbdSnorby case IMSG_CTL_SHOW_DB_ASBR: 8058e709cbdSnorby lsa = imsg->data; 8068e709cbdSnorby if (lsa->hdr.type != lasttype) 8078e709cbdSnorby show_database_head(area_id, lsa->hdr.type); 8088e709cbdSnorby show_db_hdr_msg_detail(&lsa->hdr); 8098e709cbdSnorby addr.s_addr = lsa->data.sum.mask; 8108e709cbdSnorby printf("Network Mask: %s\n", inet_ntoa(addr)); 8118e709cbdSnorby printf("Metric: %d\n\n", ntohl(lsa->data.sum.metric) & 8128e709cbdSnorby LSA_METRIC_MASK); 8138e709cbdSnorby lasttype = lsa->hdr.type; 8148e709cbdSnorby break; 8158e709cbdSnorby case IMSG_CTL_AREA: 8168e709cbdSnorby area = imsg->data; 8178e709cbdSnorby area_id = area->id; 8188e709cbdSnorby lasttype = 0; 8198e709cbdSnorby break; 8208e709cbdSnorby case IMSG_CTL_END: 8218e709cbdSnorby return (1); 8228e709cbdSnorby default: 8238e709cbdSnorby break; 8248e709cbdSnorby } 8258e709cbdSnorby 8268e709cbdSnorby return (0); 8278e709cbdSnorby } 8288e709cbdSnorby 8298e709cbdSnorby int 8308e709cbdSnorby show_nbr_msg(struct imsg *imsg) 8318e709cbdSnorby { 8328e709cbdSnorby struct ctl_nbr *nbr; 8338e709cbdSnorby char *state; 8348e709cbdSnorby 8358e709cbdSnorby switch (imsg->hdr.type) { 8368e709cbdSnorby case IMSG_CTL_SHOW_NBR: 8378e709cbdSnorby nbr = imsg->data; 8388e709cbdSnorby if (asprintf(&state, "%s/%s", nbr_state_name(nbr->nbr_state), 8398e709cbdSnorby if_state_name(nbr->iface_state)) == -1) 8408e709cbdSnorby err(1, NULL); 841558ada41Snorby printf("%-15s %-3d %-12s %-10s", inet_ntoa(nbr->id), 8428e709cbdSnorby nbr->priority, state, fmt_timeframe_core(nbr->dead_timer)); 843558ada41Snorby printf("%-11s %s\n", nbr->name, 8448e709cbdSnorby nbr->uptime == 0 ? "-" : fmt_timeframe_core(nbr->uptime)); 8458e709cbdSnorby free(state); 8468e709cbdSnorby break; 8478e709cbdSnorby case IMSG_CTL_END: 8488e709cbdSnorby printf("\n"); 8498e709cbdSnorby return (1); 8508e709cbdSnorby default: 8518e709cbdSnorby break; 8528e709cbdSnorby } 8538e709cbdSnorby 8548e709cbdSnorby return (0); 8558e709cbdSnorby } 8568e709cbdSnorby 8578e709cbdSnorby const char * 8588e709cbdSnorby print_ospf_options(u_int8_t opts) 8598e709cbdSnorby { 8608e709cbdSnorby static char optbuf[32]; 8618e709cbdSnorby 8628e709cbdSnorby snprintf(optbuf, sizeof(optbuf), "*|*|%s|%s|%s|%s|%s|%s", 8638e709cbdSnorby opts & OSPF_OPTION_DC ? "DC" : "-", 8648e709cbdSnorby opts & OSPF_OPTION_R ? "R" : "-", 8658e709cbdSnorby opts & OSPF_OPTION_N ? "N" : "-", 8668e709cbdSnorby opts & OSPF_OPTION_MC ? "MC" : "-", 8678e709cbdSnorby opts & OSPF_OPTION_E ? "E" : "-", 8688e709cbdSnorby opts & OSPF_OPTION_V6 ? "V6" : "-"); 8698e709cbdSnorby return (optbuf); 8708e709cbdSnorby } 8718e709cbdSnorby 8728e709cbdSnorby int 8738e709cbdSnorby show_nbr_detail_msg(struct imsg *imsg) 8748e709cbdSnorby { 8758e709cbdSnorby struct ctl_nbr *nbr; 8768e709cbdSnorby 8778e709cbdSnorby switch (imsg->hdr.type) { 8788e709cbdSnorby case IMSG_CTL_SHOW_NBR: 8798e709cbdSnorby nbr = imsg->data; 8808e709cbdSnorby printf("\nNeighbor %s, ", inet_ntoa(nbr->id)); 8818e709cbdSnorby printf("interface address %s\n", log_in6addr(&nbr->addr)); 8828e709cbdSnorby printf(" Area %s, interface %s\n", inet_ntoa(nbr->area), 8838e709cbdSnorby nbr->name); 8848e709cbdSnorby printf(" Neighbor priority is %d, " 8858e709cbdSnorby "State is %s, %d state changes\n", 8868e709cbdSnorby nbr->priority, nbr_state_name(nbr->nbr_state), 8878e709cbdSnorby nbr->state_chng_cnt); 8888e709cbdSnorby printf(" DR is %s, ", inet_ntoa(nbr->dr)); 8898e709cbdSnorby printf("BDR is %s\n", inet_ntoa(nbr->bdr)); 8908e709cbdSnorby printf(" Options %s\n", print_ospf_options(nbr->options)); 8918e709cbdSnorby printf(" Dead timer due in %s\n", 8928e709cbdSnorby fmt_timeframe_core(nbr->dead_timer)); 8938e709cbdSnorby printf(" Uptime %s\n", fmt_timeframe_core(nbr->uptime)); 8948e709cbdSnorby printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt); 8958e709cbdSnorby printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt); 8968e709cbdSnorby printf(" Link State Retransmission List %d\n", 8978e709cbdSnorby nbr->ls_retrans_lst_cnt); 8988e709cbdSnorby break; 8998e709cbdSnorby case IMSG_CTL_END: 9008e709cbdSnorby printf("\n"); 9018e709cbdSnorby return (1); 9028e709cbdSnorby default: 9038e709cbdSnorby break; 9048e709cbdSnorby } 9058e709cbdSnorby 9068e709cbdSnorby return (0); 9078e709cbdSnorby } 9088e709cbdSnorby 9098e709cbdSnorby int 9108e709cbdSnorby show_rib_msg(struct imsg *imsg) 9118e709cbdSnorby { 9128e709cbdSnorby struct ctl_rt *rt; 9138e709cbdSnorby char *dstnet; 9148e709cbdSnorby 9158e709cbdSnorby switch (imsg->hdr.type) { 9168e709cbdSnorby case IMSG_CTL_SHOW_RIB: 9178e709cbdSnorby rt = imsg->data; 9188e709cbdSnorby switch (rt->d_type) { 9198e709cbdSnorby case DT_NET: 9200104e403Sclaudio if (asprintf(&dstnet, "%s/%d", log_in6addr(&rt->prefix), 9218e709cbdSnorby rt->prefixlen) == -1) 9228e709cbdSnorby err(1, NULL); 9238e709cbdSnorby break; 9248e709cbdSnorby case DT_RTR: 9258e709cbdSnorby if (asprintf(&dstnet, "%s", 9260104e403Sclaudio log_in6addr(&rt->prefix)) == -1) 9278e709cbdSnorby err(1, NULL); 9288e709cbdSnorby break; 9298e709cbdSnorby default: 9308e709cbdSnorby errx(1, "Invalid route type"); 9318e709cbdSnorby } 9328e709cbdSnorby 9338e709cbdSnorby printf("%-20s %-17s %-12s %-9s %-7d %s\n", dstnet, 9340104e403Sclaudio log_in6addr(&rt->nexthop), path_type_name(rt->p_type), 9358e709cbdSnorby dst_type_name(rt->d_type), rt->cost, 9368e709cbdSnorby rt->uptime == 0 ? "-" : fmt_timeframe_core(rt->uptime)); 9378e709cbdSnorby free(dstnet); 9388e709cbdSnorby break; 9398e709cbdSnorby case IMSG_CTL_END: 9408e709cbdSnorby printf("\n"); 9418e709cbdSnorby return (1); 9428e709cbdSnorby default: 9438e709cbdSnorby break; 9448e709cbdSnorby } 9458e709cbdSnorby 9468e709cbdSnorby return (0); 9478e709cbdSnorby } 9488e709cbdSnorby 9498e709cbdSnorby void 9508e709cbdSnorby show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type) 9518e709cbdSnorby { 9528e709cbdSnorby char *header, *format, *format2; 9538e709cbdSnorby 9548e709cbdSnorby switch (p_type) { 9558e709cbdSnorby case PT_INTRA_AREA: 9568e709cbdSnorby case PT_INTER_AREA: 9578e709cbdSnorby switch (d_type) { 9588e709cbdSnorby case DT_NET: 9598e709cbdSnorby format = "Network Routing Table"; 9608e709cbdSnorby format2 = ""; 9618e709cbdSnorby break; 9628e709cbdSnorby case DT_RTR: 9638e709cbdSnorby format = "Router Routing Table"; 9648e709cbdSnorby format2 = "Type"; 9658e709cbdSnorby break; 9668e709cbdSnorby default: 9678e709cbdSnorby errx(1, "unknown route type"); 9688e709cbdSnorby } 9698e709cbdSnorby break; 9708e709cbdSnorby case PT_TYPE1_EXT: 9718e709cbdSnorby case PT_TYPE2_EXT: 9728e709cbdSnorby format = NULL; 9738e709cbdSnorby format2 = "Cost 2"; 9748e709cbdSnorby if ((header = strdup("External Routing Table")) == NULL) 9758e709cbdSnorby err(1, NULL); 9768e709cbdSnorby break; 9778e709cbdSnorby default: 9788e709cbdSnorby errx(1, "unknown route type"); 9798e709cbdSnorby } 9808e709cbdSnorby 9818e709cbdSnorby if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT) 9828e709cbdSnorby if (asprintf(&header, "%s (Area %s)", format, 9838e709cbdSnorby inet_ntoa(aid)) == -1) 9848e709cbdSnorby err(1, NULL); 9858e709cbdSnorby 9868e709cbdSnorby printf("\n%-18s %s\n", "", header); 9878e709cbdSnorby free(header); 9888e709cbdSnorby 9898e709cbdSnorby printf("\n%-18s %-15s %-15s %-12s %-7s %-7s\n", "Destination", 9908e709cbdSnorby "Nexthop", "Adv Router", "Path type", "Cost", format2); 9918e709cbdSnorby } 9928e709cbdSnorby 9938e709cbdSnorby const char * 9948e709cbdSnorby print_ospf_rtr_flags(u_int8_t opts) 9958e709cbdSnorby { 9968e709cbdSnorby static char optbuf[32]; 9978e709cbdSnorby 9988e709cbdSnorby snprintf(optbuf, sizeof(optbuf), "%s%s%s", 9998e709cbdSnorby opts & OSPF_RTR_E ? "AS" : "", 10008e709cbdSnorby opts & OSPF_RTR_E && opts & OSPF_RTR_B ? "+" : "", 10018e709cbdSnorby opts & OSPF_RTR_B ? "ABR" : ""); 10028e709cbdSnorby return (optbuf); 10038e709cbdSnorby } 10048e709cbdSnorby 10058e709cbdSnorby int 10068e709cbdSnorby show_rib_detail_msg(struct imsg *imsg) 10078e709cbdSnorby { 10088e709cbdSnorby static struct in_addr area_id; 10098e709cbdSnorby struct ctl_rt *rt; 10108e709cbdSnorby struct area *area; 10118e709cbdSnorby char *dstnet; 10128e709cbdSnorby static u_int8_t lasttype; 10138e709cbdSnorby 10148e709cbdSnorby switch (imsg->hdr.type) { 10158e709cbdSnorby case IMSG_CTL_SHOW_RIB: 10168e709cbdSnorby rt = imsg->data; 10178e709cbdSnorby 10188e709cbdSnorby switch (rt->p_type) { 10198e709cbdSnorby case PT_INTRA_AREA: 10208e709cbdSnorby case PT_INTER_AREA: 10218e709cbdSnorby switch (rt->d_type) { 10228e709cbdSnorby case DT_NET: 10238e709cbdSnorby if (lasttype != RIB_NET) 10248e709cbdSnorby show_rib_head(rt->area, rt->d_type, 10258e709cbdSnorby rt->p_type); 10268e709cbdSnorby if (asprintf(&dstnet, "%s/%d", 10270104e403Sclaudio log_in6addr(&rt->prefix), 10280104e403Sclaudio rt->prefixlen) == -1) 10298e709cbdSnorby err(1, NULL); 10308e709cbdSnorby lasttype = RIB_NET; 10318e709cbdSnorby break; 10328e709cbdSnorby case DT_RTR: 10338e709cbdSnorby if (lasttype != RIB_RTR) 10348e709cbdSnorby show_rib_head(rt->area, rt->d_type, 10358e709cbdSnorby rt->p_type); 10368e709cbdSnorby if (asprintf(&dstnet, "%s", 10370104e403Sclaudio log_in6addr(&rt->prefix)) == -1) 10388e709cbdSnorby err(1, NULL); 10398e709cbdSnorby lasttype = RIB_RTR; 10408e709cbdSnorby break; 10418e709cbdSnorby default: 10428e709cbdSnorby errx(1, "unknown route type"); 10438e709cbdSnorby } 10440104e403Sclaudio printf("%-18s %-15s ", dstnet, 10450104e403Sclaudio log_in6addr(&rt->nexthop)); 10468e709cbdSnorby printf("%-15s %-12s %-7d", inet_ntoa(rt->adv_rtr), 10478e709cbdSnorby path_type_name(rt->p_type), rt->cost); 10488e709cbdSnorby free(dstnet); 10498e709cbdSnorby 10508e709cbdSnorby if (rt->d_type == DT_RTR) 10518e709cbdSnorby printf(" %-7s", 10528e709cbdSnorby print_ospf_rtr_flags(rt->flags)); 10538e709cbdSnorby 10548e709cbdSnorby printf("\n"); 10558e709cbdSnorby break; 10568e709cbdSnorby case PT_TYPE1_EXT: 10578e709cbdSnorby case PT_TYPE2_EXT: 10588e709cbdSnorby if (lasttype != RIB_EXT) 10598e709cbdSnorby show_rib_head(rt->area, rt->d_type, rt->p_type); 10608e709cbdSnorby 10618e709cbdSnorby if (asprintf(&dstnet, "%s/%d", 10620104e403Sclaudio log_in6addr(&rt->prefix), rt->prefixlen) == -1) 10638e709cbdSnorby err(1, NULL); 10648e709cbdSnorby 10650104e403Sclaudio printf("%-18s %-15s ", dstnet, 10660104e403Sclaudio log_in6addr(&rt->nexthop)); 10678e709cbdSnorby printf("%-15s %-12s %-7d %-7d\n", 10688e709cbdSnorby inet_ntoa(rt->adv_rtr), path_type_name(rt->p_type), 10698e709cbdSnorby rt->cost, rt->cost2); 10708e709cbdSnorby 10718e709cbdSnorby lasttype = RIB_EXT; 10728e709cbdSnorby break; 10738e709cbdSnorby default: 10748e709cbdSnorby errx(1, "unknown route type"); 10758e709cbdSnorby } 10768e709cbdSnorby break; 10778e709cbdSnorby case IMSG_CTL_AREA: 10788e709cbdSnorby area = imsg->data; 10798e709cbdSnorby area_id = area->id; 10808e709cbdSnorby break; 10818e709cbdSnorby case IMSG_CTL_END: 10828e709cbdSnorby printf("\n"); 10838e709cbdSnorby return (1); 10848e709cbdSnorby default: 10858e709cbdSnorby break; 10868e709cbdSnorby } 10878e709cbdSnorby 10888e709cbdSnorby return (0); 10898e709cbdSnorby } 10908e709cbdSnorby 10918e709cbdSnorby void 10928e709cbdSnorby show_fib_head(void) 10938e709cbdSnorby { 10948e709cbdSnorby printf("flags: * = valid, O = OSPF, C = Connected, S = Static\n"); 10958e709cbdSnorby printf("%-6s %-20s %-17s\n", "Flags", "Destination", "Nexthop"); 10968e709cbdSnorby } 10978e709cbdSnorby 10988e709cbdSnorby int 10998e709cbdSnorby show_fib_msg(struct imsg *imsg) 11008e709cbdSnorby { 11018e709cbdSnorby struct kroute *k; 11028e709cbdSnorby char *p; 11038e709cbdSnorby 11048e709cbdSnorby switch (imsg->hdr.type) { 11058e709cbdSnorby case IMSG_CTL_KROUTE: 11068e709cbdSnorby if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute)) 11078e709cbdSnorby errx(1, "wrong imsg len"); 11088e709cbdSnorby k = imsg->data; 11098e709cbdSnorby 11108e709cbdSnorby if (k->flags & F_DOWN) 11118e709cbdSnorby printf(" "); 11128e709cbdSnorby else 11138e709cbdSnorby printf("*"); 11148e709cbdSnorby 11158e709cbdSnorby if (!(k->flags & F_KERNEL)) 11168e709cbdSnorby printf("O"); 11178e709cbdSnorby else if (k->flags & F_CONNECTED) 11188e709cbdSnorby printf("C"); 11198e709cbdSnorby else if (k->flags & F_STATIC) 11208e709cbdSnorby printf("S"); 11218e709cbdSnorby else 11228e709cbdSnorby printf(" "); 11238e709cbdSnorby 11248e709cbdSnorby printf(" "); 11250104e403Sclaudio if (asprintf(&p, "%s/%u", log_in6addr(&k->prefix), 11260104e403Sclaudio k->prefixlen) == -1) 11278e709cbdSnorby err(1, NULL); 11288e709cbdSnorby printf("%-20s ", p); 11298e709cbdSnorby free(p); 11308e709cbdSnorby 11310104e403Sclaudio if (!IN6_IS_ADDR_UNSPECIFIED(&k->nexthop)) 11320104e403Sclaudio printf("%s", log_in6addr(&k->nexthop)); 11338e709cbdSnorby else if (k->flags & F_CONNECTED) 11348e709cbdSnorby printf("link#%u", k->ifindex); 11358e709cbdSnorby printf("\n"); 11368e709cbdSnorby 11378e709cbdSnorby break; 11388e709cbdSnorby case IMSG_CTL_END: 11398e709cbdSnorby printf("\n"); 11408e709cbdSnorby return (1); 11418e709cbdSnorby default: 11428e709cbdSnorby break; 11438e709cbdSnorby } 11448e709cbdSnorby 11458e709cbdSnorby return (0); 11468e709cbdSnorby } 11478e709cbdSnorby 11488e709cbdSnorby void 11498e709cbdSnorby show_interface_head(void) 11508e709cbdSnorby { 11518e709cbdSnorby printf("%-15s%-15s%s\n", "Interface", "Flags", 11528e709cbdSnorby "Link state"); 11538e709cbdSnorby } 11548e709cbdSnorby 11558e709cbdSnorby const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST; 11568e709cbdSnorby const struct ifmedia_status_description 11578e709cbdSnorby ifm_status_descriptions[] = IFM_STATUS_DESCRIPTIONS; 11588e709cbdSnorby const struct ifmedia_description 11598e709cbdSnorby ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; 11608e709cbdSnorby 11618e709cbdSnorby const char * 11628e709cbdSnorby get_media_descr(int media_type) 11638e709cbdSnorby { 11648e709cbdSnorby const struct ifmedia_description *p; 11658e709cbdSnorby 11668e709cbdSnorby for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++) 11678e709cbdSnorby if (media_type == p->ifmt_word) 11688e709cbdSnorby return (p->ifmt_string); 11698e709cbdSnorby 11708e709cbdSnorby return ("unknown"); 11718e709cbdSnorby } 11728e709cbdSnorby 11738e709cbdSnorby const char * 11748e709cbdSnorby get_linkstate(int media_type, int link_state) 11758e709cbdSnorby { 11768e709cbdSnorby const struct ifmedia_status_description *p; 11778e709cbdSnorby int i; 11788e709cbdSnorby 11798e709cbdSnorby if (link_state == LINK_STATE_UNKNOWN) 11808e709cbdSnorby return ("unknown"); 11818e709cbdSnorby 11828e709cbdSnorby for (i = 0; ifm_status_valid_list[i] != 0; i++) 11838e709cbdSnorby for (p = ifm_status_descriptions; p->ifms_valid != 0; p++) { 11848e709cbdSnorby if (p->ifms_type != media_type || 11858e709cbdSnorby p->ifms_valid != ifm_status_valid_list[i]) 11868e709cbdSnorby continue; 11878e709cbdSnorby if (LINK_STATE_IS_UP(link_state)) 11888e709cbdSnorby return (p->ifms_string[1]); 11898e709cbdSnorby return (p->ifms_string[0]); 11908e709cbdSnorby } 11918e709cbdSnorby 11928e709cbdSnorby return ("unknown"); 11938e709cbdSnorby } 11948e709cbdSnorby 11958e709cbdSnorby void 11968e709cbdSnorby print_baudrate(u_int64_t baudrate) 11978e709cbdSnorby { 11988e709cbdSnorby if (baudrate > IF_Gbps(1)) 11998e709cbdSnorby printf("%llu GBit/s", baudrate / IF_Gbps(1)); 12008e709cbdSnorby else if (baudrate > IF_Mbps(1)) 12018e709cbdSnorby printf("%llu MBit/s", baudrate / IF_Mbps(1)); 12028e709cbdSnorby else if (baudrate > IF_Kbps(1)) 12038e709cbdSnorby printf("%llu KBit/s", baudrate / IF_Kbps(1)); 12048e709cbdSnorby else 12058e709cbdSnorby printf("%llu Bit/s", baudrate); 12068e709cbdSnorby } 12078e709cbdSnorby 12088e709cbdSnorby int 12098e709cbdSnorby show_fib_interface_msg(struct imsg *imsg) 12108e709cbdSnorby { 12118e709cbdSnorby struct kif *k; 12128e709cbdSnorby int ifms_type; 12138e709cbdSnorby 12148e709cbdSnorby switch (imsg->hdr.type) { 12158e709cbdSnorby case IMSG_CTL_IFINFO: 12168e709cbdSnorby k = imsg->data; 12178e709cbdSnorby printf("%-15s", k->ifname); 12188e709cbdSnorby printf("%-15s", k->flags & IFF_UP ? "UP" : ""); 12198e709cbdSnorby switch (k->media_type) { 12208e709cbdSnorby case IFT_ETHER: 12218e709cbdSnorby ifms_type = IFM_ETHER; 12228e709cbdSnorby break; 12238e709cbdSnorby case IFT_FDDI: 12248e709cbdSnorby ifms_type = IFM_FDDI; 12258e709cbdSnorby break; 12268e709cbdSnorby case IFT_CARP: 12278e709cbdSnorby ifms_type = IFM_CARP; 12288e709cbdSnorby break; 12298e709cbdSnorby default: 12308e709cbdSnorby ifms_type = 0; 12318e709cbdSnorby break; 12328e709cbdSnorby } 12338e709cbdSnorby 12348e709cbdSnorby if (ifms_type) 12358e709cbdSnorby printf("%s, %s", get_media_descr(ifms_type), 12368e709cbdSnorby get_linkstate(ifms_type, k->link_state)); 12378e709cbdSnorby else if (k->link_state == LINK_STATE_UNKNOWN) 12388e709cbdSnorby printf("unknown"); 12398e709cbdSnorby else 12408e709cbdSnorby printf("link state %u", k->link_state); 12418e709cbdSnorby 12428e709cbdSnorby if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) { 12438e709cbdSnorby printf(", "); 12448e709cbdSnorby print_baudrate(k->baudrate); 12458e709cbdSnorby } 12468e709cbdSnorby printf("\n"); 12478e709cbdSnorby break; 12488e709cbdSnorby case IMSG_CTL_END: 12498e709cbdSnorby printf("\n"); 12508e709cbdSnorby return (1); 12518e709cbdSnorby default: 12528e709cbdSnorby break; 12538e709cbdSnorby } 12548e709cbdSnorby 12558e709cbdSnorby return (0); 12568e709cbdSnorby } 1257