diff options
-rw-r--r-- | sbin/route/Makefile | 16 | ||||
-rw-r--r-- | sbin/route/keywords.c | 56 | ||||
-rw-r--r-- | sbin/route/keywords.h | 55 | ||||
-rw-r--r-- | sbin/route/keywords.sh | 119 | ||||
-rw-r--r-- | sbin/route/route.8 | 7 | ||||
-rw-r--r-- | sbin/route/route.c | 220 | ||||
-rw-r--r-- | sbin/route/show.c | 334 |
7 files changed, 679 insertions, 128 deletions
diff --git a/sbin/route/Makefile b/sbin/route/Makefile index 52850f568b4..c36b4154276 100644 --- a/sbin/route/Makefile +++ b/sbin/route/Makefile @@ -1,24 +1,12 @@ -# $OpenBSD: Makefile,v 1.2 1996/06/23 14:32:20 deraadt Exp $ +# $OpenBSD: Makefile,v 1.3 1996/12/14 17:23:51 deraadt Exp $ # $NetBSD: Makefile,v 1.12 1995/04/19 09:08:28 cgd Exp $ PROG= route MAN= route.8 -SRCS= route.c ccitt_addr.c -CFLAGS+=-I. -CLEANFILES+=keywords.h +SRCS= route.c show.c keywords.c ccitt_addr.c BINOWN= root BINMODE=4555 -keywords.h: keywords - sed -e '/^#/d' -e '/^$$/d' ${.CURDIR}/keywords > _keywords.tmp - tr a-z A-Z < _keywords.tmp | paste _keywords.tmp - | \ - awk '{ \ - if (NF > 1) \ - printf "#define\tK_%s\t%d\n\t{\"%s\", K_%s},\n", \ - $$2, NR, $$1, $$2 }' \ - > ${.TARGET} - rm -f _keywords.tmp - route.o .depend lint tags: keywords.h .include <bsd.prog.mk> diff --git a/sbin/route/keywords.c b/sbin/route/keywords.c new file mode 100644 index 00000000000..d025dd97798 --- /dev/null +++ b/sbin/route/keywords.c @@ -0,0 +1,56 @@ +/* $NetBSD$ */ + +/* WARNING! This file was generated by keywords.sh */ + +#include "keywords.h" + +struct keytab keywords[] = { + + {"add", K_ADD}, + {"blackhole", K_BLACKHOLE}, + {"change", K_CHANGE}, + {"cloning", K_CLONING}, + {"delete", K_DELETE}, + {"dst", K_DST}, + {"expire", K_EXPIRE}, + {"flush", K_FLUSH}, + {"gateway", K_GATEWAY}, + {"genmask", K_GENMASK}, + {"get", K_GET}, + {"host", K_HOST}, + {"hopcount", K_HOPCOUNT}, + {"iface", K_IFACE}, + {"interface", K_INTERFACE}, + {"ifa", K_IFA}, + {"ifp", K_IFP}, + {"inet", K_INET}, + {"ipx", K_IPX}, + {"iso", K_ISO}, + {"link", K_LINK}, + {"llinfo", K_LLINFO}, + {"lock", K_LOCK}, + {"lockrest", K_LOCKREST}, + {"mask", K_MASK}, + {"monitor", K_MONITOR}, + {"mtu", K_MTU}, + {"net", K_NET}, + {"netmask", K_NETMASK}, + {"nostatic", K_NOSTATIC}, + {"osi", K_OSI}, + {"proto1", K_PROTO1}, + {"proto2", K_PROTO2}, + {"recvpipe", K_RECVPIPE}, + {"reject", K_REJECT}, + {"rtt", K_RTT}, + {"rttvar", K_RTTVAR}, + {"sa", K_SA}, + {"sendpipe", K_SENDPIPE}, + {"show", K_SHOW}, + {"ssthresh", K_SSTHRESH}, + {"static", K_STATIC}, + {"x25", K_X25}, + {"xns", K_XNS}, + {"xresolve", K_XRESOLVE}, + {0, 0} +}; + diff --git a/sbin/route/keywords.h b/sbin/route/keywords.h new file mode 100644 index 00000000000..764f8bd8d63 --- /dev/null +++ b/sbin/route/keywords.h @@ -0,0 +1,55 @@ +/* $NetBSD$ */ + +/* WARNING! This file was generated by keywords.sh */ + +struct keytab { + char *kt_cp; + int kt_i; +} keywords[]; + + +#define K_ADD 1 +#define K_BLACKHOLE 2 +#define K_CHANGE 3 +#define K_CLONING 4 +#define K_DELETE 5 +#define K_DST 6 +#define K_EXPIRE 7 +#define K_FLUSH 8 +#define K_GATEWAY 9 +#define K_GENMASK 10 +#define K_GET 11 +#define K_HOST 12 +#define K_HOPCOUNT 13 +#define K_IFACE 14 +#define K_INTERFACE 15 +#define K_IFA 16 +#define K_IFP 17 +#define K_INET 18 +#define K_IPX 19 +#define K_ISO 20 +#define K_LINK 21 +#define K_LLINFO 22 +#define K_LOCK 23 +#define K_LOCKREST 24 +#define K_MASK 25 +#define K_MONITOR 26 +#define K_MTU 27 +#define K_NET 28 +#define K_NETMASK 29 +#define K_NOSTATIC 30 +#define K_OSI 31 +#define K_PROTO1 32 +#define K_PROTO2 33 +#define K_RECVPIPE 34 +#define K_REJECT 35 +#define K_RTT 36 +#define K_RTTVAR 37 +#define K_SA 38 +#define K_SENDPIPE 39 +#define K_SHOW 40 +#define K_SSTHRESH 41 +#define K_STATIC 42 +#define K_X25 43 +#define K_XNS 44 +#define K_XRESOLVE 45 diff --git a/sbin/route/keywords.sh b/sbin/route/keywords.sh new file mode 100644 index 00000000000..354366d8733 --- /dev/null +++ b/sbin/route/keywords.sh @@ -0,0 +1,119 @@ +#!/bin/sh +# $NetBSD: keywords.sh,v 1.2 1996/11/15 18:57:21 gwr Exp $ +# @(#)keywords 8.2 (Berkeley) 3/19/94 +# +# WARNING! If you change this file, re-run it! + +# This program requires "new" awk (or GNU awk). +awk=${AWK:-awk} + +cat << _EOF_ > _keywords.t1 +add +blackhole +change +cloning +delete +dst +expire +flush +gateway +genmask +get +host +hopcount +iface +interface +ifa +ifp +inet +ipx +iso +link +llinfo +lock +lockrest +mask +monitor +mtu +net +netmask +nostatic +osi +proto1 +proto2 +recvpipe +reject +rtt +rttvar +sa +sendpipe +show +ssthresh +static +x25 +xns +xresolve +_EOF_ + + +################################################################ +# Setup +################################################################ + +# This creates a stream of: +# keyword KEYWORD +# (lower case, upper case). +tr a-z A-Z < _keywords.t1 | +paste _keywords.t1 - > _keywords.t2 + + +################################################################ +# Generate the h file +################################################################ +exec > keywords.h + +echo '/* $'NetBSD'$ */ + +/* WARNING! This file was generated by keywords.sh */ + +struct keytab { + char *kt_cp; + int kt_i; +} keywords[]; + +' # defines follow + +$awk '{ + printf("#define\tK_%s\t%d\n", $2, NR); +}' < _keywords.t2 + + +################################################################ +# Generate the c file +################################################################ +exec > keywords.c + +echo '/* $'NetBSD'$ */ + +/* WARNING! This file was generated by keywords.sh */ + +#include "keywords.h" + +struct keytab keywords[] = { +' # initializers follow + +$awk '{ + printf("\t{\"%s\", K_%s},\n", $1, $2); +}' < _keywords.t2 + +echo ' {0, 0} +}; +' # tail + + +################################################################ +# Cleanup +################################################################ + +rm -f _keywords.t1 _keywords.t2 +exit 0 diff --git a/sbin/route/route.8 b/sbin/route/route.8 index 4d78598f60a..ef3fe83fcd0 100644 --- a/sbin/route/route.8 +++ b/sbin/route/route.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: route.8,v 1.3 1996/08/16 09:26:10 mickey Exp $ +.\" $OpenBSD: route.8,v 1.4 1996/12/14 17:23:53 deraadt Exp $ .\" $NetBSD: route.8,v 1.6 1995/03/18 15:00:13 cgd Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 @@ -79,7 +79,7 @@ Suppress all output. .Pp The .Nm route : -utility provides six commands: +utility provides several commands: .Pp .Bl -tag -width Fl -compact .It Cm add @@ -92,6 +92,9 @@ Delete a specific route. Change aspects of a route (such as its gateway). .It Cm get Lookup and display the route for a destination. +.It Cm show +Print out the route table similar to "netstat \-r" (see +.Xr netstat 8 ). .It Cm monitor Continuously report any changes to the routing information base, routing lookup misses, or suspected network partitionings. diff --git a/sbin/route/route.c b/sbin/route/route.c index 630b009cb22..5fc11352b8e 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.12 1996/11/25 03:57:56 deraadt Exp $ */ +/* $OpenBSD: route.c,v 1.13 1996/12/14 17:23:54 deraadt Exp $ */ /* $NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $ */ /* @@ -44,7 +44,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)route.c 8.3 (Berkeley) 3/19/94"; #else -static char rcsid[] = "$OpenBSD: route.c,v 1.12 1996/11/25 03:57:56 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: route.c,v 1.13 1996/12/14 17:23:54 deraadt Exp $"; #endif #endif /* not lint */ @@ -74,13 +74,7 @@ static char rcsid[] = "$OpenBSD: route.c,v 1.12 1996/11/25 03:57:56 deraadt Exp #include <string.h> #include <paths.h> -struct keytab { - char *kt_cp; - int kt_i; -} keywords[] = { #include "keywords.h" - {0, 0} -}; struct ortentry route; union sockunion { @@ -103,10 +97,12 @@ struct rt_metrics rt_metrics; u_long rtm_inits; struct in_addr inet_makeaddr(); char *routename(), *netname(); -void flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf(); -void print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr(); +void flushroutes(), newroute(), monitor(), sockaddr(), sodump(); +void print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(); +void bprintf(), mask_addr(); int getaddr(), rtmsg(), x25_makemask(); extern char *inet_ntoa(), *iso_ntoa(), *link_ntoa(); +extern void show(); __dead void usage(cp) @@ -181,30 +177,33 @@ main(argc, argv) setuid(uid); if (s < 0) quit("socket"); - if (*argv) - switch (keyword(*argv)) { - case K_GET: - uid = 0; - /* FALLTHROUGH */ - - case K_CHANGE: - case K_ADD: - case K_DELETE: - newroute(argc, argv); - exit(0); - /* NOTREACHED */ - - case K_MONITOR: - monitor(); - /* NOTREACHED */ - - case K_FLUSH: - flushroutes(argc, argv); - exit(0); - /* NOTREACHED */ - } - usage(*argv); - /* NOTREACHED */ + if (*argv == NULL) + goto no_cmd; + switch (keyword(*argv)) { + case K_GET: + uid = 0; + /* FALLTHROUGH */ + case K_CHANGE: + case K_ADD: + case K_DELETE: + newroute(argc, argv); + break; + case K_SHOW: + uid = 0; + show(argc, argv); + break; + case K_MONITOR: + monitor(); + break; + case K_FLUSH: + flushroutes(argc, argv); + break; + no_cmd: + default: + usage(*argv); + return 1; + } + return 0; } /* @@ -266,8 +265,11 @@ bad: usage(*argv); if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) quit("actual retrieval of routing table"); lim = buf + needed; - if (verbose) + if (verbose) { (void) printf("Examining routing table from sysctl\n"); + if (af) + printf("(address family %s)\n", (*argv + 1)); + } seqno = 0; /* ??? */ for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; @@ -309,25 +311,47 @@ bad: usage(*argv); } } +static char hexlist[] = "0123456789abcdef"; + +char * +any_ntoa(sa) + const struct sockaddr *sa; +{ + static char obuf[240]; + const char *in = sa->sa_data; + char *out = obuf; + int len = sa->sa_len; + + *out++ = 'Q'; + do { + *out++ = hexlist[(*in >> 4) & 15]; + *out++ = hexlist[(*in++) & 15]; + *out++ = '.'; + } while (--len > 0 && (out + 3) < &obuf[sizeof obuf-1]); + out[-1] = '\0'; + return (obuf); +} + char * routename(sa) struct sockaddr *sa; { - register char *cp; + register char *cp = NULL; static char line[MAXHOSTNAMELEN]; struct hostent *hp; - static char domain[MAXHOSTNAMELEN + 1]; + static char domain[MAXHOSTNAMELEN]; static int first = 1; char *ns_print(); char *ipx_print(); if (first) { first = 0; - if (gethostname(domain, MAXHOSTNAMELEN) == 0 && + if (gethostname(domain, sizeof domain) == 0 && (cp = strchr(domain, '.'))) (void) strcpy(domain, cp + 1); else domain[0] = 0; + cp = NULL; } if (sa->sa_len == 0) @@ -338,27 +362,19 @@ routename(sa) { struct in_addr in; in = ((struct sockaddr_in *)sa)->sin_addr; - cp = 0; if (in.s_addr == INADDR_ANY || sa->sa_len < 4) cp = "default"; - if (cp == 0 && !nflag) { - hp = gethostbyaddr((char *)&in, sizeof (struct in_addr), - AF_INET); - if (hp) { + if (!cp && !nflag) { + if ((hp = gethostbyaddr((char *)&in, + sizeof (struct in_addr), AF_INET))) { if ((cp = strchr(hp->h_name, '.')) && !strcmp(cp + 1, domain)) *cp = 0; cp = hp->h_name; } } - if (cp) - strcpy(line, cp); - else { -#define C(x) ((x) & 0xff) - in.s_addr = ntohl(in.s_addr); - (void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24), - C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr)); - } + strncpy(line, cp ? cp : inet_ntoa(in), sizeof line-1); + line[sizeof line-1] = '\0'; break; } @@ -377,14 +393,9 @@ routename(sa) break; default: - { u_short *s = (u_short *)sa; - u_short *slim = s + ((sa->sa_len + 1) >> 1); - char *cp = line + sprintf(line, "(%d)", sa->sa_family); - - while (++s < slim) /* start with sa->sa_data */ - cp += sprintf(cp, " %x", *s); + (void) snprintf(line, sizeof line, "(%d) %s", + sa->sa_family, any_ntoa(sa)); break; - } } return (line); } @@ -397,11 +408,10 @@ char * netname(sa) struct sockaddr *sa; { - char *cp = 0; + char *cp = NULL; static char line[MAXHOSTNAMELEN]; struct netent *np = 0; - u_long net, mask; - register u_long i; + u_int32_t net, mask; int subnetshift; char *ns_print(); char *ipx_print(); @@ -412,14 +422,14 @@ netname(sa) { struct in_addr in; in = ((struct sockaddr_in *)sa)->sin_addr; - i = in.s_addr = ntohl(in.s_addr); + in.s_addr = ntohl(in.s_addr); if (in.s_addr == 0) cp = "default"; else if (!nflag) { - if (IN_CLASSA(i)) { + if (IN_CLASSA(in.s_addr)) { mask = IN_CLASSA_NET; subnetshift = 8; - } else if (IN_CLASSB(i)) { + } else if (IN_CLASSB(in.s_addr)) { mask = IN_CLASSB_NET; subnetshift = 8; } else { @@ -433,7 +443,7 @@ netname(sa) * width subnet fields. */ while (in.s_addr &~ mask) - mask = (long)mask >> subnetshift; + mask = (u_int32_t)mask >> subnetshift; net = in.s_addr & mask; while ((mask & 1) == 0) mask >>= 1, net >>= 1; @@ -441,21 +451,9 @@ netname(sa) if (np) cp = np->n_name; } - if (cp) { - strncpy(line, cp, sizeof line-1); - line[sizeof line-1] = '\0'; - } else if ((in.s_addr & 0xffffff) == 0) - (void) sprintf(line, "%u", C(in.s_addr >> 24)); - else if ((in.s_addr & 0xffff) == 0) - (void) sprintf(line, "%u.%u", C(in.s_addr >> 24), - C(in.s_addr >> 16)); - else if ((in.s_addr & 0xff) == 0) - (void) sprintf(line, "%u.%u.%u", C(in.s_addr >> 24), - C(in.s_addr >> 16), C(in.s_addr >> 8)); - else - (void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24), - C(in.s_addr >> 16), C(in.s_addr >> 8), - C(in.s_addr)); + in = ((struct sockaddr_in *)sa)->sin_addr; + strncpy(line, cp ? cp : inet_ntoa(in), sizeof line-1); + line[sizeof line-1] = '\0'; break; } @@ -469,19 +467,14 @@ netname(sa) return (link_ntoa((struct sockaddr_dl *)sa)); case AF_ISO: - (void) sprintf(line, "iso %s", + (void) snprintf(line, sizeof line, "iso %s", iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr)); break; default: - { u_short *s = (u_short *)sa->sa_data; - u_short *slim = s + ((sa->sa_len + 1)>>1); - char *cp = line + sprintf(line, "af %d:", sa->sa_family); - - while (s < slim) - cp += sprintf(cp, " %x", *s++); + snprintf(line, sizeof line, "af %d: %s", + sa->sa_family, any_ntoa(sa)); break; - } } return (line); } @@ -663,7 +656,7 @@ newroute(argc, argv) if (ret == 0) { if (!qflag && strcmp(*argv, "0") == 0) - printf("%s,%s", + printf("%s,%s", "old usage of trailing 0", "assuming route to if\n"); else @@ -672,8 +665,8 @@ newroute(argc, argv) continue; } else if (ret > 0 && ret < 10) { if (!qflag) { - printf("old usage of trailing digit, "); - printf("assuming route via gateway\n"); + printf("old usage of trailing digit, "); + printf("assuming route via gateway\n"); } iflag = 0; continue; @@ -740,10 +733,10 @@ newroute(argc, argv) void inet_makenetandmask(net, sin) - u_long net; + u_int32_t net; register struct sockaddr_in *sin; { - u_long addr, mask = 0; + u_int32_t addr, mask = 0; register char *cp; rtm_addrs |= RTA_NETMASK; @@ -794,6 +787,7 @@ getaddr(which, s, hpp) struct ns_addr ns_addr(); struct ipx_addr ipx_addr(); struct iso_addr *iso_addr(); + struct ccitt_addr *ccitt_addr(); struct hostent *hp; struct netent *np; u_long val; @@ -875,7 +869,9 @@ getaddr(which, s, hpp) if (which == RTA_NETMASK || which == RTA_GENMASK) { register char *cp = (char *)TSEL(&su->siso); su->siso.siso_nlen = 0; - do {--cp ;} while ((cp > (char *)su) && (*cp == 0)); + do { + --cp; + } while ((cp > (char *)su) && (*cp == 0)); su->siso.siso_len = 1 + cp - (char *)su; } return (1); @@ -953,12 +949,11 @@ ns_print(sns) struct sockaddr_ns *sns; { struct ns_addr work; - union { union ns_net net_e; u_long long_e; } net; + union { union ns_net net_e; u_int32_t long_e; } net; u_short port; static char mybuf[50+MAXHOSTNAMELEN]; char cport[10], chost[25]; char *host = ""; - register char *p; register u_char *q; work = sns->sns_addr; @@ -988,7 +983,7 @@ ns_print(sns) *cport = '\0'; (void) snprintf(mybuf, sizeof mybuf, "0x%x.%s%s", - ntohl(net.long_e), host, cport); + (u_int32_t)ntohl(net.long_e), host, cport); return (mybuf); } @@ -1000,9 +995,9 @@ ipx_print(sipx) struct sockaddr_ipx *sipx; { struct ipx_addr work; - union { union ipx_net net_e; u_long long_e; } net; + union { union ipx_net net_e; u_int32_t long_e; } net; u_short port; - static char mybuf[50], cport[10], chost[25]; + static char mybuf[50+MAXHOSTNAMELEN], cport[10], chost[25]; char *host = ""; register char *p; register u_char *q; @@ -1014,7 +1009,7 @@ ipx_print(sipx) if (ipx_nullhost(work) && net.long_e == 0) { if (!port) return ("*.*"); - (void) sprintf(mybuf, "*.%XH", port); + (void) sprintf(mybuf, "*.0x%XH", port); return (mybuf); } @@ -1035,7 +1030,8 @@ ipx_print(sipx) else *cport = 0; - (void) sprintf(mybuf,"%XH.%s%s", ntohl(net.long_e), host, cport); + (void) snprintf(mybuf, sizeof mybuf, "%XH.%s%s", + (u_int32_t)ntohl(net.long_e), host, cport); return (mybuf); } @@ -1340,16 +1336,16 @@ print_getmsg(rtm, msglen) (void) printf("\n%s\n", "\ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire"); - printf("%8d%c ", rtm->rtm_rmx.rmx_recvpipe, lock(RPIPE)); - printf("%8d%c ", rtm->rtm_rmx.rmx_sendpipe, lock(SPIPE)); - printf("%8d%c ", rtm->rtm_rmx.rmx_ssthresh, lock(SSTHRESH)); - printf("%8d%c ", msec(rtm->rtm_rmx.rmx_rtt), lock(RTT)); - printf("%8d%c ", msec(rtm->rtm_rmx.rmx_rttvar), lock(RTTVAR)); - printf("%8d%c ", rtm->rtm_rmx.rmx_hopcount, lock(HOPCOUNT)); - printf("%8d%c ", rtm->rtm_rmx.rmx_mtu, lock(MTU)); + printf("%8d%c ", (int)rtm->rtm_rmx.rmx_recvpipe, lock(RPIPE)); + printf("%8d%c ", (int)rtm->rtm_rmx.rmx_sendpipe, lock(SPIPE)); + printf("%8d%c ", (int)rtm->rtm_rmx.rmx_ssthresh, lock(SSTHRESH)); + printf("%8d%c ", (int)msec(rtm->rtm_rmx.rmx_rtt), lock(RTT)); + printf("%8d%c ", (int)msec(rtm->rtm_rmx.rmx_rttvar), lock(RTTVAR)); + printf("%8d%c ", (int)rtm->rtm_rmx.rmx_hopcount, lock(HOPCOUNT)); + printf("%8d%c ", (int)rtm->rtm_rmx.rmx_mtu, lock(MTU)); if (rtm->rtm_rmx.rmx_expire) rtm->rtm_rmx.rmx_expire -= time(0); - printf("%8d%c\n", rtm->rtm_rmx.rmx_expire, lock(EXPIRE)); + printf("%8d%c\n", (int)rtm->rtm_rmx.rmx_expire, lock(EXPIRE)); #undef lock #undef msec #define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD) @@ -1408,8 +1404,8 @@ bprintf(fp, b, s) if (b == 0) return; - while (i = *s++) { - if (b & (1 << (i-1))) { + while ((i = *s++)) { + if ((b & (1 << (i-1)))) { if (gotsome == 0) i = '<'; else @@ -1484,7 +1480,7 @@ sockaddr(addr, sa) register char *cp = (char *)sa; int size = sa->sa_len; char *cplim = cp + size; - register int byte = 0, state = VIRGIN, new; + register int byte = 0, state = VIRGIN, new = 0; memset(cp, 0, size); cp++; diff --git a/sbin/route/show.c b/sbin/route/show.c new file mode 100644 index 00000000000..1e16d394481 --- /dev/null +++ b/sbin/route/show.c @@ -0,0 +1,334 @@ +/* $NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $ */ + +/* + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +#if 0 +static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94"; +#else +static char *rcsid = "$NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $"; +#endif +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/protosw.h> +#include <sys/socket.h> +#include <sys/mbuf.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> +#include <net/route.h> +#include <netinet/in.h> +#include <netns/ns.h> + +#include <sys/sysctl.h> + +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +/* XXX: things from route.c */ +extern char *routename __P((struct sockaddr *)); +extern char *netname __P((struct sockaddr *)); +extern char *ns_print __P((struct sockaddr_ns *)); +extern int nflag; + +/* + * Definitions for showing gateway flags. + */ +struct bits { + short b_mask; + char b_val; +}; +static const struct bits bits[] = { + { RTF_UP, 'U' }, + { RTF_GATEWAY, 'G' }, + { RTF_HOST, 'H' }, + { RTF_REJECT, 'R' }, + { RTF_DYNAMIC, 'D' }, + { RTF_MODIFIED, 'M' }, + { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ + { RTF_MASK, 'm' }, /* Mask Present -- for routing messages only */ + { RTF_CLONING, 'C' }, + { RTF_XRESOLVE, 'X' }, + { RTF_LLINFO, 'L' }, + { RTF_STATIC, 'S' }, + { RTF_PROTO1, '1' }, + { RTF_PROTO2, '2' }, + { 0 } +}; + +static void p_rtentry __P((struct rt_msghdr *)); +static void p_sockaddr __P((struct sockaddr *, int, int)); +static void p_flags __P((int, char *)); +static void pr_rthdr __P((void)); +static void pr_family __P((int)); + +/* + * Print routing tables. + */ +void +show(argc, argv) + int argc; + char **argv; +{ + register struct rt_msghdr *rtm; + char *buf, *next, *lim; + size_t needed; + int mib[6]; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = 0; + mib[4] = NET_RT_DUMP; + mib[5] = 0; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { + perror("route-sysctl-estimate"); + exit(1); + } + if ((buf = malloc(needed)) == 0) { + printf("out of space\n"); + exit(1); + } + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { + perror("sysctl of routing table"); + exit(1); + } + lim = buf + needed; + + printf("Routing tables\n"); + + for (next = buf; next < lim; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + p_rtentry(rtm); + } +} + +/* column widths; each followed by one space */ +#define WID_DST 16 /* width of destination column */ +#define WID_GW 18 /* width of gateway column */ + +/* + * Print header for routing table columns. + */ +static void +pr_rthdr() +{ + printf("%-*.*s %-*.*s %-6.6s\n", + WID_DST, WID_DST, "Destination", + WID_GW, WID_GW, "Gateway", + "Flags"); +} + +/* + * Print a routing table entry. + */ +static void +p_rtentry(rtm) + register struct rt_msghdr *rtm; +{ + register struct sockaddr *sa = (struct sockaddr *)(rtm + 1); +#ifdef notdef + static int masks_done, banner_printed; +#endif + static int old_af; + int af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST; + +#ifdef notdef + /* for the moment, netmasks are skipped over */ + if (!banner_printed) { + printf("Netmasks:\n"); + banner_printed = 1; + } + if (masks_done == 0) { + if (rtm->rtm_addrs != RTA_DST ) { + masks_done = 1; + af = sa->sa_family; + } + } else +#endif + af = sa->sa_family; + if (old_af != af) { + old_af = af; + pr_family(af); + pr_rthdr(); + } + if (rtm->rtm_addrs == RTA_DST) + p_sockaddr(sa, 0, 36); + else { + p_sockaddr(sa, rtm->rtm_flags, 16); + if (sa->sa_len == 0) + sa->sa_len = sizeof(long); + sa = (struct sockaddr *)(sa->sa_len + (char *)sa); + p_sockaddr(sa, 0, 18); + } + p_flags(rtm->rtm_flags & interesting, "%-6.6s "); + putchar('\n'); +} + + +/* + * Print address family header before a section of the routing table. + */ +static void +pr_family(af) + int af; +{ + char *afname; + + switch (af) { + case AF_INET: + afname = "Internet"; + break; + case AF_NS: + afname = "XNS"; + break; + case AF_IPX: + afname = "IPX"; + break; + case AF_ISO: + afname = "ISO"; + break; + case AF_CCITT: + afname = "X.25"; + break; + default: + afname = NULL; + break; + } + if (afname) + printf("\n%s:\n", afname); + else + printf("\nProtocol Family %d:\n", af); +} + + +static void +p_sockaddr(sa, flags, width) + struct sockaddr *sa; + int flags, width; +{ + char workbuf[128], *cplim; + register char *cp = workbuf; + + switch(sa->sa_family) { + + case AF_LINK: + { + register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; + + if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && + sdl->sdl_slen == 0) + (void) sprintf(workbuf, "link#%d", sdl->sdl_index); + else switch (sdl->sdl_type) { + case IFT_ETHER: + { + register int i; + register u_char *lla = (u_char *)sdl->sdl_data + + sdl->sdl_nlen; + + cplim = ""; + for (i = 0; i < sdl->sdl_alen; i++, lla++) { + cp += sprintf(cp, "%s%x", cplim, *lla); + cplim = ":"; + } + cp = workbuf; + break; + } + default: + cp = link_ntoa(sdl); + break; + } + break; + } + + case AF_INET: + { + register struct sockaddr_in *sin = (struct sockaddr_in *)sa; + + if (sin->sin_addr.s_addr == 0) + cp = "default"; + else + cp = (flags & RTF_HOST) ? routename(sa) : netname(sa); + break; + } + + case AF_NS: + cp = ns_print((struct sockaddr_ns *)sa); + break; + + default: + { + register u_char *s = (u_char *)sa->sa_data, *slim; + + slim = sa->sa_len + (u_char *) sa; + cplim = cp + sizeof(workbuf) - 6; + cp += sprintf(cp, "(%d)", sa->sa_family); + while (s < slim && cp < cplim) { + cp += sprintf(cp, " %02x", *s++); + if (s < slim) + cp += sprintf(cp, "%02x", *s++); + } + cp = workbuf; + } + } + if (width < 0 ) + printf("%s ", cp); + else { + if (nflag) + printf("%-*s ", width, cp); + else + printf("%-*.*s ", width, width, cp); + } +} + +static void +p_flags(f, format) + register int f; + char *format; +{ + char name[33], *flags; + register const struct bits *p = bits; + + for (flags = name; p->b_mask && flags < &name[sizeof name-2]; p++) + if (p->b_mask & f) + *flags++ = p->b_val; + *flags = '\0'; + printf(format, name); +} + |