xref: /openbsd/usr.sbin/dvmrpctl/dvmrpctl.c (revision c3319070)
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