summaryrefslogtreecommitdiff
path: root/sbin/route
diff options
context:
space:
mode:
authorCedric Berger <cedric@cvs.openbsd.org>2004-06-06 17:08:24 +0000
committerCedric Berger <cedric@cvs.openbsd.org>2004-06-06 17:08:24 +0000
commit279617b781ec14108b2825952f7d1f0a5140a417 (patch)
tree6d25610a0394a8a636188a518848e623fdd436d1 /sbin/route
parent26988a280f12eb6b5489e79481d75404a5199fd3 (diff)
add new "-src" and "-srcmask" modifiers to make it possible to add a source
selector part to the routing table entry. complements existing "-dst" and "-dstmask". typical use: route add -src 20.20.20.22 20.20.20.21 route add -src 192.168.1.0/24 -dst 192.168.2.0/24 20.20.20.21 useful for example to implement symetrical routing on multihomed boxes, or to better select which packets to send to gif/tun/... tunnels. new '-S' flag similar to netstat one. ok deraadt@ mcbride@
Diffstat (limited to 'sbin/route')
-rw-r--r--sbin/route/keywords.c4
-rw-r--r--sbin/route/keywords.h14
-rw-r--r--sbin/route/keywords.sh4
-rw-r--r--sbin/route/route.838
-rw-r--r--sbin/route/route.c126
-rw-r--r--sbin/route/show.c47
6 files changed, 174 insertions, 59 deletions
diff --git a/sbin/route/keywords.c b/sbin/route/keywords.c
index ba38d6ab288..eb6a73237db 100644
--- a/sbin/route/keywords.c
+++ b/sbin/route/keywords.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: keywords.c,v 1.6 2000/07/27 20:12:24 angelos Exp $ */
+/* $OpenBSD: keywords.c,v 1.7 2004/06/06 17:08:23 cedric Exp $ */
/* WARNING! This file was generated by keywords.sh */
@@ -48,6 +48,8 @@ struct keytab keywords[] = {
{"sa", K_SA},
{"sendpipe", K_SENDPIPE},
{"show", K_SHOW},
+ {"src", K_SRC},
+ {"srcmask", K_SRCMASK},
{"ssthresh", K_SSTHRESH},
{"static", K_STATIC},
{"x25", K_X25},
diff --git a/sbin/route/keywords.h b/sbin/route/keywords.h
index 81c547bf986..2c2d9cdae8b 100644
--- a/sbin/route/keywords.h
+++ b/sbin/route/keywords.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: keywords.h,v 1.6 2000/07/27 20:12:25 angelos Exp $ */
+/* $OpenBSD: keywords.h,v 1.7 2004/06/06 17:08:23 cedric Exp $ */
/* WARNING! This file was generated by keywords.sh */
@@ -50,8 +50,10 @@ extern struct keytab {
#define K_SA 40
#define K_SENDPIPE 41
#define K_SHOW 42
-#define K_SSTHRESH 43
-#define K_STATIC 44
-#define K_X25 45
-#define K_XNS 46
-#define K_XRESOLVE 47
+#define K_SRC 43
+#define K_SRCMASK 44
+#define K_SSTHRESH 45
+#define K_STATIC 46
+#define K_X25 47
+#define K_XNS 48
+#define K_XRESOLVE 49
diff --git a/sbin/route/keywords.sh b/sbin/route/keywords.sh
index c97c481abee..f79f7330a24 100644
--- a/sbin/route/keywords.sh
+++ b/sbin/route/keywords.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: keywords.sh,v 1.5 2000/07/27 20:12:25 angelos Exp $
+# $OpenBSD: keywords.sh,v 1.6 2004/06/06 17:08:23 cedric Exp $
# $NetBSD: keywords.sh,v 1.2 1996/11/15 18:57:21 gwr Exp $
# @(#)keywords 8.2 (Berkeley) 3/19/94
#
@@ -51,6 +51,8 @@ rttvar
sa
sendpipe
show
+src
+srcmask
ssthresh
static
x25
diff --git a/sbin/route/route.8 b/sbin/route/route.8
index 1eae7b93d85..68f8587641b 100644
--- a/sbin/route/route.8
+++ b/sbin/route/route.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: route.8,v 1.30 2003/08/31 07:03:29 jmc Exp $
+.\" $OpenBSD: route.8,v 1.31 2004/06/06 17:08:23 cedric Exp $
.\" $NetBSD: route.8,v 1.6 1995/03/18 15:00:13 cgd Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
@@ -73,6 +73,10 @@ to forgo this, especially when attempting to repair networking operations.)
(verbose) Print additional details.
.It Fl q
Suppress all output.
+.It Fl S
+Makes the
+.Cm show
+command display the source selector part of the routes.
.El
.Pp
The
@@ -270,6 +274,38 @@ specify that all ensuing metrics may be locked by the
.Fl lockrest
meta-modifier.
.Pp
+The
+.Fl src
+and
+.Fl srcmask
+modifiers can be used to specify the source selector of the route,
+which will match the source IP address of outgoing packets.
+.Fl src
+and
+.Fl srcmask
+work in a similar way than
+.Fl dst
+and
+.Fl netmask .
+For example:
+.Pp
+.Bd -filled -offset indent -compact
+.Nm route
+.Cm add
+.Fl src
+180.83.46.98
+180.83.46.97
+.Ed
+.Bd -filled -offset indent -compact
+.Nm route
+.Cm add
+.Fl src
+192.168.10.0/24
+.Fl dst
+10.5.1.0/24
+180.83.46.97
+.Ed
+.Pp
In a
.Cm change
or
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 9f0f0740f44..649dd964b14 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.66 2004/05/15 07:43:34 claudio Exp $ */
+/* $OpenBSD: route.c,v 1.67 2004/06/06 17:08:23 cedric Exp $ */
/* $NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $ */
/*
@@ -40,7 +40,7 @@ static const char copyright[] =
#if 0
static const char sccsid[] = "@(#)route.c 8.3 (Berkeley) 3/19/94";
#else
-static const char rcsid[] = "$OpenBSD: route.c,v 1.66 2004/05/15 07:43:34 claudio Exp $";
+static const char rcsid[] = "$OpenBSD: route.c,v 1.67 2004/06/06 17:08:23 cedric Exp $";
#endif
#endif /* not lint */
@@ -83,13 +83,14 @@ union sockunion {
struct sockaddr_iso siso;
struct sockaddr_dl sdl;
struct sockaddr_x25 sx25;
-} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
+ struct sockaddr_rtin rtin;
+} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp, so_src, so_srcmask;
typedef union sockunion *sup;
pid_t pid;
int rtm_addrs, s;
int forcehost, forcenet, doflush, nflag, af, qflag, tflag, keyword(char *);
-int iflag, verbose, aflen = sizeof (struct sockaddr_in);
+int Sflag, iflag, verbose, aflen = sizeof (struct sockaddr_in);
int locking, lockrest, debugonly;
struct rt_metrics rt_metrics;
u_long rtm_inits;
@@ -108,7 +109,7 @@ void print_rtmsg(struct rt_msghdr *, int);
void pmsg_common(struct rt_msghdr *);
void pmsg_addrs(char *, int);
void bprintf(FILE *, int, u_char *);
-void mask_addr(void);
+void mask_addr(union sockunion *, union sockunion *, int which);
#ifdef INET6
static int inet6_makenetandmask(struct sockaddr_in6 *);
#endif
@@ -119,7 +120,8 @@ __dead void usage(char *cp);
void quit(char *s);
char *any_ntoa(const struct sockaddr *sa);
void set_metric(char *value, int key);
-void inet_makenetandmask(u_int32_t net, struct sockaddr_in *sin, int bits);
+void inet_makenetandmask(u_int32_t net, struct sockaddr_in *sin, int bits,
+ int which);
char *ns_print(struct sockaddr_ns *sns);
char *ipx_print(struct sockaddr_ipx *sipx);
void interfaces(void);
@@ -132,7 +134,7 @@ usage(char *cp)
if (cp)
(void) fprintf(stderr, "route: botched keyword: %s\n", cp);
(void) fprintf(stderr,
- "usage: route [ -nqv ] cmd [[ -<modifiers> ] args ]\n");
+ "usage: route [ -nqSv ] cmd [[ -<modifiers> ] args ]\n");
(void) fprintf(stderr,
"keywords: get, add, change, delete, show, flush, monitor.\n");
exit(1);
@@ -165,7 +167,7 @@ main(int argc, char **argv)
if (argc < 2)
usage(NULL);
- while ((ch = getopt(argc, argv, "nqdtv")) != -1)
+ while ((ch = getopt(argc, argv, "nqdtvS")) != -1)
switch(ch) {
case 'n':
nflag = 1;
@@ -182,6 +184,9 @@ main(int argc, char **argv)
case 'd':
debugonly = 1;
break;
+ case 'S':
+ Sflag = 1;
+ break;
default:
usage(NULL);
}
@@ -601,7 +606,7 @@ set_metric(char *value, int key)
int
newroute(int argc, char **argv)
{
- char *cmd, *dest = "", *gateway = "", *err;
+ char *cmd, *dest = "", *source = "", *gateway = "", *err;
int ishost = 0, ret = 0, attempts, oerrno, flags = RTF_STATIC;
int key;
struct hostent *hp = 0;
@@ -718,6 +723,17 @@ newroute(int argc, char **argv)
ishost = getaddr(RTA_DST, *++argv, &hp);
dest = *argv;
break;
+ case K_SRC:
+ if (!--argc)
+ usage(1+*argv);
+ (void) getaddr(RTA_SRC, *++argv, 0);
+ source = *argv;
+ break;
+ case K_SRCMASK:
+ if (!--argc)
+ usage(1+*argv);
+ (void) getaddr(RTA_SRCMASK, *++argv, 0);
+ break;
case K_NETMASK:
if (!--argc)
usage(1+*argv);
@@ -747,7 +763,7 @@ newroute(int argc, char **argv)
usage(1+*argv);
}
} else {
- if ((rtm_addrs & RTA_DST) == 0) {
+ if ((rtm_addrs & (RTA_DST|RTA_SRC)) == 0) {
dest = *argv;
ishost = getaddr(RTA_DST, *argv, &hp);
} else if ((rtm_addrs & RTA_GATEWAY) == 0) {
@@ -786,6 +802,11 @@ newroute(int argc, char **argv)
flags |= RTF_HOST;
if (iflag == 0)
flags |= RTF_GATEWAY;
+ if (rtm_addrs & (RTA_SRC|RTA_SRCMASK)) {
+ if (!(rtm_addrs & RTA_DST))
+ getaddr(RTA_DST, "default", &hp);
+ flags |= RTF_SOURCE;
+ }
for (attempts = 1; ; attempts++) {
errno = 0;
if ((ret = rtmsg(*cmd, flags)) == 0)
@@ -804,6 +825,8 @@ newroute(int argc, char **argv)
oerrno = errno;
if (!qflag) {
(void) printf("%s %s %s", cmd, ishost? "host" : "net", dest);
+ if (*source)
+ (void) printf(": source %s", source);
if (*gateway) {
(void) printf(": gateway %s", gateway);
if (attempts > 1 && ret == 0 && af == AF_INET)
@@ -834,12 +857,12 @@ newroute(int argc, char **argv)
}
void
-inet_makenetandmask(u_int32_t net, struct sockaddr_in *sin, int bits)
+inet_makenetandmask(u_int32_t net, struct sockaddr_in *sin, int bits, int which)
{
u_int32_t addr, mask = 0;
char *cp;
- rtm_addrs |= RTA_NETMASK;
+ rtm_addrs |= (which == RTA_DST) ? RTA_NETMASK : RTA_SRCMASK;
if (net == 0)
mask = addr = 0;
else if (bits) {
@@ -866,7 +889,7 @@ inet_makenetandmask(u_int32_t net, struct sockaddr_in *sin, int bits)
mask = -1;
}
sin->sin_addr.s_addr = htonl(addr);
- sin = &so_mask.sin;
+ sin = (which == RTA_DST) ? &so_mask.sin : &so_srcmask.sin;
sin->sin_addr.s_addr = htonl(mask);
sin->sin_len = 0;
sin->sin_family = 0;
@@ -948,6 +971,12 @@ getaddr(int which, char *s, struct hostent **hpp)
su = &so_ifa;
su->sa.sa_family = af;
break;
+ case RTA_SRC:
+ su = &so_src;
+ break;
+ case RTA_SRCMASK:
+ su = &so_srcmask;
+ break;
default:
usage("Internal Error");
/*NOTREACHED*/
@@ -1073,19 +1102,19 @@ getaddr(int which, char *s, struct hostent **hpp)
*hpp = NULL;
q = strchr(s,'/');
- if (q && which == RTA_DST) {
+ if (q && (which == RTA_DST || which == RTA_SRC)) {
qs = *q;
*q = '\0';
val = inet_addr(s);
if (val != INADDR_NONE) {
inet_makenetandmask(htonl(val), &su->sin,
- strtoul(q+1, 0, 0));
+ strtoul(q+1, 0, 0), which);
return (0);
}
*q =qs;
}
if (((val = inet_addr(s)) != INADDR_NONE) &&
- (which != RTA_DST || forcenet == 0)) {
+ ((which != RTA_DST && which != RTA_SRC) || forcenet == 0)) {
su->sin.sin_addr.s_addr = val;
if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
return (1);
@@ -1098,8 +1127,8 @@ getaddr(int which, char *s, struct hostent **hpp)
(forcehost == 0 && (np = getnetbyname(s)) != NULL &&
(val = np->n_net) != 0)) {
netdone:
- if (which == RTA_DST)
- inet_makenetandmask(val, &su->sin, 0);
+ if (which == RTA_DST || which == RTA_SRC)
+ inet_makenetandmask(val, &su->sin, 0, which);
return (0);
}
hp = gethostbyname(s);
@@ -1367,13 +1396,17 @@ rtmsg(int cmd, int flags)
rtm.rtm_inits = rtm_inits;
if (rtm_addrs & RTA_NETMASK)
- mask_addr();
+ mask_addr(&so_dst, &so_mask, RTA_DST);
+ if (rtm_addrs & RTA_SRCMASK)
+ mask_addr(&so_src, &so_srcmask, RTA_SRC);
NEXTADDR(RTA_DST, so_dst);
NEXTADDR(RTA_GATEWAY, so_gate);
NEXTADDR(RTA_NETMASK, so_mask);
NEXTADDR(RTA_GENMASK, so_genmask);
NEXTADDR(RTA_IFP, so_ifp);
NEXTADDR(RTA_IFA, so_ifa);
+ NEXTADDR(RTA_SRC, so_src);
+ NEXTADDR(RTA_SRCMASK, so_srcmask);
rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
if (verbose)
print_rtmsg(&rtm, l);
@@ -1400,19 +1433,19 @@ rtmsg(int cmd, int flags)
}
void
-mask_addr(void)
+mask_addr(union sockunion *addr, union sockunion *mask, int which)
{
- int olen = so_mask.sa.sa_len;
- char *cp1 = olen + (char *)&so_mask, *cp2;
+ int olen = mask->sa.sa_len;
+ char *cp1 = olen + (char *)mask, *cp2;
- for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; )
+ for (mask->sa.sa_len = 0; cp1 > (char *)mask; )
if (*--cp1 != 0) {
- so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask;
+ mask->sa.sa_len = 1 + cp1 - (char *)mask;
break;
}
- if ((rtm_addrs & RTA_DST) == 0)
+ if ((rtm_addrs & which) == 0)
return;
- switch (so_dst.sa.sa_family) {
+ switch (addr->sa.sa_family) {
case AF_NS:
case AF_IPX:
case AF_INET:
@@ -1423,20 +1456,20 @@ mask_addr(void)
case 0:
return;
case AF_ISO:
- olen = MIN(so_dst.siso.siso_nlen,
- MAX(so_mask.sa.sa_len - 6, 0));
+ olen = MIN(addr->siso.siso_nlen,
+ MAX(mask->sa.sa_len - 6, 0));
break;
}
- cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst;
- cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst;
+ cp1 = mask->sa.sa_len + 1 + (char *)addr;
+ cp2 = addr->sa.sa_len + 1 + (char *)addr;
while (cp2 > cp1)
*--cp2 = 0;
- cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask;
- while (cp1 > so_dst.sa.sa_data)
+ cp2 = mask->sa.sa_len + 1 + (char *)mask;
+ while (cp1 > addr->sa.sa_data)
*--cp1 &= *--cp2;
- switch (so_dst.sa.sa_family) {
+ switch (addr->sa.sa_family) {
case AF_ISO:
- so_dst.siso.siso_nlen = olen;
+ addr->siso.siso_nlen = olen;
break;
}
}
@@ -1464,11 +1497,11 @@ char *msgtypes[] = {
char metricnames[] =
"\011pksent\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu";
char routeflags[] =
-"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\017PROTO2\020PROTO1\040CLONED";
+"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE\016PROTO3\017PROTO2\020PROTO1\021CLONED\022SOURCE";
char ifnetflags[] =
"\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6NOTRAILERS\7RUNNING\010NOARP\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1\017LINK2\020MULTICAST";
char addrnames[] =
-"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
+"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD\011SRC\012SRCMASK";
void
print_rtmsg(struct rt_msghdr *rtm, int msglen)
@@ -1538,6 +1571,7 @@ void
print_getmsg(struct rt_msghdr *rtm, int msglen)
{
struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL;
+ struct sockaddr *src = NULL, *srcmask = NULL;
struct sockaddr_dl *ifp = NULL;
struct sockaddr *sa;
char *cp;
@@ -1575,6 +1609,12 @@ print_getmsg(struct rt_msghdr *rtm, int msglen)
case RTA_NETMASK:
mask = sa;
break;
+ case RTA_SRC:
+ src = sa;
+ break;
+ case RTA_SRCMASK:
+ srcmask = sa;
+ break;
case RTA_IFP:
if (sa->sa_family == AF_LINK &&
((struct sockaddr_dl *)sa)->sdl_nlen)
@@ -1594,6 +1634,17 @@ print_getmsg(struct rt_msghdr *rtm, int msglen)
(void)printf(" mask: %s\n", routename(mask));
nflag = savenflag;
}
+ if (src && srcmask)
+ srcmask->sa_family = src->sa_family; /* XXX */
+ if (src)
+ (void)printf(" source: %s\n", routename(src));
+ if (srcmask) {
+ int savenflag = nflag;
+
+ nflag = 1;
+ (void)printf(" mask: %s\n", routename(mask));
+ nflag = savenflag;
+ }
if (gate && rtm->rtm_flags & RTF_GATEWAY)
(void)printf(" gateway: %s\n", routename(gate));
if (ifp)
@@ -1619,7 +1670,8 @@ print_getmsg(struct rt_msghdr *rtm, int msglen)
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)
+#define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_SRC|RTA_SRCMASK| \
+ RTA_IFP|RTA_IFA|RTA_BRD)
if (verbose)
pmsg_common(rtm);
else if (rtm->rtm_addrs &~ RTA_IGN) {
diff --git a/sbin/route/show.c b/sbin/route/show.c
index f0e20a63b89..7c5df9b9d2e 100644
--- a/sbin/route/show.c
+++ b/sbin/route/show.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: show.c,v 1.26 2003/08/26 08:33:12 itojun Exp $ */
+/* $OpenBSD: show.c,v 1.27 2004/06/06 17:08:23 cedric Exp $ */
/* $NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $ */
/*
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94";
#else
-static char *rcsid = "$OpenBSD: show.c,v 1.26 2003/08/26 08:33:12 itojun Exp $";
+static char *rcsid = "$OpenBSD: show.c,v 1.27 2004/06/06 17:08:23 cedric Exp $";
#endif
#endif /* not lint */
@@ -66,7 +66,7 @@ static char *rcsid = "$OpenBSD: show.c,v 1.26 2003/08/26 08:33:12 itojun Exp $";
extern char *routename(struct sockaddr *);
extern char *netname(struct sockaddr *);
extern char *ns_print(struct sockaddr_ns *);
-extern int nflag;
+extern int nflag, Sflag;
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
@@ -97,13 +97,14 @@ static const struct bits bits[] = {
{ RTF_PROTO2, '2' },
{ RTF_PROTO3, '3' },
{ RTF_CLONED, 'c' },
+ { RTF_SOURCE, 's' },
{ 0 }
};
static void p_rtentry(struct rt_msghdr *);
static void p_sockaddr(struct sockaddr *, int, int);
static void p_flags(int, char *);
-static void pr_rthdr(void);
+static void pr_rthdr(int);
static void pr_family(int);
int keyword(char *);
@@ -193,18 +194,27 @@ bad: usage(*argv);
/* column widths; each followed by one space */
#define WID_DST 16 /* width of destination column */
+#define WID_SRC 16 /* width of source column */
#define WID_GW 18 /* width of gateway column */
/*
* Print header for routing table columns.
*/
static void
-pr_rthdr()
+pr_rthdr(int af)
{
- printf("%-*.*s %-*.*s %-6.6s\n",
- WID_DST, WID_DST, "Destination",
- WID_GW, WID_GW, "Gateway",
- "Flags");
+ if (af == AF_INET && Sflag) {
+ printf("%-*.*s %-*.*s %-*.*s %-6.6s\n",
+ WID_SRC, WID_SRC, "Source",
+ WID_DST, WID_DST, "Destination",
+ WID_GW, WID_GW, "Gateway",
+ "Flags");
+ } else {
+ printf("%-*.*s %-*.*s %-6.6s\n",
+ WID_DST, WID_DST, "Destination",
+ WID_GW, WID_GW, "Gateway",
+ "Flags");
+ }
}
/*
@@ -214,12 +224,13 @@ static void
p_rtentry(rtm)
struct rt_msghdr *rtm;
{
- struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
+ struct sockaddr *sa = (struct sockaddr *)(rtm + 1), *sa2;
#ifdef notdef
static int masks_done, banner_printed;
#endif
static int old_af;
- int af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST | RTF_MASK;
+ int i, af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST |
+ RTF_MASK | RTF_SOURCE;
#ifdef notdef
/* for the moment, netmasks are skipped over */
@@ -238,9 +249,19 @@ p_rtentry(rtm)
if (old_af != af) {
old_af = af;
pr_family(af);
- pr_rthdr();
+ pr_rthdr(af);
+ }
+ if (af == AF_INET && Sflag) {
+ if (rtm->rtm_addrs & RTA_SRC) {
+ for (sa2 = sa, i = 1; i < RTA_SRC; i <<= 1)
+ if (rtm->rtm_addrs & i)
+ sa2 = (struct sockaddr *)(ROUNDUP(
+ sa2->sa_len) + (char *)sa2);
+ p_sockaddr(sa2, 0, 16);
+ } else
+ printf("%-*s ", 16, "default");
}
- if (rtm->rtm_addrs == RTA_DST)
+ if (!(rtm->rtm_addrs & RTA_GATEWAY))
p_sockaddr(sa, 0, 36);
else {
p_sockaddr(sa, rtm->rtm_flags, 16);