1*daa441c5Sderaadt /* $OpenBSD: dvmrpctl.c,v 1.14 2015/10/25 20:23:00 deraadt Exp $ */ 289189827Snorby 389189827Snorby /* 489189827Snorby * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 589189827Snorby * Copyright (c) 2004, 2005, 2006 Esben Norby <norby@openbsd.org> 689189827Snorby * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> 789189827Snorby * 889189827Snorby * Permission to use, copy, modify, and distribute this software for any 989189827Snorby * purpose with or without fee is hereby granted, provided that the above 1089189827Snorby * copyright notice and this permission notice appear in all copies. 1189189827Snorby * 1289189827Snorby * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1389189827Snorby * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1489189827Snorby * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1589189827Snorby * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1689189827Snorby * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1789189827Snorby * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1889189827Snorby * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1989189827Snorby */ 2089189827Snorby 2189189827Snorby #include <sys/types.h> 2289189827Snorby #include <sys/socket.h> 2389189827Snorby #include <sys/un.h> 2489189827Snorby #include <netinet/in.h> 2589189827Snorby #include <netinet/ip_mroute.h> 2689189827Snorby #include <arpa/inet.h> 2789189827Snorby #include <net/if_types.h> 2889189827Snorby 2989189827Snorby #include <err.h> 30397afdbcSderaadt #include <errno.h> 3189189827Snorby #include <stdio.h> 3289189827Snorby #include <stdlib.h> 3389189827Snorby #include <string.h> 3489189827Snorby #include <unistd.h> 3589189827Snorby 3689189827Snorby #include "igmp.h" 3789189827Snorby #include "dvmrp.h" 3889189827Snorby #include "dvmrpd.h" 3989189827Snorby #include "dvmrpe.h" 4089189827Snorby #include "parser.h" 4189189827Snorby #include "log.h" 4289189827Snorby 4389189827Snorby __dead void usage(void); 4489189827Snorby int show_summary_msg(struct imsg *); 4589189827Snorby int show_interface_msg(struct imsg *); 4689189827Snorby int show_interface_detail_msg(struct imsg *); 4789189827Snorby int show_igmp_msg(struct imsg *); 4889189827Snorby const char *print_if_type(enum iface_type type); 4989189827Snorby const char *print_nbr_state(int); 5089189827Snorby const char *print_link(int); 5189189827Snorby const char *fmt_timeframe(time_t t); 5289189827Snorby const char *fmt_timeframe_core(time_t t); 5389189827Snorby int show_nbr_msg(struct imsg *); 5489189827Snorby const char *print_dvmrp_options(u_int8_t); 5589189827Snorby int show_nbr_detail_msg(struct imsg *); 5689189827Snorby int show_rib_msg(struct imsg *); 5789189827Snorby int show_rib_detail_msg(struct imsg *); 5889189827Snorby int show_mfc_msg(struct imsg *); 5989189827Snorby int show_mfc_detail_msg(struct imsg *); 609f69273fSstsp const char * get_linkstate(uint8_t, int); 6189189827Snorby 6289189827Snorby struct imsgbuf *ibuf; 6389189827Snorby 6489189827Snorby __dead void 6589189827Snorby usage(void) 6689189827Snorby { 6789189827Snorby extern char *__progname; 6889189827Snorby 69b63b9e86Ssobrado fprintf(stderr, "usage: %s command [argument ...]\n", __progname); 7089189827Snorby exit(1); 7189189827Snorby } 7289189827Snorby 7389189827Snorby int 7489189827Snorby main(int argc, char *argv[]) 7589189827Snorby { 7689189827Snorby struct sockaddr_un sun; 7789189827Snorby struct parse_result *res; 7889189827Snorby struct imsg imsg; 7989189827Snorby unsigned int ifidx = 0; 8089189827Snorby int ctl_sock; 81c3319070Sclaudio int done = 0, verbose = 0; 8289189827Snorby int n; 8389189827Snorby 8489189827Snorby /* parse options */ 8589189827Snorby if ((res = parse(argc - 1, argv + 1)) == NULL) 8689189827Snorby exit(1); 8789189827Snorby 8889189827Snorby /* connect to dvmrpd control socket */ 8989189827Snorby if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 9089189827Snorby err(1, "socket"); 9189189827Snorby 9289189827Snorby bzero(&sun, sizeof(sun)); 9389189827Snorby sun.sun_family = AF_UNIX; 9489189827Snorby strlcpy(sun.sun_path, DVMRPD_SOCKET, sizeof(sun.sun_path)); 9589189827Snorby if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 9689189827Snorby err(1, "connect: %s", DVMRPD_SOCKET); 9789189827Snorby 98*daa441c5Sderaadt if (pledge("stdio", NULL) == -1) 99bc3fb1a1Sderaadt err(1, "pledge"); 100bc3fb1a1Sderaadt 10189189827Snorby if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 10289189827Snorby fatal(NULL); 10314d72cd0Spyr imsg_init(ibuf, ctl_sock); 10489189827Snorby done = 0; 10589189827Snorby 10689189827Snorby /* process user request */ 10789189827Snorby switch (res->action) { 10889189827Snorby case NONE: 10989189827Snorby usage(); 11089189827Snorby /* NOTREACHED */ 11189189827Snorby case SHOW: 11289189827Snorby case SHOW_SUM: 11314d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); 11489189827Snorby break; 11589189827Snorby case SHOW_IFACE: 11689189827Snorby printf("%-11s %-18s %-10s %-10s %-10s %-8s %s\n", 11789189827Snorby "Interface", "Address", "State", "ProbeTimer", "Linkstate", 11889189827Snorby "Uptime", "Groups"); 11989189827Snorby /* FALLTHROUGH */ 12089189827Snorby case SHOW_IFACE_DTAIL: 12189189827Snorby if (*res->ifname) { 12289189827Snorby ifidx = if_nametoindex(res->ifname); 12389189827Snorby if (ifidx == 0) 12489189827Snorby errx(1, "no such interface %s", res->ifname); 12589189827Snorby } 12614d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_IFACE, 0, 0, -1, &ifidx, 12789189827Snorby sizeof(ifidx)); 12889189827Snorby break; 12989189827Snorby case SHOW_IGMP: 13089189827Snorby if (*res->ifname) { 13189189827Snorby ifidx = if_nametoindex(res->ifname); 13289189827Snorby if (ifidx == 0) 13389189827Snorby errx(1, "no such interface %s", res->ifname); 13489189827Snorby } 13514d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_IGMP, 0, 0, -1, &ifidx, 13689189827Snorby sizeof(ifidx)); 13789189827Snorby break; 13889189827Snorby case SHOW_NBR: 13989189827Snorby printf("%-15s %-10s %-9s %-15s %-11s %-8s\n", "ID", "State", 14089189827Snorby "DeadTime", "Address", "Interface", "Uptime"); 14189189827Snorby /* FALLTHROUGH */ 14289189827Snorby case SHOW_NBR_DTAIL: 14314d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 14489189827Snorby break; 14589189827Snorby case SHOW_RIB: 14689189827Snorby printf("%-20s %-17s %-7s %-10s %-s\n", "Destination", "Nexthop", 14789189827Snorby "Cost", "Uptime", "Expire"); 14889189827Snorby /* FALLTHROUGH */ 14989189827Snorby case SHOW_RIB_DTAIL: 15014d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); 15189189827Snorby break; 15289189827Snorby case SHOW_MFC: 15389189827Snorby printf("%-16s %-16s %-9s %-9s %-4s %-10s %-10s\n", "Group", 15489189827Snorby "Origin", "Incoming", "Outgoing", "TTL", "Uptime", 15589189827Snorby "Expire"); 15689189827Snorby /* FALLTHROUGH */ 15789189827Snorby case SHOW_MFC_DTAIL: 15814d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_MFC, 0, 0, -1, NULL, 0); 15989189827Snorby break; 160c3319070Sclaudio case LOG_VERBOSE: 161c3319070Sclaudio verbose = 1; 162c3319070Sclaudio /* FALLTHROUGH */ 163c3319070Sclaudio case LOG_BRIEF: 164c3319070Sclaudio imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, 165c3319070Sclaudio &verbose, sizeof(verbose)); 166c3319070Sclaudio printf("logging request sent.\n"); 167c3319070Sclaudio done = 1; 168c3319070Sclaudio break; 16989189827Snorby case RELOAD: 17014d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 17189189827Snorby printf("reload request sent.\n"); 17289189827Snorby done = 1; 17389189827Snorby break; 17489189827Snorby } 17589189827Snorby 17689189827Snorby while (ibuf->w.queued) 177397afdbcSderaadt if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) 17889189827Snorby err(1, "write error"); 17989189827Snorby 18089189827Snorby while (!done) { 18189189827Snorby if ((n = imsg_read(ibuf)) == -1) 18289189827Snorby errx(1, "imsg_read error"); 18389189827Snorby if (n == 0) 18489189827Snorby errx(1, "pipe closed"); 18589189827Snorby 18689189827Snorby while (!done) { 18789189827Snorby if ((n = imsg_get(ibuf, &imsg)) == -1) 18889189827Snorby errx(1, "imsg_get error"); 18989189827Snorby if (n == 0) 19089189827Snorby break; 19189189827Snorby switch (res->action) { 19289189827Snorby case SHOW: 19389189827Snorby case SHOW_SUM: 19489189827Snorby done = show_summary_msg(&imsg); 19589189827Snorby break; 19689189827Snorby case SHOW_IFACE: 19789189827Snorby done = show_interface_msg(&imsg); 19889189827Snorby break; 19989189827Snorby case SHOW_IFACE_DTAIL: 20089189827Snorby done = show_interface_detail_msg(&imsg); 20189189827Snorby break; 20289189827Snorby case SHOW_IGMP: 20389189827Snorby done = show_igmp_msg(&imsg); 20489189827Snorby break; 20589189827Snorby case SHOW_NBR: 20689189827Snorby done = show_nbr_msg(&imsg); 20789189827Snorby break; 20889189827Snorby case SHOW_NBR_DTAIL: 20989189827Snorby done = show_nbr_detail_msg(&imsg); 21089189827Snorby break; 21189189827Snorby case SHOW_RIB: 21289189827Snorby done = show_rib_msg(&imsg); 21389189827Snorby break; 21489189827Snorby case SHOW_RIB_DTAIL: 21589189827Snorby done = show_rib_detail_msg(&imsg); 21689189827Snorby break; 21789189827Snorby case SHOW_MFC: 21889189827Snorby done = show_mfc_msg(&imsg); 21989189827Snorby break; 22089189827Snorby case SHOW_MFC_DTAIL: 22189189827Snorby done = show_mfc_detail_msg(&imsg); 22289189827Snorby break; 22389189827Snorby case NONE: 224c3319070Sclaudio case LOG_VERBOSE: 225c3319070Sclaudio case LOG_BRIEF: 22689189827Snorby case RELOAD: 22789189827Snorby break; 22889189827Snorby } 22989189827Snorby imsg_free(&imsg); 23089189827Snorby } 23189189827Snorby } 23289189827Snorby close(ctl_sock); 23389189827Snorby free(ibuf); 23489189827Snorby 23589189827Snorby return (0); 23689189827Snorby } 23789189827Snorby 23889189827Snorby int 23989189827Snorby show_summary_msg(struct imsg *imsg) 24089189827Snorby { 24189189827Snorby struct ctl_sum *sum; 24289189827Snorby 24389189827Snorby switch (imsg->hdr.type) { 24489189827Snorby case IMSG_CTL_SHOW_SUM: 24589189827Snorby sum = imsg->data; 24689189827Snorby printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); 24789189827Snorby printf("Hold time is %d sec(s)\n", sum->hold_time); 24889189827Snorby break; 24989189827Snorby case IMSG_CTL_END: 25089189827Snorby printf("\n"); 25189189827Snorby return (1); 25289189827Snorby default: 25389189827Snorby break; 25489189827Snorby } 25589189827Snorby 25689189827Snorby return (0); 25789189827Snorby } 25889189827Snorby 25989189827Snorby int 26089189827Snorby show_interface_msg(struct imsg *imsg) 26189189827Snorby { 26289189827Snorby struct ctl_iface *iface; 26389189827Snorby char *netid; 26489189827Snorby 26589189827Snorby switch (imsg->hdr.type) { 26689189827Snorby case IMSG_CTL_SHOW_IFACE: 26789189827Snorby iface = imsg->data; 26889189827Snorby 26989189827Snorby if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), 27089189827Snorby mask2prefixlen(iface->mask.s_addr)) == -1) 27189189827Snorby err(1, NULL); 27289189827Snorby printf("%-11s %-18s %-10s %-10s %-10s %-8s %5d\n", 27389189827Snorby iface->name, netid, if_state_name(iface->state), 27489189827Snorby iface->probe_timer == 0 ? "00:00:00" : 27589189827Snorby fmt_timeframe_core(iface->probe_timer), 2769f69273fSstsp get_linkstate(iface->if_type, iface->linkstate), 2770f617141Sclaudio iface->uptime == 0 ? "00:00:00" : 27889189827Snorby fmt_timeframe_core(iface->uptime), iface->group_cnt); 27989189827Snorby free(netid); 28089189827Snorby break; 28189189827Snorby case IMSG_CTL_END: 28289189827Snorby printf("\n"); 28389189827Snorby return (1); 28489189827Snorby default: 28589189827Snorby break; 28689189827Snorby } 28789189827Snorby 28889189827Snorby return (0); 28989189827Snorby } 29089189827Snorby 29189189827Snorby int 29289189827Snorby show_interface_detail_msg(struct imsg *imsg) 29389189827Snorby { 29489189827Snorby struct ctl_iface *iface; 29589189827Snorby 29689189827Snorby switch (imsg->hdr.type) { 29789189827Snorby case IMSG_CTL_SHOW_IFACE: 29889189827Snorby iface = imsg->data; 29989189827Snorby 30089189827Snorby printf("\n"); 30189189827Snorby printf("Interface %s, line protocol is %s\n", 30289189827Snorby iface->name, print_link(iface->flags)); 30389189827Snorby printf(" Internet address %s/%d\n", 30489189827Snorby inet_ntoa(iface->addr), 30589189827Snorby mask2prefixlen(iface->mask.s_addr)); 30689189827Snorby printf(" Linkstate %s\n", 3079f69273fSstsp get_linkstate(iface->if_type, iface->linkstate)); 30889189827Snorby printf(" Network type %s, cost: %d\n", 30989189827Snorby if_type_name(iface->type), iface->metric); 31089189827Snorby printf(" State %s, querier ", if_state_name(iface->state)); 31189189827Snorby if (iface->state == IF_STA_QUERIER) 31289189827Snorby printf("%s\n", inet_ntoa(iface->addr)); 31389189827Snorby else 31489189827Snorby printf("%s\n", inet_ntoa(iface->querier)); 31589189827Snorby printf(" Generation ID %d\n", iface->gen_id); 31689189827Snorby printf(" Timer intervals configured, " 31789189827Snorby "probe %d, dead %d\n", iface->probe_interval, 31889189827Snorby iface->dead_interval); 31989189827Snorby if (iface->passive) 32089189827Snorby printf(" Passive interface (No Hellos)\n"); 32189189827Snorby else if (iface->probe_timer < 0) 32289189827Snorby printf(" Hello timer not running\n"); 32389189827Snorby else 32489189827Snorby printf(" Hello timer due in %s\n", 32589189827Snorby fmt_timeframe_core(iface->probe_timer)); 32689189827Snorby printf(" Uptime %s\n", iface->uptime == 0 ? 32789189827Snorby "00:00:00" : fmt_timeframe_core(iface->uptime)); 328b39d1d57Smichele printf(" Adjacent neighbor count is " 329b39d1d57Smichele "%d\n", iface->adj_cnt); 33089189827Snorby break; 33189189827Snorby case IMSG_CTL_END: 33289189827Snorby printf("\n"); 33389189827Snorby return (1); 33489189827Snorby default: 33589189827Snorby break; 33689189827Snorby } 33789189827Snorby 33889189827Snorby return (0); 33989189827Snorby } 34089189827Snorby 34189189827Snorby int 34289189827Snorby show_igmp_msg(struct imsg *imsg) 34389189827Snorby { 34489189827Snorby struct ctl_iface *iface; 34589189827Snorby struct ctl_group *group; 34689189827Snorby char *netid; 34789189827Snorby 34889189827Snorby switch (imsg->hdr.type) { 34989189827Snorby case IMSG_CTL_SHOW_IFACE: 35089189827Snorby iface = imsg->data; 35189189827Snorby if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), 35289189827Snorby mask2prefixlen(iface->mask.s_addr)) == -1) 35389189827Snorby err(1, NULL); 35489189827Snorby printf("\nInterface %s, address %s, state %s, groups %d\n", 35589189827Snorby iface->name, netid, if_state_name(iface->state), 35689189827Snorby iface->group_cnt); 35789189827Snorby free(netid); 35889189827Snorby printf(" %-16s %-10s %-10s %-10s\n", "Group", "State", 35989189827Snorby "DeadTimer", "Uptime"); 36089189827Snorby break; 36189189827Snorby case IMSG_CTL_SHOW_IGMP: 36289189827Snorby group = imsg->data; 36389189827Snorby printf(" %-16s %-10s %-10s %-10s\n", inet_ntoa(group->addr), 36489189827Snorby group_state_name(group->state), 36589189827Snorby group->dead_timer == 0 ? "00:00:00" : 36689189827Snorby fmt_timeframe_core(group->dead_timer), 36789189827Snorby group->uptime == 0 ? "00:00:00" : 36889189827Snorby fmt_timeframe_core(group->uptime)); 36989189827Snorby break; 37089189827Snorby case IMSG_CTL_END: 37189189827Snorby printf("\n"); 37289189827Snorby return (1); 37389189827Snorby default: 37489189827Snorby break; 37589189827Snorby } 37689189827Snorby 37789189827Snorby return (0); 37889189827Snorby } 37989189827Snorby 38089189827Snorby const char * 38189189827Snorby print_if_type(enum iface_type type) 38289189827Snorby { 38389189827Snorby switch (type) { 38489189827Snorby case IF_TYPE_POINTOPOINT: 38589189827Snorby return ("POINTOPOINT"); 38689189827Snorby case IF_TYPE_BROADCAST: 38789189827Snorby return ("BROADCAST"); 38889189827Snorby default: 38989189827Snorby return ("UNKNOWN"); 39089189827Snorby } 39189189827Snorby } 39289189827Snorby 39389189827Snorby const char * 39489189827Snorby print_nbr_state(int state) 39589189827Snorby { 39689189827Snorby switch (state) { 39789189827Snorby case NBR_STA_DOWN: 39889189827Snorby return ("DOWN"); 39989189827Snorby case NBR_STA_1_WAY: 40089189827Snorby return ("1-WAY"); 40189189827Snorby case NBR_STA_2_WAY: 40289189827Snorby return ("2-WAY"); 40389189827Snorby default: 40489189827Snorby return ("UNKNOWN"); 40589189827Snorby } 40689189827Snorby } 40789189827Snorby 40889189827Snorby const char * 40989189827Snorby print_link(int state) 41089189827Snorby { 41189189827Snorby if (state & IFF_UP) 41289189827Snorby return ("UP"); 41389189827Snorby else 41489189827Snorby return ("DOWN"); 41589189827Snorby } 41689189827Snorby 41789189827Snorby #define TF_BUFS 8 41889189827Snorby #define TF_LEN 9 41989189827Snorby 42089189827Snorby const char * 42189189827Snorby fmt_timeframe(time_t t) 42289189827Snorby { 42389189827Snorby if (t == 0) 42489189827Snorby return ("Never"); 42589189827Snorby else 42689189827Snorby return (fmt_timeframe_core(time(NULL) - t)); 42789189827Snorby } 42889189827Snorby 42989189827Snorby const char * 43089189827Snorby fmt_timeframe_core(time_t t) 43189189827Snorby { 43289189827Snorby char *buf; 43389189827Snorby static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 43489189827Snorby static int idx = 0; 435035b0708Sgilles unsigned int sec, min, hrs, day; 436035b0708Sgilles unsigned long long week; 43789189827Snorby 43889189827Snorby if (t == 0) 43989189827Snorby return ("Stopped"); 44089189827Snorby 44189189827Snorby buf = tfbuf[idx++]; 44289189827Snorby if (idx == TF_BUFS) 44389189827Snorby idx = 0; 44489189827Snorby 44589189827Snorby week = t; 44689189827Snorby 44789189827Snorby sec = week % 60; 44889189827Snorby week /= 60; 44989189827Snorby min = week % 60; 45089189827Snorby week /= 60; 45189189827Snorby hrs = week % 24; 45289189827Snorby week /= 24; 45389189827Snorby day = week % 7; 45489189827Snorby week /= 7; 45589189827Snorby 45689189827Snorby if (week > 0) 457035b0708Sgilles snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs); 45889189827Snorby else if (day > 0) 45989189827Snorby snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 46089189827Snorby else 46189189827Snorby snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 46289189827Snorby 46389189827Snorby return (buf); 46489189827Snorby } 46589189827Snorby 46689189827Snorby /* prototype defined in dvmrpd.h and shared with the kroute.c version */ 46789189827Snorby u_int8_t 46889189827Snorby mask2prefixlen(in_addr_t ina) 46989189827Snorby { 47089189827Snorby if (ina == 0) 47189189827Snorby return (0); 47289189827Snorby else 47389189827Snorby return (33 - ffs(ntohl(ina))); 47489189827Snorby } 47589189827Snorby 47689189827Snorby int 47789189827Snorby show_nbr_msg(struct imsg *imsg) 47889189827Snorby { 47989189827Snorby struct ctl_nbr *nbr; 48089189827Snorby 48189189827Snorby switch (imsg->hdr.type) { 48289189827Snorby case IMSG_CTL_SHOW_NBR: 48389189827Snorby nbr = imsg->data; 48489189827Snorby printf("%-15s %-10s %-10s", inet_ntoa(nbr->id), 48589189827Snorby print_nbr_state(nbr->state), 48689189827Snorby fmt_timeframe_core(nbr->dead_timer)); 48789189827Snorby printf("%-15s %-11s %s\n", inet_ntoa(nbr->addr), 48889189827Snorby nbr->name, fmt_timeframe_core(nbr->uptime)); 48989189827Snorby break; 49089189827Snorby case IMSG_CTL_END: 49189189827Snorby printf("\n"); 49289189827Snorby return (1); 49389189827Snorby default: 49489189827Snorby break; 49589189827Snorby } 49689189827Snorby 49789189827Snorby return (0); 49889189827Snorby } 49989189827Snorby 50089189827Snorby const char * 50189189827Snorby print_dvmrp_options(u_int8_t opts) 50289189827Snorby { 50389189827Snorby static char optbuf[32]; 50489189827Snorby 50589189827Snorby snprintf(optbuf, sizeof(optbuf), "*|*|%s|%s|%s|%s|%s|%s", 50689189827Snorby opts & DVMRP_CAP_NETMASK ? "N" : "-", 50789189827Snorby opts & DVMRP_CAP_SNMP ? "S" : "-", 50889189827Snorby opts & DVMRP_CAP_MTRACE ? "M" : "-", 50989189827Snorby opts & DVMRP_CAP_GENID ? "G" : "-", 51089189827Snorby opts & DVMRP_CAP_PRUNE ? "P" : "-", 51189189827Snorby opts & DVMRP_CAP_LEAF ? "L" : "-"); 51289189827Snorby return (optbuf); 51389189827Snorby } 51489189827Snorby 51589189827Snorby int 51689189827Snorby show_nbr_detail_msg(struct imsg *imsg) 51789189827Snorby { 51889189827Snorby struct ctl_nbr *nbr; 51989189827Snorby 52089189827Snorby switch (imsg->hdr.type) { 52189189827Snorby case IMSG_CTL_SHOW_NBR: 52289189827Snorby nbr = imsg->data; 52389189827Snorby break; 52489189827Snorby case IMSG_CTL_END: 52589189827Snorby printf("\n"); 52689189827Snorby return (1); 52789189827Snorby default: 52889189827Snorby break; 52989189827Snorby } 53089189827Snorby 53189189827Snorby return (0); 53289189827Snorby } 53389189827Snorby 53489189827Snorby int 53589189827Snorby show_rib_msg(struct imsg *imsg) 53689189827Snorby { 53789189827Snorby struct ctl_rt *rt; 53889189827Snorby char *dstnet; 53989189827Snorby 54089189827Snorby switch (imsg->hdr.type) { 54189189827Snorby case IMSG_CTL_SHOW_RIB: 54289189827Snorby rt = imsg->data; 54389189827Snorby if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), 54489189827Snorby rt->prefixlen) == -1) 54589189827Snorby err(1, NULL); 54689189827Snorby 54789189827Snorby printf("%-20s %-17s %-7d %-9s %9s\n", dstnet, 54889189827Snorby inet_ntoa(rt->nexthop), 54989189827Snorby rt->cost, rt->uptime == 0 ? "-" : 55089189827Snorby fmt_timeframe_core(rt->uptime), 55189189827Snorby rt->expire == 0 ? "00:00:00" : 55289189827Snorby fmt_timeframe_core(rt->expire)); 55389189827Snorby free(dstnet); 55489189827Snorby 55589189827Snorby break; 55689189827Snorby case IMSG_CTL_END: 55789189827Snorby printf("\n"); 55889189827Snorby return (1); 55989189827Snorby default: 56089189827Snorby break; 56189189827Snorby } 56289189827Snorby 56389189827Snorby return (0); 56489189827Snorby } 56589189827Snorby 56689189827Snorby int 56789189827Snorby show_rib_detail_msg(struct imsg *imsg) 56889189827Snorby { 56989189827Snorby 57089189827Snorby switch (imsg->hdr.type) { 57189189827Snorby case IMSG_CTL_SHOW_RIB: 57289189827Snorby break; 57389189827Snorby case IMSG_CTL_END: 57489189827Snorby printf("\n"); 57589189827Snorby return (1); 57689189827Snorby default: 57789189827Snorby break; 57889189827Snorby } 57989189827Snorby 58089189827Snorby return (0); 58189189827Snorby } 58289189827Snorby 58389189827Snorby int 58489189827Snorby show_mfc_msg(struct imsg *imsg) 58589189827Snorby { 58689189827Snorby char iname[IF_NAMESIZE]; 58789189827Snorby char oname[IF_NAMESIZE] = "-"; 58889189827Snorby struct ctl_mfc *mfc; 58989189827Snorby int i; 59089189827Snorby 59189189827Snorby 59289189827Snorby switch (imsg->hdr.type) { 59389189827Snorby case IMSG_CTL_SHOW_MFC: 59489189827Snorby mfc = imsg->data; 59589189827Snorby if_indextoname(mfc->ifindex, iname); 59689189827Snorby 59789189827Snorby /* search for first entry with ttl > 0 */ 59889189827Snorby for (i = 0; i < MAXVIFS; i++) { 59989189827Snorby if (mfc->ttls[i] > 0) { 60089189827Snorby if_indextoname(i, oname); 60189189827Snorby i++; 60289189827Snorby break; 60389189827Snorby } 60489189827Snorby } 60589189827Snorby 60689189827Snorby /* display first entry with uptime */ 60789189827Snorby printf("%-16s ", inet_ntoa(mfc->group)); 60889189827Snorby printf("%-16s %-9s %-9s %-4d %-10s %-10s\n", 60989189827Snorby inet_ntoa(mfc->origin), iname, oname, mfc->ttls[i - 1], 61089189827Snorby mfc->uptime == 0 ? "-" : fmt_timeframe_core(mfc->uptime), 61189189827Snorby mfc->expire == 0 ? "-" : fmt_timeframe_core(mfc->expire)); 61289189827Snorby 61389189827Snorby /* display remaining entries with ttl > 0 */ 61489189827Snorby for (; i < MAXVIFS; i++) { 61589189827Snorby if (mfc->ttls[i] > 0) { 61689189827Snorby if_indextoname(i, oname); 61789189827Snorby printf("%43s %-9s %-4d\n", " ", oname, 61889189827Snorby mfc->ttls[i]); 61989189827Snorby } 62089189827Snorby } 62189189827Snorby break; 62289189827Snorby case IMSG_CTL_END: 62389189827Snorby printf("\n"); 62489189827Snorby return (1); 62589189827Snorby default: 62689189827Snorby break; 62789189827Snorby } 62889189827Snorby 62989189827Snorby return (0); 63089189827Snorby } 63189189827Snorby 63289189827Snorby int 63389189827Snorby show_mfc_detail_msg(struct imsg *imsg) 63489189827Snorby { 63589189827Snorby 63689189827Snorby switch (imsg->hdr.type) { 63789189827Snorby case IMSG_CTL_SHOW_MFC: 63889189827Snorby break; 63989189827Snorby case IMSG_CTL_END: 64089189827Snorby printf("\n"); 64189189827Snorby return (1); 64289189827Snorby default: 64389189827Snorby break; 64489189827Snorby } 64589189827Snorby 64689189827Snorby return (0); 64789189827Snorby } 64889189827Snorby 6490f617141Sclaudio const struct if_status_description 6500f617141Sclaudio if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; 65189189827Snorby 65289189827Snorby const char * 6539f69273fSstsp get_linkstate(uint8_t if_type, int link_state) 65489189827Snorby { 6550f617141Sclaudio const struct if_status_description *p; 6560f617141Sclaudio static char buf[8]; 65789189827Snorby 6580f617141Sclaudio for (p = if_status_descriptions; p->ifs_string != NULL; p++) { 6599f69273fSstsp if (LINK_STATE_DESC_MATCH(p, if_type, link_state)) 6600f617141Sclaudio return (p->ifs_string); 66189189827Snorby } 6620f617141Sclaudio snprintf(buf, sizeof(buf), "[#%d]", link_state); 6630f617141Sclaudio return (buf); 66489189827Snorby } 665