* 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 <sys/param.h>
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 *));
p_rtnode();
} else {
p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key),
- 0, 44);
+ NULL, 0, 44);
putchar('\n');
}
if (rn = rnode.rn_dupedkey)
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 {
rm, -1 - rmask.rm_b, rmask.rm_refs ? nbuf : " ");
if (rmask.rm_flags & RNF_NORMAL) {
struct radix_node rnode_aux;
- printf(nbuf, " <normal>, ");
+ printf(" <normal>, ");
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(" ->");
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;
{
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;
}
{
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) {
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.
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
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);
}