1*c3319070Sclaudio /* $OpenBSD: dvmrpctl.c,v 1.9 2009/11/02 20:32:17 claudio 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_media.h> 2889189827Snorby #include <net/if_types.h> 2989189827Snorby 3089189827Snorby #include <err.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 get_ifms_type(int); 4689189827Snorby int show_interface_msg(struct imsg *); 4789189827Snorby int show_interface_detail_msg(struct imsg *); 4889189827Snorby int show_igmp_msg(struct imsg *); 4989189827Snorby const char *print_if_type(enum iface_type type); 5089189827Snorby const char *print_nbr_state(int); 5189189827Snorby const char *print_link(int); 5289189827Snorby const char *fmt_timeframe(time_t t); 5389189827Snorby const char *fmt_timeframe_core(time_t t); 5489189827Snorby int show_nbr_msg(struct imsg *); 5589189827Snorby const char *print_dvmrp_options(u_int8_t); 5689189827Snorby int show_nbr_detail_msg(struct imsg *); 5789189827Snorby int show_rib_msg(struct imsg *); 5889189827Snorby int show_rib_detail_msg(struct imsg *); 5989189827Snorby int show_mfc_msg(struct imsg *); 6089189827Snorby int show_mfc_detail_msg(struct imsg *); 6189189827Snorby const char * get_linkstate(int, int); 6289189827Snorby 6389189827Snorby struct imsgbuf *ibuf; 6489189827Snorby 6589189827Snorby __dead void 6689189827Snorby usage(void) 6789189827Snorby { 6889189827Snorby extern char *__progname; 6989189827Snorby 70b63b9e86Ssobrado fprintf(stderr, "usage: %s command [argument ...]\n", __progname); 7189189827Snorby exit(1); 7289189827Snorby } 7389189827Snorby 7489189827Snorby int 7589189827Snorby main(int argc, char *argv[]) 7689189827Snorby { 7789189827Snorby struct sockaddr_un sun; 7889189827Snorby struct parse_result *res; 7989189827Snorby struct imsg imsg; 8089189827Snorby unsigned int ifidx = 0; 8189189827Snorby int ctl_sock; 82*c3319070Sclaudio int done = 0, verbose = 0; 8389189827Snorby int n; 8489189827Snorby 8589189827Snorby /* parse options */ 8689189827Snorby if ((res = parse(argc - 1, argv + 1)) == NULL) 8789189827Snorby exit(1); 8889189827Snorby 8989189827Snorby /* connect to dvmrpd control socket */ 9089189827Snorby if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 9189189827Snorby err(1, "socket"); 9289189827Snorby 9389189827Snorby bzero(&sun, sizeof(sun)); 9489189827Snorby sun.sun_family = AF_UNIX; 9589189827Snorby strlcpy(sun.sun_path, DVMRPD_SOCKET, sizeof(sun.sun_path)); 9689189827Snorby if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 9789189827Snorby err(1, "connect: %s", DVMRPD_SOCKET); 9889189827Snorby 9989189827Snorby if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) 10089189827Snorby fatal(NULL); 10114d72cd0Spyr imsg_init(ibuf, ctl_sock); 10289189827Snorby done = 0; 10389189827Snorby 10489189827Snorby /* process user request */ 10589189827Snorby switch (res->action) { 10689189827Snorby case NONE: 10789189827Snorby usage(); 10889189827Snorby /* NOTREACHED */ 10989189827Snorby case SHOW: 11089189827Snorby case SHOW_SUM: 11114d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); 11289189827Snorby break; 11389189827Snorby case SHOW_IFACE: 11489189827Snorby printf("%-11s %-18s %-10s %-10s %-10s %-8s %s\n", 11589189827Snorby "Interface", "Address", "State", "ProbeTimer", "Linkstate", 11689189827Snorby "Uptime", "Groups"); 11789189827Snorby /* FALLTHROUGH */ 11889189827Snorby case SHOW_IFACE_DTAIL: 11989189827Snorby if (*res->ifname) { 12089189827Snorby ifidx = if_nametoindex(res->ifname); 12189189827Snorby if (ifidx == 0) 12289189827Snorby errx(1, "no such interface %s", res->ifname); 12389189827Snorby } 12414d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_IFACE, 0, 0, -1, &ifidx, 12589189827Snorby sizeof(ifidx)); 12689189827Snorby break; 12789189827Snorby case SHOW_IGMP: 12889189827Snorby if (*res->ifname) { 12989189827Snorby ifidx = if_nametoindex(res->ifname); 13089189827Snorby if (ifidx == 0) 13189189827Snorby errx(1, "no such interface %s", res->ifname); 13289189827Snorby } 13314d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_IGMP, 0, 0, -1, &ifidx, 13489189827Snorby sizeof(ifidx)); 13589189827Snorby break; 13689189827Snorby case SHOW_NBR: 13789189827Snorby printf("%-15s %-10s %-9s %-15s %-11s %-8s\n", "ID", "State", 13889189827Snorby "DeadTime", "Address", "Interface", "Uptime"); 13989189827Snorby /* FALLTHROUGH */ 14089189827Snorby case SHOW_NBR_DTAIL: 14114d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); 14289189827Snorby break; 14389189827Snorby case SHOW_RIB: 14489189827Snorby printf("%-20s %-17s %-7s %-10s %-s\n", "Destination", "Nexthop", 14589189827Snorby "Cost", "Uptime", "Expire"); 14689189827Snorby /* FALLTHROUGH */ 14789189827Snorby case SHOW_RIB_DTAIL: 14814d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); 14989189827Snorby break; 15089189827Snorby case SHOW_MFC: 15189189827Snorby printf("%-16s %-16s %-9s %-9s %-4s %-10s %-10s\n", "Group", 15289189827Snorby "Origin", "Incoming", "Outgoing", "TTL", "Uptime", 15389189827Snorby "Expire"); 15489189827Snorby /* FALLTHROUGH */ 15589189827Snorby case SHOW_MFC_DTAIL: 15614d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_SHOW_MFC, 0, 0, -1, NULL, 0); 15789189827Snorby break; 158*c3319070Sclaudio case LOG_VERBOSE: 159*c3319070Sclaudio verbose = 1; 160*c3319070Sclaudio /* FALLTHROUGH */ 161*c3319070Sclaudio case LOG_BRIEF: 162*c3319070Sclaudio imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, 163*c3319070Sclaudio &verbose, sizeof(verbose)); 164*c3319070Sclaudio printf("logging request sent.\n"); 165*c3319070Sclaudio done = 1; 166*c3319070Sclaudio break; 16789189827Snorby case RELOAD: 16814d72cd0Spyr imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); 16989189827Snorby printf("reload request sent.\n"); 17089189827Snorby done = 1; 17189189827Snorby break; 17289189827Snorby } 17389189827Snorby 17489189827Snorby while (ibuf->w.queued) 17589189827Snorby if (msgbuf_write(&ibuf->w) < 0) 17689189827Snorby err(1, "write error"); 17789189827Snorby 17889189827Snorby while (!done) { 17989189827Snorby if ((n = imsg_read(ibuf)) == -1) 18089189827Snorby errx(1, "imsg_read error"); 18189189827Snorby if (n == 0) 18289189827Snorby errx(1, "pipe closed"); 18389189827Snorby 18489189827Snorby while (!done) { 18589189827Snorby if ((n = imsg_get(ibuf, &imsg)) == -1) 18689189827Snorby errx(1, "imsg_get error"); 18789189827Snorby if (n == 0) 18889189827Snorby break; 18989189827Snorby switch (res->action) { 19089189827Snorby case SHOW: 19189189827Snorby case SHOW_SUM: 19289189827Snorby done = show_summary_msg(&imsg); 19389189827Snorby break; 19489189827Snorby case SHOW_IFACE: 19589189827Snorby done = show_interface_msg(&imsg); 19689189827Snorby break; 19789189827Snorby case SHOW_IFACE_DTAIL: 19889189827Snorby done = show_interface_detail_msg(&imsg); 19989189827Snorby break; 20089189827Snorby case SHOW_IGMP: 20189189827Snorby done = show_igmp_msg(&imsg); 20289189827Snorby break; 20389189827Snorby case SHOW_NBR: 20489189827Snorby done = show_nbr_msg(&imsg); 20589189827Snorby break; 20689189827Snorby case SHOW_NBR_DTAIL: 20789189827Snorby done = show_nbr_detail_msg(&imsg); 20889189827Snorby break; 20989189827Snorby case SHOW_RIB: 21089189827Snorby done = show_rib_msg(&imsg); 21189189827Snorby break; 21289189827Snorby case SHOW_RIB_DTAIL: 21389189827Snorby done = show_rib_detail_msg(&imsg); 21489189827Snorby break; 21589189827Snorby case SHOW_MFC: 21689189827Snorby done = show_mfc_msg(&imsg); 21789189827Snorby break; 21889189827Snorby case SHOW_MFC_DTAIL: 21989189827Snorby done = show_mfc_detail_msg(&imsg); 22089189827Snorby break; 22189189827Snorby case NONE: 222*c3319070Sclaudio case LOG_VERBOSE: 223*c3319070Sclaudio case LOG_BRIEF: 22489189827Snorby case RELOAD: 22589189827Snorby break; 22689189827Snorby } 22789189827Snorby imsg_free(&imsg); 22889189827Snorby } 22989189827Snorby } 23089189827Snorby close(ctl_sock); 23189189827Snorby free(ibuf); 23289189827Snorby 23389189827Snorby return (0); 23489189827Snorby } 23589189827Snorby 23689189827Snorby int 23789189827Snorby show_summary_msg(struct imsg *imsg) 23889189827Snorby { 23989189827Snorby struct ctl_sum *sum; 24089189827Snorby 24189189827Snorby switch (imsg->hdr.type) { 24289189827Snorby case IMSG_CTL_SHOW_SUM: 24389189827Snorby sum = imsg->data; 24489189827Snorby printf("Router ID: %s\n", inet_ntoa(sum->rtr_id)); 24589189827Snorby printf("Hold time is %d sec(s)\n", sum->hold_time); 24689189827Snorby break; 24789189827Snorby case IMSG_CTL_END: 24889189827Snorby printf("\n"); 24989189827Snorby return (1); 25089189827Snorby default: 25189189827Snorby break; 25289189827Snorby } 25389189827Snorby 25489189827Snorby return (0); 25589189827Snorby } 25689189827Snorby 25789189827Snorby int 25889189827Snorby get_ifms_type(int mediatype) 25989189827Snorby { 26089189827Snorby switch (mediatype) { 26189189827Snorby case IFT_ETHER: 26289189827Snorby return (IFM_ETHER); 26389189827Snorby break; 26489189827Snorby case IFT_FDDI: 26589189827Snorby return (IFM_FDDI); 26689189827Snorby break; 26789189827Snorby case IFT_CARP: 26889189827Snorby return (IFM_CARP); 26989189827Snorby break; 27089189827Snorby default: 27189189827Snorby return (0); 27289189827Snorby break; 27389189827Snorby } 27489189827Snorby } 27589189827Snorby 27689189827Snorby int 27789189827Snorby show_interface_msg(struct imsg *imsg) 27889189827Snorby { 27989189827Snorby struct ctl_iface *iface; 28089189827Snorby char *netid; 28189189827Snorby 28289189827Snorby switch (imsg->hdr.type) { 28389189827Snorby case IMSG_CTL_SHOW_IFACE: 28489189827Snorby iface = imsg->data; 28589189827Snorby 28689189827Snorby if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), 28789189827Snorby mask2prefixlen(iface->mask.s_addr)) == -1) 28889189827Snorby err(1, NULL); 28989189827Snorby printf("%-11s %-18s %-10s %-10s %-10s %-8s %5d\n", 29089189827Snorby iface->name, netid, if_state_name(iface->state), 29189189827Snorby iface->probe_timer == 0 ? "00:00:00" : 29289189827Snorby fmt_timeframe_core(iface->probe_timer), 2930f617141Sclaudio get_linkstate(iface->mediatype, iface->linkstate), 2940f617141Sclaudio iface->uptime == 0 ? "00:00:00" : 29589189827Snorby fmt_timeframe_core(iface->uptime), iface->group_cnt); 29689189827Snorby free(netid); 29789189827Snorby break; 29889189827Snorby case IMSG_CTL_END: 29989189827Snorby printf("\n"); 30089189827Snorby return (1); 30189189827Snorby default: 30289189827Snorby break; 30389189827Snorby } 30489189827Snorby 30589189827Snorby return (0); 30689189827Snorby } 30789189827Snorby 30889189827Snorby int 30989189827Snorby show_interface_detail_msg(struct imsg *imsg) 31089189827Snorby { 31189189827Snorby struct ctl_iface *iface; 31289189827Snorby 31389189827Snorby switch (imsg->hdr.type) { 31489189827Snorby case IMSG_CTL_SHOW_IFACE: 31589189827Snorby iface = imsg->data; 31689189827Snorby 31789189827Snorby printf("\n"); 31889189827Snorby printf("Interface %s, line protocol is %s\n", 31989189827Snorby iface->name, print_link(iface->flags)); 32089189827Snorby printf(" Internet address %s/%d\n", 32189189827Snorby inet_ntoa(iface->addr), 32289189827Snorby mask2prefixlen(iface->mask.s_addr)); 32389189827Snorby printf(" Linkstate %s\n", 3240f617141Sclaudio get_linkstate(iface->mediatype, iface->linkstate)); 32589189827Snorby printf(" Network type %s, cost: %d\n", 32689189827Snorby if_type_name(iface->type), iface->metric); 32789189827Snorby printf(" State %s, querier ", if_state_name(iface->state)); 32889189827Snorby if (iface->state == IF_STA_QUERIER) 32989189827Snorby printf("%s\n", inet_ntoa(iface->addr)); 33089189827Snorby else 33189189827Snorby printf("%s\n", inet_ntoa(iface->querier)); 33289189827Snorby printf(" Generation ID %d\n", iface->gen_id); 33389189827Snorby printf(" Timer intervals configured, " 33489189827Snorby "probe %d, dead %d\n", iface->probe_interval, 33589189827Snorby iface->dead_interval); 33689189827Snorby if (iface->passive) 33789189827Snorby printf(" Passive interface (No Hellos)\n"); 33889189827Snorby else if (iface->probe_timer < 0) 33989189827Snorby printf(" Hello timer not running\n"); 34089189827Snorby else 34189189827Snorby printf(" Hello timer due in %s\n", 34289189827Snorby fmt_timeframe_core(iface->probe_timer)); 34389189827Snorby printf(" Uptime %s\n", iface->uptime == 0 ? 34489189827Snorby "00:00:00" : fmt_timeframe_core(iface->uptime)); 345b39d1d57Smichele printf(" Adjacent neighbor count is " 346b39d1d57Smichele "%d\n", iface->adj_cnt); 34789189827Snorby break; 34889189827Snorby case IMSG_CTL_END: 34989189827Snorby printf("\n"); 35089189827Snorby return (1); 35189189827Snorby default: 35289189827Snorby break; 35389189827Snorby } 35489189827Snorby 35589189827Snorby return (0); 35689189827Snorby } 35789189827Snorby 35889189827Snorby int 35989189827Snorby show_igmp_msg(struct imsg *imsg) 36089189827Snorby { 36189189827Snorby struct ctl_iface *iface; 36289189827Snorby struct ctl_group *group; 36389189827Snorby char *netid; 36489189827Snorby 36589189827Snorby switch (imsg->hdr.type) { 36689189827Snorby case IMSG_CTL_SHOW_IFACE: 36789189827Snorby iface = imsg->data; 36889189827Snorby if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr), 36989189827Snorby mask2prefixlen(iface->mask.s_addr)) == -1) 37089189827Snorby err(1, NULL); 37189189827Snorby printf("\nInterface %s, address %s, state %s, groups %d\n", 37289189827Snorby iface->name, netid, if_state_name(iface->state), 37389189827Snorby iface->group_cnt); 37489189827Snorby free(netid); 37589189827Snorby printf(" %-16s %-10s %-10s %-10s\n", "Group", "State", 37689189827Snorby "DeadTimer", "Uptime"); 37789189827Snorby break; 37889189827Snorby case IMSG_CTL_SHOW_IGMP: 37989189827Snorby group = imsg->data; 38089189827Snorby printf(" %-16s %-10s %-10s %-10s\n", inet_ntoa(group->addr), 38189189827Snorby group_state_name(group->state), 38289189827Snorby group->dead_timer == 0 ? "00:00:00" : 38389189827Snorby fmt_timeframe_core(group->dead_timer), 38489189827Snorby group->uptime == 0 ? "00:00:00" : 38589189827Snorby fmt_timeframe_core(group->uptime)); 38689189827Snorby break; 38789189827Snorby case IMSG_CTL_END: 38889189827Snorby printf("\n"); 38989189827Snorby return (1); 39089189827Snorby default: 39189189827Snorby break; 39289189827Snorby } 39389189827Snorby 39489189827Snorby return (0); 39589189827Snorby } 39689189827Snorby 39789189827Snorby const char * 39889189827Snorby print_if_type(enum iface_type type) 39989189827Snorby { 40089189827Snorby switch (type) { 40189189827Snorby case IF_TYPE_POINTOPOINT: 40289189827Snorby return ("POINTOPOINT"); 40389189827Snorby case IF_TYPE_BROADCAST: 40489189827Snorby return ("BROADCAST"); 40589189827Snorby default: 40689189827Snorby return ("UNKNOWN"); 40789189827Snorby } 40889189827Snorby } 40989189827Snorby 41089189827Snorby const char * 41189189827Snorby print_nbr_state(int state) 41289189827Snorby { 41389189827Snorby switch (state) { 41489189827Snorby case NBR_STA_DOWN: 41589189827Snorby return ("DOWN"); 41689189827Snorby case NBR_STA_1_WAY: 41789189827Snorby return ("1-WAY"); 41889189827Snorby case NBR_STA_2_WAY: 41989189827Snorby return ("2-WAY"); 42089189827Snorby default: 42189189827Snorby return ("UNKNOWN"); 42289189827Snorby } 42389189827Snorby } 42489189827Snorby 42589189827Snorby const char * 42689189827Snorby print_link(int state) 42789189827Snorby { 42889189827Snorby if (state & IFF_UP) 42989189827Snorby return ("UP"); 43089189827Snorby else 43189189827Snorby return ("DOWN"); 43289189827Snorby } 43389189827Snorby 43489189827Snorby #define TF_BUFS 8 43589189827Snorby #define TF_LEN 9 43689189827Snorby 43789189827Snorby const char * 43889189827Snorby fmt_timeframe(time_t t) 43989189827Snorby { 44089189827Snorby if (t == 0) 44189189827Snorby return ("Never"); 44289189827Snorby else 44389189827Snorby return (fmt_timeframe_core(time(NULL) - t)); 44489189827Snorby } 44589189827Snorby 44689189827Snorby const char * 44789189827Snorby fmt_timeframe_core(time_t t) 44889189827Snorby { 44989189827Snorby char *buf; 45089189827Snorby static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ 45189189827Snorby static int idx = 0; 452db93f2f1Sderaadt unsigned int sec, min, hrs, day, week; 45389189827Snorby 45489189827Snorby if (t == 0) 45589189827Snorby return ("Stopped"); 45689189827Snorby 45789189827Snorby buf = tfbuf[idx++]; 45889189827Snorby if (idx == TF_BUFS) 45989189827Snorby idx = 0; 46089189827Snorby 46189189827Snorby week = t; 46289189827Snorby 46389189827Snorby sec = week % 60; 46489189827Snorby week /= 60; 46589189827Snorby min = week % 60; 46689189827Snorby week /= 60; 46789189827Snorby hrs = week % 24; 46889189827Snorby week /= 24; 46989189827Snorby day = week % 7; 47089189827Snorby week /= 7; 47189189827Snorby 47289189827Snorby if (week > 0) 47389189827Snorby snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs); 47489189827Snorby else if (day > 0) 47589189827Snorby snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); 47689189827Snorby else 47789189827Snorby snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); 47889189827Snorby 47989189827Snorby return (buf); 48089189827Snorby } 48189189827Snorby 48289189827Snorby /* prototype defined in dvmrpd.h and shared with the kroute.c version */ 48389189827Snorby u_int8_t 48489189827Snorby mask2prefixlen(in_addr_t ina) 48589189827Snorby { 48689189827Snorby if (ina == 0) 48789189827Snorby return (0); 48889189827Snorby else 48989189827Snorby return (33 - ffs(ntohl(ina))); 49089189827Snorby } 49189189827Snorby 49289189827Snorby int 49389189827Snorby show_nbr_msg(struct imsg *imsg) 49489189827Snorby { 49589189827Snorby struct ctl_nbr *nbr; 49689189827Snorby 49789189827Snorby switch (imsg->hdr.type) { 49889189827Snorby case IMSG_CTL_SHOW_NBR: 49989189827Snorby nbr = imsg->data; 50089189827Snorby printf("%-15s %-10s %-10s", inet_ntoa(nbr->id), 50189189827Snorby print_nbr_state(nbr->state), 50289189827Snorby fmt_timeframe_core(nbr->dead_timer)); 50389189827Snorby printf("%-15s %-11s %s\n", inet_ntoa(nbr->addr), 50489189827Snorby nbr->name, fmt_timeframe_core(nbr->uptime)); 50589189827Snorby break; 50689189827Snorby case IMSG_CTL_END: 50789189827Snorby printf("\n"); 50889189827Snorby return (1); 50989189827Snorby default: 51089189827Snorby break; 51189189827Snorby } 51289189827Snorby 51389189827Snorby return (0); 51489189827Snorby } 51589189827Snorby 51689189827Snorby const char * 51789189827Snorby print_dvmrp_options(u_int8_t opts) 51889189827Snorby { 51989189827Snorby static char optbuf[32]; 52089189827Snorby 52189189827Snorby snprintf(optbuf, sizeof(optbuf), "*|*|%s|%s|%s|%s|%s|%s", 52289189827Snorby opts & DVMRP_CAP_NETMASK ? "N" : "-", 52389189827Snorby opts & DVMRP_CAP_SNMP ? "S" : "-", 52489189827Snorby opts & DVMRP_CAP_MTRACE ? "M" : "-", 52589189827Snorby opts & DVMRP_CAP_GENID ? "G" : "-", 52689189827Snorby opts & DVMRP_CAP_PRUNE ? "P" : "-", 52789189827Snorby opts & DVMRP_CAP_LEAF ? "L" : "-"); 52889189827Snorby return (optbuf); 52989189827Snorby } 53089189827Snorby 53189189827Snorby int 53289189827Snorby show_nbr_detail_msg(struct imsg *imsg) 53389189827Snorby { 53489189827Snorby struct ctl_nbr *nbr; 53589189827Snorby 53689189827Snorby switch (imsg->hdr.type) { 53789189827Snorby case IMSG_CTL_SHOW_NBR: 53889189827Snorby nbr = imsg->data; 53989189827Snorby break; 54089189827Snorby case IMSG_CTL_END: 54189189827Snorby printf("\n"); 54289189827Snorby return (1); 54389189827Snorby default: 54489189827Snorby break; 54589189827Snorby } 54689189827Snorby 54789189827Snorby return (0); 54889189827Snorby } 54989189827Snorby 55089189827Snorby int 55189189827Snorby show_rib_msg(struct imsg *imsg) 55289189827Snorby { 55389189827Snorby struct ctl_rt *rt; 55489189827Snorby char *dstnet; 55589189827Snorby 55689189827Snorby switch (imsg->hdr.type) { 55789189827Snorby case IMSG_CTL_SHOW_RIB: 55889189827Snorby rt = imsg->data; 55989189827Snorby if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix), 56089189827Snorby rt->prefixlen) == -1) 56189189827Snorby err(1, NULL); 56289189827Snorby 56389189827Snorby printf("%-20s %-17s %-7d %-9s %9s\n", dstnet, 56489189827Snorby inet_ntoa(rt->nexthop), 56589189827Snorby rt->cost, rt->uptime == 0 ? "-" : 56689189827Snorby fmt_timeframe_core(rt->uptime), 56789189827Snorby rt->expire == 0 ? "00:00:00" : 56889189827Snorby fmt_timeframe_core(rt->expire)); 56989189827Snorby free(dstnet); 57089189827Snorby 57189189827Snorby break; 57289189827Snorby case IMSG_CTL_END: 57389189827Snorby printf("\n"); 57489189827Snorby return (1); 57589189827Snorby default: 57689189827Snorby break; 57789189827Snorby } 57889189827Snorby 57989189827Snorby return (0); 58089189827Snorby } 58189189827Snorby 58289189827Snorby int 58389189827Snorby show_rib_detail_msg(struct imsg *imsg) 58489189827Snorby { 58589189827Snorby 58689189827Snorby switch (imsg->hdr.type) { 58789189827Snorby case IMSG_CTL_SHOW_RIB: 58889189827Snorby break; 58989189827Snorby case IMSG_CTL_END: 59089189827Snorby printf("\n"); 59189189827Snorby return (1); 59289189827Snorby default: 59389189827Snorby break; 59489189827Snorby } 59589189827Snorby 59689189827Snorby return (0); 59789189827Snorby } 59889189827Snorby 59989189827Snorby int 60089189827Snorby show_mfc_msg(struct imsg *imsg) 60189189827Snorby { 60289189827Snorby char iname[IF_NAMESIZE]; 60389189827Snorby char oname[IF_NAMESIZE] = "-"; 60489189827Snorby struct ctl_mfc *mfc; 60589189827Snorby int i; 60689189827Snorby 60789189827Snorby 60889189827Snorby switch (imsg->hdr.type) { 60989189827Snorby case IMSG_CTL_SHOW_MFC: 61089189827Snorby mfc = imsg->data; 61189189827Snorby if_indextoname(mfc->ifindex, iname); 61289189827Snorby 61389189827Snorby /* search for first entry with ttl > 0 */ 61489189827Snorby for (i = 0; i < MAXVIFS; i++) { 61589189827Snorby if (mfc->ttls[i] > 0) { 61689189827Snorby if_indextoname(i, oname); 61789189827Snorby i++; 61889189827Snorby break; 61989189827Snorby } 62089189827Snorby } 62189189827Snorby 62289189827Snorby /* display first entry with uptime */ 62389189827Snorby printf("%-16s ", inet_ntoa(mfc->group)); 62489189827Snorby printf("%-16s %-9s %-9s %-4d %-10s %-10s\n", 62589189827Snorby inet_ntoa(mfc->origin), iname, oname, mfc->ttls[i - 1], 62689189827Snorby mfc->uptime == 0 ? "-" : fmt_timeframe_core(mfc->uptime), 62789189827Snorby mfc->expire == 0 ? "-" : fmt_timeframe_core(mfc->expire)); 62889189827Snorby 62989189827Snorby /* display remaining entries with ttl > 0 */ 63089189827Snorby for (; i < MAXVIFS; i++) { 63189189827Snorby if (mfc->ttls[i] > 0) { 63289189827Snorby if_indextoname(i, oname); 63389189827Snorby printf("%43s %-9s %-4d\n", " ", oname, 63489189827Snorby mfc->ttls[i]); 63589189827Snorby } 63689189827Snorby } 63789189827Snorby break; 63889189827Snorby case IMSG_CTL_END: 63989189827Snorby printf("\n"); 64089189827Snorby return (1); 64189189827Snorby default: 64289189827Snorby break; 64389189827Snorby } 64489189827Snorby 64589189827Snorby return (0); 64689189827Snorby } 64789189827Snorby 64889189827Snorby int 64989189827Snorby show_mfc_detail_msg(struct imsg *imsg) 65089189827Snorby { 65189189827Snorby 65289189827Snorby switch (imsg->hdr.type) { 65389189827Snorby case IMSG_CTL_SHOW_MFC: 65489189827Snorby break; 65589189827Snorby case IMSG_CTL_END: 65689189827Snorby printf("\n"); 65789189827Snorby return (1); 65889189827Snorby default: 65989189827Snorby break; 66089189827Snorby } 66189189827Snorby 66289189827Snorby return (0); 66389189827Snorby } 66489189827Snorby 6650f617141Sclaudio const struct if_status_description 6660f617141Sclaudio if_status_descriptions[] = LINK_STATE_DESCRIPTIONS; 66789189827Snorby 66889189827Snorby const char * 66989189827Snorby get_linkstate(int media_type, int link_state) 67089189827Snorby { 6710f617141Sclaudio const struct if_status_description *p; 6720f617141Sclaudio static char buf[8]; 67389189827Snorby 6740f617141Sclaudio for (p = if_status_descriptions; p->ifs_string != NULL; p++) { 6750f617141Sclaudio if (LINK_STATE_DESC_MATCH(p, media_type, link_state)) 6760f617141Sclaudio return (p->ifs_string); 67789189827Snorby } 6780f617141Sclaudio snprintf(buf, sizeof(buf), "[#%d]", link_state); 6790f617141Sclaudio return (buf); 68089189827Snorby } 681