X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/e754a85d2785f2cf3e68aa7c3a3fc519a5ea7d49..fd88f5c5678c80ff5e338adc372d28a52ad20530:/usr/src/usr.bin/netstat/route.c diff --git a/usr/src/usr.bin/netstat/route.c b/usr/src/usr.bin/netstat/route.c index 0a8286cfc0..ee98f0714a 100644 --- a/usr/src/usr.bin/netstat/route.c +++ b/usr/src/usr.bin/netstat/route.c @@ -2,11 +2,37 @@ * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * - * %sccs.include.redist.c% + * 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.4 (Berkeley) %G%"; +static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95"; #endif /* not lint */ #include @@ -76,7 +102,7 @@ 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_sockaddr __P((struct sockaddr *, struct sockaddr *, int, int)); static void p_flags __P((int, char *)); static void p_rtentry __P((struct rtentry *)); @@ -203,7 +229,7 @@ again: p_rtnode(); } else { p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key), - 0, 44); + NULL, 0, 44); putchar('\n'); } if (rn = rnode.rn_dupedkey) @@ -230,7 +256,7 @@ p_rtnode() if (rnode.rn_mask) { printf("\t mask "); p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask), - 0, -1); + NULL, 0, -1); } else if (rm == 0) return; } else { @@ -244,12 +270,13 @@ p_rtnode() rm, -1 - rmask.rm_b, rmask.rm_refs ? nbuf : " "); if (rmask.rm_flags & RNF_NORMAL) { struct radix_node rnode_aux; - printf(nbuf, " , "); + printf(" , "); kget(rmask.rm_leaf, rnode_aux); - p_sockaddr( - kgetsa((struct sockaddr *)rnode_aux.rn_mask), 0, -1); + p_sockaddr(kgetsa((struct sockaddr *)rnode_aux.rn_mask), + NULL, 0, -1); } else - p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), 0, -1); + p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), + NULL, 0, -1); putchar('}'); if (rm = rmask.rm_mklist) printf(" ->"); @@ -314,21 +341,21 @@ np_rtentry(rtm) old_af = af; } if (rtm->rtm_addrs == RTA_DST) - p_sockaddr(sa, 0, 36); + p_sockaddr(sa, NULL, 0, 36); else { - p_sockaddr(sa, rtm->rtm_flags, 16); + p_sockaddr(sa, NULL, 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_sockaddr(sa, NULL, 0, 18); } p_flags(rtm->rtm_flags & interesting, "%-6.6s "); putchar('\n'); } static void -p_sockaddr(sa, flags, width) - struct sockaddr *sa; +p_sockaddr(sa, mask, flags, width) + struct sockaddr *sa, *mask; int flags, width; { char workbuf[128], *cplim; @@ -339,10 +366,16 @@ p_sockaddr(sa, flags, width) { 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)); + if (sin->sin_addr.s_addr == INADDR_ANY) + cp = "default"; + else if (flags & RTF_HOST) + cp = routename(sin->sin_addr.s_addr); + else if (mask) + cp = netname(sin->sin_addr.s_addr, + ntohl(((struct sockaddr_in *)mask) + ->sin_addr.s_addr)); + else + cp = netname(sin->sin_addr.s_addr, 0L); break; } @@ -425,9 +458,19 @@ p_rtentry(rt) { static struct ifnet ifnet, *lastif; static char name[16]; + register struct sockaddr *sa; + struct sockaddr addr, mask; - p_sockaddr(kgetsa(rt_key(rt)), rt->rt_flags, WID_DST); - p_sockaddr(kgetsa(rt->rt_gateway), RTF_HOST, WID_GW); + if (!(sa = kgetsa(rt_key(rt)))) + bzero(&addr, sizeof addr); + else + addr = *sa; + if (!rt_mask(rt) || !(sa = kgetsa(rt_mask(rt)))) + bzero(&mask, sizeof mask); + else + mask = *sa; + p_sockaddr(&addr, &mask, rt->rt_flags, WID_DST); + p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, WID_GW); p_flags(rt->rt_flags, "%-6.6s "); printf("%6d %8d ", rt->rt_refcnt, rt->rt_use); if (rt->rt_ifp) { @@ -482,6 +525,51 @@ routename(in) return (line); } +static u_long +forgemask(a) + u_long a; +{ + u_long m; + + if (IN_CLASSA(a)) + m = IN_CLASSA_NET; + else if (IN_CLASSB(a)) + m = IN_CLASSB_NET; + else + m = IN_CLASSC_NET; + return (m); +} + +static void +domask(dst, addr, mask) + char *dst; + u_long addr, mask; +{ + register int b, i; + + if (!mask || (forgemask(addr) == mask)) { + *dst = '\0'; + return; + } + i = 0; + for (b = 0; b < 32; b++) + if (mask & (1 << b)) { + register int bb; + + i = b; + for (bb = b+1; bb < 32; bb++) + if (!(mask & (1 << bb))) { + i = -1; /* noncontig */ + break; + } + break; + } + if (i == -1) + sprintf(dst, "&0x%lx", mask); + else + sprintf(dst, "/%d", 32-i); +} + /* * 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. @@ -493,22 +581,26 @@ netname(in, mask) char *cp = 0; static char line[MAXHOSTNAMELEN + 1]; struct netent *np = 0; - u_long net; - register int i; + u_long net, omask; + register u_long i; int subnetshift; i = ntohl(in); + omask = mask; if (!nflag && i) { if (mask == 0) { - if (IN_CLASSA(i)) { - mask = IN_CLASSA_NET; + switch (mask = forgemask(i)) { + case IN_CLASSA_NET: subnetshift = 8; - } else if (IN_CLASSB(i)) { - mask = IN_CLASSB_NET; + break; + case IN_CLASSB_NET: subnetshift = 8; - } else { - mask = IN_CLASSC_NET; + break; + case IN_CLASSC_NET: subnetshift = 4; + break; + default: + abort(); } /* * If there are more bits than the standard mask @@ -537,6 +629,7 @@ netname(in, mask) else sprintf(line, "%u.%u.%u.%u", C(i >> 24), C(i >> 16), C(i >> 8), C(i)); + domask(line+strlen(line), i, omask); return (line); }