summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric Berger <cedric@cvs.openbsd.org>2004-06-09 19:32:09 +0000
committerCedric Berger <cedric@cvs.openbsd.org>2004-06-09 19:32:09 +0000
commitf5ab5fbbc994e5197e8b9a9d36e316d08b172dc7 (patch)
tree006bd2b5e0df76755349640cdc1b9d3d8264b1a3
parent286ab264183890dbc85ed24cf3007712d45f7e50 (diff)
Fix IPv4 name->address translation. Addresses like "10.1000" will not be
accepted anymore, but constructs like "route add 10.1.2/24 <gw>" will finally do the right thing. ok millert@
-rw-r--r--sbin/route/route.c101
1 files changed, 47 insertions, 54 deletions
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 649dd964b14..b60e94a6764 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.67 2004/06/06 17:08:23 cedric Exp $ */
+/* $OpenBSD: route.c,v 1.68 2004/06/09 19:32:08 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.67 2004/06/06 17:08:23 cedric Exp $";
+static const char rcsid[] = "$OpenBSD: route.c,v 1.68 2004/06/09 19:32:08 cedric Exp $";
#endif
#endif /* not lint */
@@ -69,6 +69,7 @@ static const char rcsid[] = "$OpenBSD: route.c,v 1.67 2004/06/06 17:08:23 cedric
#include <stdlib.h>
#include <string.h>
#include <paths.h>
+#include <err.h>
#include "keywords.h"
@@ -888,6 +889,7 @@ inet_makenetandmask(u_int32_t net, struct sockaddr_in *sin, int bits, int which)
else
mask = -1;
}
+ addr &= mask;
sin->sin_addr.s_addr = htonl(addr);
sin = (which == RTA_DST) ? &so_mask.sin : &so_srcmask.sin;
sin->sin_addr.s_addr = htonl(mask);
@@ -940,15 +942,14 @@ getaddr(int which, char *s, struct hostent **hpp)
struct ccitt_addr *ccitt_addr(char *, struct sockaddr_x25 *);
struct hostent *hp;
struct netent *np;
- u_long val;
- char *q, qs;
- int afamily;
+ int afamily, bits;
if (af == 0) {
af = AF_INET;
aflen = sizeof(struct sockaddr_in);
}
afamily = af; /* local copy of af so we can change it */
+
rtm_addrs |= which;
switch (which) {
case RTA_DST:
@@ -969,7 +970,6 @@ getaddr(int which, char *s, struct hostent **hpp)
break;
case RTA_IFA:
su = &so_ifa;
- su->sa.sa_family = af;
break;
case RTA_SRC:
su = &so_src;
@@ -978,16 +978,16 @@ getaddr(int which, char *s, struct hostent **hpp)
su = &so_srcmask;
break;
default:
- usage("Internal Error");
- /*NOTREACHED*/
+ errx(1, "internal error");
}
su->sa.sa_len = aflen;
- su->sa.sa_family = afamily; /* cases that don't want it have left already */
+ su->sa.sa_family = afamily;
+
if (strcmp(s, "default") == 0) {
switch (which) {
case RTA_DST:
forcenet++;
- (void) getaddr(RTA_NETMASK, s, 0);
+ getaddr(RTA_NETMASK, s, 0);
break;
case RTA_NETMASK:
case RTA_GENMASK:
@@ -995,6 +995,7 @@ getaddr(int which, char *s, struct hostent **hpp)
}
return (0);
}
+
switch (afamily) {
#ifdef INET6
case AF_INET6:
@@ -1093,53 +1094,45 @@ getaddr(int which, char *s, struct hostent **hpp)
return (1);
case AF_INET:
- default:
- break;
- }
-
- if (hpp == NULL)
- hpp = &hp;
- *hpp = NULL;
-
- q = strchr(s,'/');
- 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), which);
- return (0);
+ if (hpp != NULL)
+ *hpp = NULL;
+ if ((which == RTA_DST || which == RTA_SRC) && !forcehost) {
+ bits = inet_net_pton(AF_INET, s, &su->sin.sin_addr,
+ sizeof(su->sin.sin_addr));
+ if (bits == 32) {
+ if (forcenet)
+ errx(1, "%s: not a network", s);
+ return (1);
+ }
+ if (bits >= 0) {
+ inet_makenetandmask(ntohl(
+ su->sin.sin_addr.s_addr),
+ &su->sin, bits, which);
+ return (0);
+ }
+ np = getnetbyname(s);
+ if (np != NULL && np->n_net != 0) {
+ inet_makenetandmask(np->n_net, &su->sin, 0,
+ which);
+ return (0);
+ }
+ if (forcenet)
+ errx(1, "%s: not a network", s);
}
- *q =qs;
- }
- if (((val = inet_addr(s)) != INADDR_NONE) &&
- ((which != RTA_DST && which != RTA_SRC) || forcenet == 0)) {
- su->sin.sin_addr.s_addr = val;
- if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
+ if (inet_pton(AF_INET, s, &su->sin.sin_addr) == 1)
+ return (1);
+ hp = gethostbyname(s);
+ if (hp != NULL) {
+ if (hpp != NULL)
+ *hpp = hp;
+ su->sin.sin_addr = *(struct in_addr *)hp->h_addr;
return (1);
- else {
- val = ntohl(val);
- goto netdone;
}
+ errx(1, "%s: bad address", s);
+
+ default:
+ errx(1, "%d: bad address family", afamily);
}
- if ((val = inet_network(s)) != INADDR_NONE ||
- (forcehost == 0 && (np = getnetbyname(s)) != NULL &&
- (val = np->n_net) != 0)) {
-netdone:
- if (which == RTA_DST || which == RTA_SRC)
- inet_makenetandmask(val, &su->sin, 0, which);
- return (0);
- }
- hp = gethostbyname(s);
- if (hp) {
- *hpp = hp;
- su->sin.sin_family = hp->h_addrtype;
- memcpy(&su->sin.sin_addr, hp->h_addr, hp->h_length);
- return (1);
- }
- (void) fprintf(stderr, "route: %s: bad value\n", s);
- exit(1);
}
int
@@ -1368,7 +1361,7 @@ rtmsg(int cmd, int flags)
#define NEXTADDR(w, u) \
if (rtm_addrs & (w)) {\
l = ROUNDUP(u.sa.sa_len); memcpy(cp, &(u), l); cp += l;\
- if (verbose) sodump(&(u),"u");\
+ if (verbose) sodump(&(u),#u);\
}
errno = 0;