Home | History | Annotate | Line # | Download | only in route
show.c revision 1.14.4.2
      1  1.14.4.2        he /*	$NetBSD: show.c,v 1.14.4.2 2001/04/05 12:33:54 he Exp $	*/
      2       1.1       gwr 
      3       1.1       gwr /*
      4       1.1       gwr  * Copyright (c) 1983, 1988, 1993
      5       1.1       gwr  *	The Regents of the University of California.  All rights reserved.
      6       1.1       gwr  *
      7       1.1       gwr  * Redistribution and use in source and binary forms, with or without
      8       1.1       gwr  * modification, are permitted provided that the following conditions
      9       1.1       gwr  * are met:
     10       1.1       gwr  * 1. Redistributions of source code must retain the above copyright
     11       1.1       gwr  *    notice, this list of conditions and the following disclaimer.
     12       1.1       gwr  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1       gwr  *    notice, this list of conditions and the following disclaimer in the
     14       1.1       gwr  *    documentation and/or other materials provided with the distribution.
     15       1.1       gwr  * 3. All advertising materials mentioning features or use of this software
     16       1.1       gwr  *    must display the following acknowledgement:
     17       1.1       gwr  *	This product includes software developed by the University of
     18       1.1       gwr  *	California, Berkeley and its contributors.
     19       1.1       gwr  * 4. Neither the name of the University nor the names of its contributors
     20       1.1       gwr  *    may be used to endorse or promote products derived from this software
     21       1.1       gwr  *    without specific prior written permission.
     22       1.1       gwr  *
     23       1.1       gwr  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24       1.1       gwr  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25       1.1       gwr  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26       1.1       gwr  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27       1.1       gwr  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28       1.1       gwr  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29       1.1       gwr  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30       1.1       gwr  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31       1.1       gwr  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32       1.1       gwr  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33       1.1       gwr  * SUCH DAMAGE.
     34       1.1       gwr  */
     35       1.1       gwr 
     36       1.4     lukem #include <sys/cdefs.h>
     37       1.1       gwr #ifndef lint
     38       1.1       gwr #if 0
     39       1.1       gwr static char sccsid[] = "from: @(#)route.c	8.3 (Berkeley) 3/9/94";
     40       1.1       gwr #else
     41  1.14.4.2        he __RCSID("$NetBSD: show.c,v 1.14.4.2 2001/04/05 12:33:54 he Exp $");
     42       1.1       gwr #endif
     43       1.1       gwr #endif /* not lint */
     44       1.1       gwr 
     45       1.1       gwr #include <sys/param.h>
     46       1.1       gwr #include <sys/protosw.h>
     47       1.1       gwr #include <sys/socket.h>
     48       1.1       gwr #include <sys/mbuf.h>
     49       1.1       gwr 
     50       1.1       gwr #include <net/if.h>
     51       1.1       gwr #include <net/if_dl.h>
     52       1.1       gwr #include <net/if_types.h>
     53       1.1       gwr #include <net/route.h>
     54       1.1       gwr #include <netinet/in.h>
     55       1.1       gwr #include <netns/ns.h>
     56       1.1       gwr 
     57       1.1       gwr #include <sys/sysctl.h>
     58       1.1       gwr 
     59       1.1       gwr #include <netdb.h>
     60       1.1       gwr #include <stdio.h>
     61       1.1       gwr #include <stdlib.h>
     62       1.1       gwr #include <string.h>
     63       1.1       gwr #include <unistd.h>
     64       1.5  christos #include <err.h>
     65       1.1       gwr 
     66       1.2  christos #include "extern.h"
     67       1.1       gwr 
     68      1.12    itojun #define ROUNDUP(a) \
     69      1.12    itojun 	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
     70      1.12    itojun #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
     71      1.12    itojun 
     72       1.1       gwr /*
     73       1.1       gwr  * Definitions for showing gateway flags.
     74       1.1       gwr  */
     75       1.1       gwr struct bits {
     76       1.1       gwr 	short	b_mask;
     77       1.1       gwr 	char	b_val;
     78       1.1       gwr };
     79       1.1       gwr static const struct bits bits[] = {
     80       1.1       gwr 	{ RTF_UP,	'U' },
     81       1.1       gwr 	{ RTF_GATEWAY,	'G' },
     82       1.1       gwr 	{ RTF_HOST,	'H' },
     83       1.1       gwr 	{ RTF_REJECT,	'R' },
     84       1.1       gwr 	{ RTF_DYNAMIC,	'D' },
     85       1.1       gwr 	{ RTF_MODIFIED,	'M' },
     86       1.1       gwr 	{ RTF_DONE,	'd' }, /* Completed -- for routing messages only */
     87       1.1       gwr 	{ RTF_MASK,	'm' }, /* Mask Present -- for routing messages only */
     88       1.1       gwr 	{ RTF_CLONING,	'C' },
     89       1.1       gwr 	{ RTF_XRESOLVE,	'X' },
     90       1.1       gwr 	{ RTF_LLINFO,	'L' },
     91       1.1       gwr 	{ RTF_STATIC,	'S' },
     92  1.14.4.2        he 	{ RTF_BLACKHOLE, 'B' },
     93       1.1       gwr 	{ RTF_PROTO1,	'1' },
     94       1.1       gwr 	{ RTF_PROTO2,	'2' },
     95       1.1       gwr 	{ 0 }
     96       1.1       gwr };
     97       1.1       gwr 
     98       1.2  christos static void pr_rthdr __P((void));
     99       1.1       gwr static void p_rtentry __P((struct rt_msghdr *));
    100       1.2  christos static void pr_family __P((int));
    101       1.2  christos static void p_sockaddr __P((struct sockaddr *, int, int ));
    102  1.14.4.1        tv static void p_flags __P((int));
    103       1.1       gwr 
    104       1.1       gwr /*
    105       1.1       gwr  * Print routing tables.
    106       1.1       gwr  */
    107       1.1       gwr void
    108       1.1       gwr show(argc, argv)
    109       1.1       gwr 	int argc;
    110       1.1       gwr 	char **argv;
    111       1.1       gwr {
    112       1.1       gwr 	size_t needed;
    113       1.1       gwr 	int mib[6];
    114       1.1       gwr 	char *buf, *next, *lim;
    115       1.4     lukem 	struct rt_msghdr *rtm;
    116       1.1       gwr 
    117       1.1       gwr 	mib[0] = CTL_NET;
    118       1.1       gwr 	mib[1] = PF_ROUTE;
    119       1.1       gwr 	mib[2] = 0;
    120       1.1       gwr 	mib[3] = 0;
    121       1.1       gwr 	mib[4] = NET_RT_DUMP;
    122       1.1       gwr 	mib[5] = 0;
    123       1.1       gwr 	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)	{
    124       1.1       gwr 		perror("route-sysctl-estimate");
    125       1.1       gwr 		exit(1);
    126       1.1       gwr 	}
    127       1.5  christos 	if ((buf = malloc(needed)) == 0)
    128      1.14  drochner 		err(1, NULL);
    129       1.5  christos 	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
    130       1.5  christos 		err(1, "sysctl of routing table");
    131       1.1       gwr 	lim  = buf + needed;
    132       1.1       gwr 
    133       1.1       gwr 	printf("Routing tables\n");
    134       1.1       gwr 
    135       1.1       gwr 	/* for (i = 0; i <= AF_MAX; i++) ??? */
    136       1.1       gwr 	{
    137       1.1       gwr 		for (next = buf; next < lim; next += rtm->rtm_msglen) {
    138       1.1       gwr 			rtm = (struct rt_msghdr *)next;
    139       1.1       gwr 			p_rtentry(rtm);
    140       1.1       gwr 		}
    141       1.1       gwr 	}
    142       1.1       gwr }
    143       1.1       gwr 
    144       1.1       gwr 
    145       1.1       gwr /* column widths; each followed by one space */
    146       1.1       gwr #define	WID_DST		16	/* width of destination column */
    147       1.1       gwr #define	WID_GW		18	/* width of gateway column */
    148       1.1       gwr 
    149       1.1       gwr /*
    150       1.1       gwr  * Print header for routing table columns.
    151       1.1       gwr  */
    152       1.1       gwr static void
    153       1.1       gwr pr_rthdr()
    154       1.1       gwr {
    155       1.1       gwr 
    156       1.1       gwr 	printf("%-*.*s %-*.*s %-6.6s\n",
    157       1.1       gwr 		WID_DST, WID_DST, "Destination",
    158       1.1       gwr 		WID_GW, WID_GW, "Gateway",
    159       1.1       gwr 		"Flags");
    160       1.1       gwr }
    161       1.1       gwr 
    162       1.1       gwr 
    163       1.1       gwr /*
    164       1.1       gwr  * Print a routing table entry.
    165       1.1       gwr  */
    166       1.1       gwr static void
    167       1.1       gwr p_rtentry(rtm)
    168       1.4     lukem 	struct rt_msghdr *rtm;
    169       1.1       gwr {
    170       1.4     lukem 	struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
    171       1.1       gwr #ifdef notdef
    172       1.1       gwr 	static int masks_done, banner_printed;
    173       1.1       gwr #endif
    174       1.1       gwr 	static int old_af;
    175       1.1       gwr 	int af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST;
    176       1.1       gwr 
    177       1.1       gwr #ifdef notdef
    178       1.1       gwr 	/* for the moment, netmasks are skipped over */
    179       1.1       gwr 	if (!banner_printed) {
    180       1.1       gwr 		printf("Netmasks:\n");
    181       1.1       gwr 		banner_printed = 1;
    182       1.1       gwr 	}
    183       1.1       gwr 	if (masks_done == 0) {
    184       1.1       gwr 		if (rtm->rtm_addrs != RTA_DST ) {
    185       1.1       gwr 			masks_done = 1;
    186       1.1       gwr 			af = sa->sa_family;
    187       1.1       gwr 		}
    188       1.1       gwr 	} else
    189       1.1       gwr #endif
    190       1.1       gwr 		af = sa->sa_family;
    191       1.1       gwr 	if (old_af != af) {
    192       1.1       gwr 		old_af = af;
    193       1.1       gwr 		pr_family(af);
    194       1.1       gwr 		pr_rthdr();
    195       1.1       gwr 	}
    196       1.1       gwr 	if (rtm->rtm_addrs == RTA_DST)
    197      1.10    itojun 		p_sockaddr(sa, 0, WID_DST + 1 + WID_GW + 1);
    198       1.1       gwr 	else {
    199      1.10    itojun 		p_sockaddr(sa, rtm->rtm_flags, WID_DST);
    200      1.12    itojun 		sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
    201      1.10    itojun 		p_sockaddr(sa, 0, WID_GW);
    202       1.1       gwr 	}
    203  1.14.4.1        tv 	p_flags(rtm->rtm_flags & interesting);
    204       1.1       gwr 	putchar('\n');
    205       1.1       gwr }
    206       1.1       gwr 
    207       1.1       gwr 
    208       1.1       gwr /*
    209       1.1       gwr  * Print address family header before a section of the routing table.
    210       1.1       gwr  */
    211       1.1       gwr static void
    212       1.1       gwr pr_family(af)
    213       1.1       gwr 	int af;
    214       1.1       gwr {
    215       1.1       gwr 	char *afname;
    216       1.1       gwr 
    217       1.1       gwr 	switch (af) {
    218       1.1       gwr 	case AF_INET:
    219       1.1       gwr 		afname = "Internet";
    220       1.1       gwr 		break;
    221       1.1       gwr #ifndef SMALL
    222       1.9    itojun #ifdef INET6
    223       1.9    itojun 	case AF_INET6:
    224       1.9    itojun 		afname = "Internet6";
    225       1.9    itojun 		break;
    226       1.9    itojun #endif /* INET6 */
    227       1.1       gwr 	case AF_NS:
    228       1.1       gwr 		afname = "XNS";
    229       1.1       gwr 		break;
    230       1.1       gwr 	case AF_ISO:
    231       1.1       gwr 		afname = "ISO";
    232       1.1       gwr 		break;
    233       1.1       gwr 	case AF_CCITT:
    234       1.1       gwr 		afname = "X.25";
    235       1.6    kleink 		break;
    236       1.8     lukem #endif /* SMALL */
    237       1.6    kleink 	case AF_APPLETALK:
    238       1.6    kleink 		afname = "AppleTalk";
    239       1.1       gwr 		break;
    240       1.1       gwr 	default:
    241       1.1       gwr 		afname = NULL;
    242       1.1       gwr 		break;
    243       1.1       gwr 	}
    244       1.1       gwr 	if (afname)
    245       1.1       gwr 		printf("\n%s:\n", afname);
    246       1.1       gwr 	else
    247       1.1       gwr 		printf("\nProtocol Family %d:\n", af);
    248       1.1       gwr }
    249       1.1       gwr 
    250       1.1       gwr 
    251       1.1       gwr static void
    252       1.1       gwr p_sockaddr(sa, flags, width)
    253       1.1       gwr 	struct sockaddr *sa;
    254       1.1       gwr 	int flags, width;
    255       1.1       gwr {
    256       1.1       gwr 	char workbuf[128], *cplim;
    257       1.4     lukem 	char *cp = workbuf;
    258       1.3       mrg 	int cplen = 0, len;
    259       1.1       gwr 
    260       1.1       gwr 	switch(sa->sa_family) {
    261       1.1       gwr 
    262       1.1       gwr 	case AF_LINK:
    263       1.1       gwr 	    {
    264       1.4     lukem 		struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
    265       1.1       gwr 
    266       1.1       gwr 		if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 &&
    267       1.1       gwr 		    sdl->sdl_slen == 0)
    268       1.3       mrg 			(void)snprintf(workbuf, sizeof workbuf, "link#%d",
    269       1.3       mrg 			    sdl->sdl_index);
    270       1.1       gwr 		else switch (sdl->sdl_type) {
    271       1.1       gwr 		case IFT_ETHER:
    272       1.1       gwr 		    {
    273       1.4     lukem 			int i;
    274       1.4     lukem 			u_char *lla = (u_char *)sdl->sdl_data +
    275       1.1       gwr 			    sdl->sdl_nlen;
    276       1.1       gwr 
    277       1.1       gwr 			cplim = "";
    278       1.1       gwr 			for (i = 0; i < sdl->sdl_alen; i++, lla++) {
    279       1.3       mrg 				len = snprintf(cp, sizeof(workbuf) - cplen,
    280       1.3       mrg 				    "%s%x", cplim, *lla);
    281       1.3       mrg 				cp += len;
    282       1.3       mrg 				cplen += len;
    283       1.1       gwr 				cplim = ":";
    284       1.1       gwr 			}
    285       1.1       gwr 			cp = workbuf;
    286       1.1       gwr 			break;
    287       1.1       gwr 		    }
    288       1.1       gwr 		default:
    289       1.1       gwr 			cp = link_ntoa(sdl);
    290       1.1       gwr 			break;
    291       1.1       gwr 		}
    292       1.1       gwr 		break;
    293       1.1       gwr 	    }
    294       1.1       gwr 
    295       1.1       gwr 	case AF_INET:
    296       1.1       gwr 	    {
    297       1.4     lukem 		struct sockaddr_in *sin = (struct sockaddr_in *)sa;
    298       1.1       gwr 
    299       1.1       gwr 		cp = (sin->sin_addr.s_addr == 0) ? "default" :
    300       1.1       gwr 			((flags & RTF_HOST) ?
    301       1.1       gwr 			routename(sa) :	netname(sa));
    302       1.1       gwr 		break;
    303       1.1       gwr 	    }
    304       1.1       gwr 
    305       1.1       gwr #ifndef SMALL
    306       1.9    itojun #ifdef INET6
    307       1.9    itojun 	case AF_INET6:
    308       1.9    itojun 	    {
    309       1.9    itojun 		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
    310       1.9    itojun 
    311      1.12    itojun 		cp = IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr) ? "default" :
    312       1.9    itojun 			((flags & RTF_HOST) ?
    313       1.9    itojun 			routename(sa) :	netname(sa));
    314      1.11    itojun 		/* make sure numeric address is not truncated */
    315      1.11    itojun 		if (strchr(cp, ':') != NULL && strlen(cp) > width)
    316      1.11    itojun 			width = strlen(cp);
    317       1.9    itojun 		break;
    318       1.9    itojun 	    }
    319       1.9    itojun #endif /* INET6 */
    320       1.9    itojun 
    321       1.1       gwr 	case AF_NS:
    322       1.1       gwr 		cp = ns_print((struct sockaddr_ns *)sa);
    323       1.1       gwr 		break;
    324       1.1       gwr #endif /* SMALL */
    325       1.1       gwr 
    326       1.1       gwr 	default:
    327       1.1       gwr 	    {
    328       1.4     lukem 		u_char *s = (u_char *)sa->sa_data, *slim;
    329       1.1       gwr 
    330      1.13    itojun 		slim = sa->sa_len + (u_char *) sa;
    331       1.1       gwr 		cplim = cp + sizeof(workbuf) - 6;
    332       1.7   mycroft 		cp += snprintf(cp, cplim - cp, "(%d)", sa->sa_family);
    333       1.1       gwr 		while (s < slim && cp < cplim) {
    334       1.7   mycroft 			cp += snprintf(cp, cplim - cp, " %02x", *s++);
    335       1.1       gwr 			if (s < slim)
    336       1.7   mycroft 			    cp += snprintf(cp, cplim - cp, "%02x", *s++);
    337       1.1       gwr 		}
    338       1.1       gwr 		cp = workbuf;
    339       1.1       gwr 	    }
    340       1.1       gwr 	}
    341       1.1       gwr 	if (width < 0 )
    342       1.1       gwr 		printf("%s ", cp);
    343       1.1       gwr 	else {
    344       1.1       gwr 		if (nflag)
    345       1.1       gwr 			printf("%-*s ", width, cp);
    346       1.1       gwr 		else
    347       1.1       gwr 			printf("%-*.*s ", width, width, cp);
    348       1.1       gwr 	}
    349       1.1       gwr }
    350       1.1       gwr 
    351       1.1       gwr static void
    352  1.14.4.1        tv p_flags(f)
    353       1.4     lukem 	int f;
    354       1.1       gwr {
    355       1.1       gwr 	char name[33], *flags;
    356       1.4     lukem 	const struct bits *p = bits;
    357       1.1       gwr 
    358       1.1       gwr 	for (flags = name; p->b_mask; p++)
    359       1.1       gwr 		if (p->b_mask & f)
    360       1.1       gwr 			*flags++ = p->b_val;
    361       1.1       gwr 	*flags = '\0';
    362  1.14.4.1        tv 	printf("%-6.6s ", name);
    363       1.1       gwr }
    364       1.1       gwr 
    365