Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/route Alloc dynamically sockunions in sou.
details: https://anonhg.NetBSD.org/src/rev/5cd09b92733c
branches: trunk
changeset: 766395:5cd09b92733c
user: kefren <kefren%NetBSD.org@localhost>
date: Tue Jun 21 14:33:14 2011 +0000
description:
Alloc dynamically sockunions in sou.
Teach route(8) about multiple tags. E.G.: -tag 100,20,33
XXX: needs documentation
diffstat:
sbin/route/route.c | 196 ++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 144 insertions(+), 52 deletions(-)
diffs (truncated from 389 to 300 lines):
diff -r 400b37b2685e -r 5cd09b92733c sbin/route/route.c
--- a/sbin/route/route.c Tue Jun 21 14:30:19 2011 +0000
+++ b/sbin/route/route.c Tue Jun 21 14:33:14 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: route.c,v 1.128 2011/02/01 01:39:19 matt Exp $ */
+/* $NetBSD: route.c,v 1.129 2011/06/21 14:33:14 kefren Exp $ */
/*
* Copyright (c) 1983, 1989, 1991, 1993
@@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95";
#else
-__RCSID("$NetBSD: route.c,v 1.128 2011/02/01 01:39:19 matt Exp $");
+__RCSID("$NetBSD: route.c,v 1.129 2011/06/21 14:33:14 kefren Exp $");
#endif
#endif /* not lint */
@@ -97,7 +97,8 @@
typedef union sockunion *sup;
struct sou {
- union sockunion so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp, so_mpls;
+ union sockunion *so_dst, *so_gate, *so_mask, *so_genmask, *so_ifa,
+ *so_ifp, *so_mpls;
};
static char *any_ntoa(const struct sockaddr *);
@@ -116,6 +117,8 @@
static void monitor(void);
static int print_getmsg(struct rt_msghdr *, int, struct sou *);
static const char *linkstate(struct if_msghdr *);
+static sup readtag(sup, const char *);
+static void addtag(sup, const char *, int);
#endif /* SMALL */
static int rtmsg(int, int, struct sou *);
static void mask_addr(struct sou *);
@@ -588,11 +591,21 @@
case AF_MPLS:
{
union mpls_shim ms;
+ const union mpls_shim *pms;
+ int psize = sizeof(struct sockaddr_mpls);
ms.s_addr =((const struct sockaddr_mpls*)sa)->smpls_addr.s_addr;
ms.s_addr = ntohl(ms.s_addr);
snprintf(line, sizeof(line), "%u", ms.shim.label);
+ pms = &((const struct sockaddr_mpls*)sa)->smpls_addr;
+ while(psize < sa->sa_len) {
+ pms++;
+ ms.s_addr = ntohl(pms->s_addr);
+ snprintf(line, sizeof(line), "%s %u", line,
+ ms.shim.label);
+ psize += sizeof(ms);
+ }
break;
}
#endif /* SMALL */
@@ -795,7 +808,18 @@
struct hostent *hp = 0;
struct sou sou, *soup = &sou;
- memset(&sou, 0, sizeof(sou));
+ sou.so_dst = calloc(1, sizeof(union sockunion));
+ sou.so_gate = calloc(1, sizeof(union sockunion));
+ sou.so_mask = calloc(1, sizeof(union sockunion));
+ sou.so_genmask = calloc(1, sizeof(union sockunion));
+ sou.so_ifa = calloc(1, sizeof(union sockunion));
+ sou.so_ifp = calloc(1, sizeof(union sockunion));
+ sou.so_mpls = calloc(1, sizeof(union sockunion));
+
+ if (sou.so_dst == NULL || sou.so_gate == NULL || sou.so_mask == NULL ||
+ sou.so_genmask == NULL || sou.so_ifa == NULL || sou.so_ifp == NULL ||
+ sou.so_mpls == NULL)
+ errx(EXIT_FAILURE, "Cannot allocate memory");
cmd = argv[0];
af = AF_UNSPEC;
@@ -849,6 +873,7 @@
case K_TAG:
if (!--argc)
usage(1+*argv);
+ af = AF_MPLS;
aflen = sizeof(struct sockaddr_mpls);
(void)getaddr(RTA_TAG, *++argv, 0, soup);
break;
@@ -1016,7 +1041,7 @@
break;
if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {
hp->h_addr_list++;
- memmove(&soup->so_gate.sin.sin_addr, hp->h_addr_list[0],
+ memmove(&soup->so_gate->sin.sin_addr, hp->h_addr_list[0],
hp->h_length);
} else
break;
@@ -1030,13 +1055,21 @@
(void)printf(": gateway %s", gateway);
if (attempts > 1 && ret == 0 && af == AF_INET)
(void)printf(" (%s)",
- inet_ntoa(soup->so_gate.sin.sin_addr));
+ inet_ntoa(soup->so_gate->sin.sin_addr));
}
if (ret == 0)
(void)printf("\n");
else
(void)printf(": %s\n", route_strerror(oerrno));
}
+ free(sou.so_dst);
+ free(sou.so_gate);
+ free(sou.so_mask);
+ free(sou.so_genmask);
+ free(sou.so_ifa);
+ free(sou.so_ifp);
+ free(sou.so_mpls);
+
return ret != 0;
}
@@ -1090,7 +1123,7 @@
mask = -1;
}
isin->sin_addr.s_addr = htonl(addr);
- sin = &soup->so_mask.sin;
+ sin = &soup->so_mask->sin;
sin->sin_addr.s_addr = htonl(mask);
sin->sin_len = 0;
sin->sin_family = 0;
@@ -1154,28 +1187,28 @@
rtm_addrs |= which;
switch (which) {
case RTA_DST:
- su = &soup->so_dst;
+ su = soup->so_dst;
break;
case RTA_GATEWAY:
- su = &soup->so_gate;
+ su = soup->so_gate;
break;
case RTA_NETMASK:
- su = &soup->so_mask;
+ su = soup->so_mask;
break;
case RTA_GENMASK:
- su = &soup->so_genmask;
+ su = soup->so_genmask;
break;
case RTA_IFP:
- su = &soup->so_ifp;
+ su = soup->so_ifp;
afamily = AF_LINK;
break;
case RTA_IFA:
- su = &soup->so_ifa;
+ su = soup->so_ifa;
su->sa.sa_family = af;
break;
#ifndef SMALL
case RTA_TAG:
- su = &soup->so_mpls;
+ su = soup->so_mpls;
afamily = AF_MPLS;
break;
#endif
@@ -1285,15 +1318,13 @@
rtm_addrs |= RTA_NETMASK;
return(forcehost || su->sat.sat_addr.s_node != 0);
case AF_MPLS:
- /* Tag should be a positive value, limited to 20 bits */
- if (atoi(s) < 0 || atoi(s) >= (1 << 20))
- errx(1, "bad tag: %s", s);
- su->smpls.smpls_addr.s_addr = 0;
- su->smpls.smpls_addr.shim.label = atoi(s);
- su->smpls.smpls_addr.s_addr =
- htonl(su->smpls.smpls_addr.s_addr);
-
- /* We don't have netmasks for tags */
+ if (which == RTA_DST)
+ soup->so_dst = readtag(su, s);
+ else if (which == RTA_TAG)
+ soup->so_mpls = readtag(su, s);
+ else
+ errx(EXIT_FAILURE, "MPLS can be used only as "
+ "DST or TAG");
return 1;
#endif
@@ -1353,6 +1384,56 @@
/*NOTREACHED*/
}
+static sup
+readtag(sup su, const char *s)
+{
+ char *p, *n, *norig;
+ int mplssize = 0;
+ sup retsu = su;
+
+ n = (char*)malloc(strlen(s) + 1);
+ if (n == NULL)
+ errx(EXIT_FAILURE, "%s: Cannot allocate memory", s);
+ norig = n;
+ strlcpy(n, s, strlen(s) + 1);
+ for (uint i = 0; i < strlen(n); i++)
+ if(n[i] == ',')
+ mplssize++;
+
+#define MPLS_NEW_SIZE (sizeof(struct sockaddr_mpls) + \
+ mplssize * sizeof(union mpls_shim))
+
+ if (mplssize != 0 && sizeof(union sockunion) < MPLS_NEW_SIZE) {
+ free(su);
+ retsu = malloc(MPLS_NEW_SIZE);
+ retsu->smpls.smpls_family = AF_MPLS;
+ }
+ retsu->smpls.smpls_len = MPLS_NEW_SIZE;
+ mplssize = 0;
+ while ((p = strchr(n, ',')) != NULL) {
+ p[0] = '\0';
+ addtag(retsu, n, mplssize);
+ n = p + 1;
+ mplssize++;
+ }
+ addtag(retsu, n, mplssize);
+
+ free(norig);
+ return retsu;
+}
+
+static void
+addtag(sup su, const char *s, int where)
+{
+ union mpls_shim *ms = &su->smpls.smpls_addr;
+
+ if (atoi(s) < 0 || atoi(s) >= (1 << 20))
+ errx(EXIT_FAILURE, "%s: Bad tag", s);
+ ms[where].s_addr = 0;
+ ms[where].shim.label = atoi(s);
+ ms[where].s_addr = htonl(ms[where].s_addr);
+}
+
int
prefixlen(const char *s, struct sou *soup)
{
@@ -1381,22 +1462,22 @@
r = len & 7;
switch (af) {
case AF_INET:
- memset(&soup->so_mask, 0, sizeof(soup->so_mask));
- soup->so_mask.sin.sin_family = AF_INET;
- soup->so_mask.sin.sin_len = sizeof(struct sockaddr_in);
- soup->so_mask.sin.sin_addr.s_addr = (len == 0 ? 0
+ memset(soup->so_mask, 0, sizeof(soup->so_mask));
+ soup->so_mask->sin.sin_family = AF_INET;
+ soup->so_mask->sin.sin_len = sizeof(struct sockaddr_in);
+ soup->so_mask->sin.sin_addr.s_addr = (len == 0 ? 0
: htonl(0xffffffff << (32 - len)));
break;
#ifdef INET6
case AF_INET6:
- soup->so_mask.sin6.sin6_family = AF_INET6;
- soup->so_mask.sin6.sin6_len = sizeof(struct sockaddr_in6);
- memset(&soup->so_mask.sin6.sin6_addr, 0,
- sizeof(soup->so_mask.sin6.sin6_addr));
+ soup->so_mask->sin6.sin6_family = AF_INET6;
+ soup->so_mask->sin6.sin6_len = sizeof(struct sockaddr_in6);
+ memset(&soup->so_mask->sin6.sin6_addr, 0,
+ sizeof(soup->so_mask->sin6.sin6_addr));
if (q > 0)
- memset(&soup->so_mask.sin6.sin6_addr, 0xff, q);
+ memset(&soup->so_mask->sin6.sin6_addr, 0xff, q);
if (r > 0)
- *((u_char *)&soup->so_mask.sin6.sin6_addr + q) =
+ *((u_char *)&soup->so_mask->sin6.sin6_addr + q) =
(0xff00 >> r) & 0xff;
break;
#endif
@@ -1478,8 +1559,8 @@
#define NEXTADDR(w, u) \
if (rtm_addrs & (w)) {\
- l = RT_ROUNDUP(u.sa.sa_len); memmove(cp, &(u), l); cp += l;\
- if (verbose && ! shortoutput) sodump(&(u),#u);\
+ l = RT_ROUNDUP(u->sa.sa_len); memmove(cp, u, l); cp += l;\
+ if (verbose && ! shortoutput) sodump(u,#u);\
}
errno = 0;
@@ -1493,9 +1574,9 @@
return -1;
#else /* SMALL */
cmd = RTM_GET;
- if (soup->so_ifp.sa.sa_family == AF_UNSPEC) {
- soup->so_ifp.sa.sa_family = AF_LINK;
- soup->so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
+ if (soup->so_ifp->sa.sa_family == AF_UNSPEC) {
+ soup->so_ifp->sa.sa_family = AF_LINK;
+ soup->so_ifp->sa.sa_len = sizeof(struct sockaddr_dl);
rtm_addrs |= RTA_IFP;
}
Home |
Main Index |
Thread Index |
Old Index