summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-06-08 18:53:43 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-06-08 18:53:43 +0000
commit74f80d2a48939fd5d1afe9a84e24a2be04037d2d (patch)
tree96c329aaddd9590b8c693a6eead4d292eb45371c /sbin
parent384d5963830a2b84ac255a4553d5a6134385a431 (diff)
support IPv4 in -prefixlen.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/route/route.84
-rw-r--r--sbin/route/route.c73
2 files changed, 47 insertions, 30 deletions
diff --git a/sbin/route/route.8 b/sbin/route/route.8
index 8db6b075c48..231d03e5595 100644
--- a/sbin/route/route.8
+++ b/sbin/route/route.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: route.8,v 1.26 2000/12/20 21:18:39 deraadt Exp $
+.\" $OpenBSD: route.8,v 1.27 2002/06/08 18:53:42 itojun Exp $
.\" $NetBSD: route.8,v 1.6 1995/03/18 15:00:13 cgd Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
@@ -234,7 +234,7 @@ The implicit network mask generated in the
case
can be overridden by making sure this option follows the destination parameter.
.Fl prefixlen
-is also available for similar purpose, in IPv6 case.
+is also available for similar purpose, in IPv6/v4 case.
.Pp
Routes have associated flags which influence operation of the protocols
when sending to destinations matched by the routes.
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 30a9a4c262b..cdbe9b175bb 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.48 2002/06/05 22:14:15 itojun Exp $ */
+/* $OpenBSD: route.c,v 1.49 2002/06/08 18:53:42 itojun 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.48 2002/06/05 22:14:15 itojun Exp $";
+static char rcsid[] = "$OpenBSD: route.c,v 1.49 2002/06/08 18:53:42 itojun Exp $";
#endif
#endif /* not lint */
@@ -104,9 +104,7 @@ char *netname(struct sockaddr *);
void flushroutes(int, char **);
int newroute(int, char **);
void monitor(void);
-#ifdef INET6
-static int prefixlen(char *);
-#endif
+int prefixlen(char *);
void sockaddr(char *, struct sockaddr *);
void sodump(sup, char *);
void print_getmsg(struct rt_msghdr *, int);
@@ -736,18 +734,10 @@ newroute(argc, argv)
case K_NET:
forcenet++;
break;
-#ifdef INET6
case K_PREFIXLEN:
argc--;
- if (prefixlen(*++argv) == 128) {
- forcenet = 0;
- ishost = 1;
- } else {
- forcenet = 1;
- ishost = 0;
- }
+ prefixlen(*++argv);
break;
-#endif
case K_MTU:
case K_HOPCOUNT:
case K_EXPIRE:
@@ -1127,32 +1117,59 @@ netdone:
exit(1);
}
-#ifdef INET6
int
prefixlen(s)
char *s;
{
int len = atoi(s), q, r;
+ int max;
- rtm_addrs |= RTA_NETMASK;
- if (len < -1 || len > 129) {
- (void) fprintf(stderr, "%s: bad value\n", s);
+ switch (af) {
+ case AF_INET:
+ max = sizeof(struct in_addr) * 8;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ max = sizeof(struct in6_addr) * 8;
+ break;
+#endif
+ default:
+ (void) fprintf(stderr,
+ "prefixlen is not supported with af %d\n", af);
exit(1);
}
+ rtm_addrs |= RTA_NETMASK;
+ if (len < -1 || len > max) {
+ (void) fprintf(stderr, "%s: bad value\n", s);
+ exit(1);
+ }
+
q = len >> 3;
r = len & 7;
- so_mask.sin6.sin6_family = AF_INET6;
- so_mask.sin6.sin6_len = sizeof(struct sockaddr_in6);
- memset((void *)&so_mask.sin6.sin6_addr, 0,
- sizeof(so_mask.sin6.sin6_addr));
- if (q > 0)
- memset((void *)&so_mask.sin6.sin6_addr, 0xff, q);
- if (r > 0)
- *((u_char *)&so_mask.sin6.sin6_addr + q) = (0xff00 >> r) & 0xff;
- return (len);
-}
+ switch (af) {
+ case AF_INET:
+ memset(&so_mask, 0, sizeof(so_mask));
+ so_mask.sin.sin_family = AF_INET;
+ so_mask.sin.sin_len = sizeof(struct sockaddr_in);
+ so_mask.sin.sin_addr.s_addr = htonl(0xffffffff << (32 - len));
+ break;
+#ifdef INET6
+ case AF_INET6:
+ so_mask.sin6.sin6_family = AF_INET6;
+ so_mask.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ memset((void *)&so_mask.sin6.sin6_addr, 0,
+ sizeof(so_mask.sin6.sin6_addr));
+ if (q > 0)
+ memset((void *)&so_mask.sin6.sin6_addr, 0xff, q);
+ if (r > 0)
+ *((u_char *)&so_mask.sin6.sin6_addr + q) =
+ (0xff00 >> r) & 0xff;
+ break;
#endif
+ }
+ return(len);
+}
int
x25_makemask()