diff options
Diffstat (limited to 'usr.bin/netstat/route.c')
-rw-r--r-- | usr.bin/netstat/route.c | 666 |
1 files changed, 0 insertions, 666 deletions
diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c deleted file mode 100644 index 7f4ebb6..0000000 --- a/usr.bin/netstat/route.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * 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 -static char sccsid[] = "@(#)route.c 8.3 (Berkeley) 3/9/94"; -#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> -#define KERNEL -#include <net/route.h> -#undef KERNEL -#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> -#include "netstat.h" - -#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d))) - -/* - * Definitions for showing gateway flags. - */ -struct bits { - short b_mask; - char b_val; -} 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 union { - struct sockaddr u_sa; - u_short u_data[128]; -} pt_u; - -int do_rtent = 0; -struct rtentry rtentry; -struct radix_node rnode; -struct radix_mask rmask; - -int NewTree = 0; - -static struct sockaddr *kgetsa __P((struct sockaddr *)); -static void p_tree __P((struct radix_node *)); -static void p_rtnode __P(()); -static void ntreestuff __P(()); -static void np_rtentry __P((struct rt_msghdr *)); -static void p_sockaddr __P((struct sockaddr *, int, int)); -static void p_flags __P((int, char *)); -static void p_rtentry __P((struct rtentry *)); - -/* - * Print routing tables. - */ -void -routepr(rtree) - u_long rtree; -{ - struct radix_node_head *rnh, head; - int i; - - printf("Routing tables\n"); - - if (Aflag == 0 && NewTree) - ntreestuff(); - else { - if (rtree == 0) { - printf("rt_tables: symbol not in namelist\n"); - return; - } - - kget(rtree, rt_tables); - for (i = 0; i <= AF_MAX; i++) { - if ((rnh = rt_tables[i]) == 0) - continue; - kget(rnh, head); - if (i == AF_UNSPEC) { - if (Aflag && af == 0) { - printf("Netmasks:\n"); - p_tree(head.rnh_treetop); - } - } else if (af == AF_UNSPEC || af == i) { - pr_family(i); - do_rtent = 1; - pr_rthdr(); - p_tree(head.rnh_treetop); - } - } - } -} - -/* - * Print address family header before a section of the routing table. - */ -void -pr_family(af) - int af; -{ - char *afname; - - switch (af) { - case AF_INET: - afname = "Internet"; - break; - case AF_NS: - afname = "XNS"; - 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); -} - -/* 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. - */ -void -pr_rthdr() -{ - - if (Aflag) - printf("%-8.8s ","Address"); - printf("%-*.*s %-*.*s %-6.6s %6.6s%8.8s %s\n", - WID_DST, WID_DST, "Destination", - WID_GW, WID_GW, "Gateway", - "Flags", "Refs", "Use", "Interface"); -} - -static struct sockaddr * -kgetsa(dst) - register struct sockaddr *dst; -{ - - kget(dst, pt_u.u_sa); - if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa)) - kread((u_long)dst, (char *)pt_u.u_data, pt_u.u_sa.sa_len); - return (&pt_u.u_sa); -} - -static void -p_tree(rn) - struct radix_node *rn; -{ - -again: - kget(rn, rnode); - if (rnode.rn_b < 0) { - if (Aflag) - printf("%-8.8x ", rn); - if (rnode.rn_flags & RNF_ROOT) { - if (Aflag) - printf("(root node)%s", - rnode.rn_dupedkey ? " =>\n" : "\n"); - } else if (do_rtent) { - kget(rn, rtentry); - p_rtentry(&rtentry); - if (Aflag) - p_rtnode(); - } else { - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key), - 0, 44); - putchar('\n'); - } - if (rn = rnode.rn_dupedkey) - goto again; - } else { - if (Aflag && do_rtent) { - printf("%-8.8x ", rn); - p_rtnode(); - } - rn = rnode.rn_r; - p_tree(rnode.rn_l); - p_tree(rn); - } -} - -char nbuf[20]; - -static void -p_rtnode() -{ - struct radix_mask *rm = rnode.rn_mklist; - - if (rnode.rn_b < 0) { - if (rnode.rn_mask) { - printf("\t mask "); - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask), - 0, -1); - } else if (rm == 0) - return; - } else { - sprintf(nbuf, "(%d)", rnode.rn_b); - printf("%6.6s %8.8x : %8.8x", nbuf, rnode.rn_l, rnode.rn_r); - } - while (rm) { - kget(rm, rmask); - sprintf(nbuf, " %d refs, ", rmask.rm_refs); - printf(" mk = %8.8x {(%d),%s", - rm, -1 - rmask.rm_b, rmask.rm_refs ? nbuf : " "); - p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), 0, -1); - putchar('}'); - if (rm = rmask.rm_mklist) - printf(" ->"); - } - putchar('\n'); -} - -static void -ntreestuff() -{ - size_t needed; - int mib[6]; - char *buf, *next, *lim; - register struct rt_msghdr *rtm; - - 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; - for (next = buf; next < lim; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)next; - np_rtentry(rtm); - } -} - -static void -np_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 (af != old_af) { - pr_family(af); - old_af = af; - } - 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'); -} - -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_INET: - { - register struct sockaddr_in *sin = (struct sockaddr_in *)sa; - - cp = (sin->sin_addr.s_addr == 0) ? "default" : - ((flags & RTF_HOST) ? - routename(sin->sin_addr.s_addr) : - netname(sin->sin_addr.s_addr, 0L)); - break; - } - - case AF_NS: - cp = ns_print(sa); - break; - - 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; - } - - 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 struct bits *p = bits; - - for (flags = name; p->b_mask; p++) - if (p->b_mask & f) - *flags++ = p->b_val; - *flags = '\0'; - printf(format, name); -} - -static void -p_rtentry(rt) - register struct rtentry *rt; -{ - static struct ifnet ifnet, *lastif; - static char name[16]; - - p_sockaddr(kgetsa(rt_key(rt)), rt->rt_flags, WID_DST); - p_sockaddr(kgetsa(rt->rt_gateway), RTF_HOST, WID_GW); - p_flags(rt->rt_flags, "%-6.6s "); - printf("%6d %8d ", rt->rt_refcnt, rt->rt_use); - if (rt->rt_ifp) { - if (rt->rt_ifp != lastif) { - kget(rt->rt_ifp, ifnet); - kread((u_long)ifnet.if_name, name, 16); - lastif = rt->rt_ifp; - } - printf(" %.15s%d%s", name, ifnet.if_unit, - rt->rt_nodes[0].rn_dupedkey ? " =>" : ""); - } - putchar('\n'); -} - -char * -routename(in) - u_long in; -{ - register char *cp; - static char line[MAXHOSTNAMELEN + 1]; - struct hostent *hp; - static char domain[MAXHOSTNAMELEN + 1]; - static int first = 1; - - if (first) { - first = 0; - if (gethostname(domain, MAXHOSTNAMELEN) == 0 && - (cp = index(domain, '.'))) - (void) strcpy(domain, cp + 1); - else - domain[0] = 0; - } - cp = 0; - if (!nflag) { - hp = gethostbyaddr((char *)&in, sizeof (struct in_addr), - AF_INET); - if (hp) { - if ((cp = index(hp->h_name, '.')) && - !strcmp(cp + 1, domain)) - *cp = 0; - cp = hp->h_name; - } - } - if (cp) - strncpy(line, cp, sizeof(line) - 1); - else { -#define C(x) ((x) & 0xff) - in = ntohl(in); - sprintf(line, "%u.%u.%u.%u", - C(in >> 24), C(in >> 16), C(in >> 8), C(in)); - } - return (line); -} - -/* - * Return the name of the network whose address is given. - * The address is assumed to be that of a net or subnet, not a host. - */ -char * -netname(in, mask) - u_long in, mask; -{ - char *cp = 0; - static char line[MAXHOSTNAMELEN + 1]; - struct netent *np = 0; - u_long net; - register int i; - int subnetshift; - - i = ntohl(in); - if (!nflag && i) { - if (mask == 0) { - if (IN_CLASSA(i)) { - mask = IN_CLASSA_NET; - subnetshift = 8; - } else if (IN_CLASSB(i)) { - mask = IN_CLASSB_NET; - subnetshift = 8; - } else { - mask = IN_CLASSC_NET; - subnetshift = 4; - } - /* - * If there are more bits than the standard mask - * would suggest, subnets must be in use. - * Guess at the subnet mask, assuming reasonable - * width subnet fields. - */ - while (i &~ mask) - mask = (long)mask >> subnetshift; - } - net = i & mask; - while ((mask & 1) == 0) - mask >>= 1, net >>= 1; - np = getnetbyaddr(net, AF_INET); - if (np) - cp = np->n_name; - } - if (cp) - strncpy(line, cp, sizeof(line) - 1); - else if ((i & 0xffffff) == 0) - sprintf(line, "%u", C(i >> 24)); - else if ((i & 0xffff) == 0) - sprintf(line, "%u.%u", C(i >> 24) , C(i >> 16)); - else if ((i & 0xff) == 0) - sprintf(line, "%u.%u.%u", C(i >> 24), C(i >> 16), C(i >> 8)); - else - sprintf(line, "%u.%u.%u.%u", C(i >> 24), - C(i >> 16), C(i >> 8), C(i)); - return (line); -} - -/* - * Print routing statistics - */ -void -rt_stats(off) - u_long off; -{ - struct rtstat rtstat; - - if (off == 0) { - printf("rtstat: symbol not in namelist\n"); - return; - } - kread(off, (char *)&rtstat, sizeof (rtstat)); - printf("routing:\n"); - printf("\t%u bad routing redirect%s\n", - rtstat.rts_badredirect, plural(rtstat.rts_badredirect)); - printf("\t%u dynamically created route%s\n", - rtstat.rts_dynamic, plural(rtstat.rts_dynamic)); - printf("\t%u new gateway%s due to redirects\n", - rtstat.rts_newgateway, plural(rtstat.rts_newgateway)); - printf("\t%u destination%s found unreachable\n", - rtstat.rts_unreach, plural(rtstat.rts_unreach)); - printf("\t%u use%s of a wildcard route\n", - rtstat.rts_wildcard, plural(rtstat.rts_wildcard)); -} -short ns_nullh[] = {0,0,0}; -short ns_bh[] = {-1,-1,-1}; - -char * -ns_print(sa) - register struct sockaddr *sa; -{ - register struct sockaddr_ns *sns = (struct sockaddr_ns*)sa; - struct ns_addr work; - union { union ns_net net_e; u_long long_e; } net; - u_short port; - static char mybuf[50], cport[10], chost[25]; - char *host = ""; - register char *p; register u_char *q; - - work = sns->sns_addr; - port = ntohs(work.x_port); - work.x_port = 0; - net.net_e = work.x_net; - if (ns_nullhost(work) && net.long_e == 0) { - if (port ) { - sprintf(mybuf, "*.%xH", port); - upHex(mybuf); - } else - sprintf(mybuf, "*.*"); - return (mybuf); - } - - if (bcmp(ns_bh, work.x_host.c_host, 6) == 0) { - host = "any"; - } else if (bcmp(ns_nullh, work.x_host.c_host, 6) == 0) { - host = "*"; - } else { - q = work.x_host.c_host; - sprintf(chost, "%02x%02x%02x%02x%02x%02xH", - q[0], q[1], q[2], q[3], q[4], q[5]); - for (p = chost; *p == '0' && p < chost + 12; p++) - continue; - host = p; - } - if (port) - sprintf(cport, ".%xH", htons(port)); - else - *cport = 0; - - sprintf(mybuf,"%xH.%s%s", ntohl(net.long_e), host, cport); - upHex(mybuf); - return(mybuf); -} - -char * -ns_phost(sa) - struct sockaddr *sa; -{ - register struct sockaddr_ns *sns = (struct sockaddr_ns *)sa; - struct sockaddr_ns work; - static union ns_net ns_zeronet; - char *p; - - work = *sns; - work.sns_addr.x_port = 0; - work.sns_addr.x_net = ns_zeronet; - - p = ns_print((struct sockaddr *)&work); - if (strncmp("0H.", p, 3) == 0) p += 3; - return(p); -} - -void -upHex(p0) - char *p0; -{ - register char *p = p0; - for (; *p; p++) switch (*p) { - - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - *p += ('A' - 'a'); - } -} |