Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Oct 2013 17:07:33 +0200
From:      Sebastian Huber <sebastian.huber@embedded-brains.de>
To:        FreeBSD Hackers <freebsd-hackers@freebsd.org>
Subject:   Global variables in system programs
Message-ID:  <525D5A35.4040005@embedded-brains.de>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------080606050100070303070204
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Hello,

I work currently on a port of the FreeBSD network stack to a real-time 
operating system for embedded targets.  Here the applications are statically 
linked with the operating system and the network stack.  We would like to use 
the standard FreeBSD system programs to configure the network stack, e.g. 
ROUTE(8), IFCONFIG(8), etc.  For example

static const char *const argv[] = {
   "ifconfig",
   "lo0",
   "127.0.0.1"
};

ifconfig(3, &argv[0]);

These programs use some global variables.  In a statically linked context we 
have now the following problems

o we cannot call the programs concurrently,

o we have to initialize the values each time.

We would like to follow the FreeBSD sources to stay up-to-date.  So it is 
desirable for us to keep the divergence from the original sources as small as 
possible.  Are patches acceptable for the FreeBSD project that alter system 
programs such that

o global variables are moved into context structures,

o constant global variables are declared as "const", and

o variables and functions are declared as "static" if possible?

Attached is a patch for the ROUTE(8) program to give an example.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

--------------080606050100070303070204
Content-Type: text/x-patch;
 name="0001-FIXME-Add-and-use-context-for-route-command.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="0001-FIXME-Add-and-use-context-for-route-command.patch"

>From fa564bb20b40c613c7607cb07116fc3813a7055d Mon Sep 17 00:00:00 2001
From: Sebastian Huber <sebastian.huber@embedded-brains.de>
Date: Tue, 15 Oct 2013 16:39:53 +0200
Subject: [PATCH] FIXME: Add and use context for route command

---
 freebsd/sbin/route/route.c |  453 +++++++++++++++++++++++---------------------
 1 files changed, 238 insertions(+), 215 deletions(-)

diff --git a/freebsd/sbin/route/route.c b/freebsd/sbin/route/route.c
index 206533f..896c7b2 100644
--- a/freebsd/sbin/route/route.c
+++ b/freebsd/sbin/route/route.c
@@ -72,7 +72,7 @@ static const char rcsid[] =
 #include <unistd.h>
 #include <ifaddrs.h>
 
-struct keytab {
+static const struct keytab {
 	char	*kt_cp;
 	int	kt_i;
 } keywords[] = {
@@ -80,41 +80,53 @@ struct keytab {
 	{0, 0}
 };
 
-struct	ortentry route;
-union	sockunion {
-	struct	sockaddr sa;
-	struct	sockaddr_in sin;
+struct route_context {
+	struct	ortentry route;
+	union	sockunion {
+		struct	sockaddr sa;
+		struct	sockaddr_in sin;
 #ifdef INET6
-	struct	sockaddr_in6 sin6;
+		struct	sockaddr_in6 sin6;
 #endif
-	struct	sockaddr_at sat;
-	struct	sockaddr_dl sdl;
-	struct	sockaddr_inarp sinarp;
-	struct	sockaddr_storage ss; /* added to avoid memory overrun */
-} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
+		struct	sockaddr_at sat;
+		struct	sockaddr_dl sdl;
+		struct	sockaddr_inarp sinarp;
+		struct	sockaddr_storage ss; /* added to avoid memory overrun */
+	} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
+
+	int	pid, rtm_addrs;
+	int	s;
+	int	forcehost, forcenet, nflag, af, qflag, tflag;
+	int	iflag, verbose, aflen;
+	int	locking, lockrest, debugonly;
+	struct	rt_metrics rt_metrics;
+	u_long  rtm_inits;
+	uid_t	uid;
+	struct {
+		struct	rt_msghdr m_rtm;
+		char	m_space[512];
+	} m_rtmsg;
+} route_context;
 
 typedef union sockunion *sup;
-int	pid, rtm_addrs;
-int	s;
-int	forcehost, forcenet, doflush, nflag, af, qflag, tflag, keyword();
-int	iflag, verbose, aflen = sizeof (struct sockaddr_in);
-int	locking, lockrest, debugonly;
-struct	rt_metrics rt_metrics;
-u_long  rtm_inits;
-uid_t	uid;
-int	atalk_aton(const char *, struct at_addr *);
-char	*atalk_ntoa(struct at_addr);
-const char	*routename(), *netname();
-void	flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
-void	print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
+
+static int	keyword();
+static int	atalk_aton(const char *, struct at_addr *);
+static char	*atalk_ntoa(struct at_addr);
+static const char	*routename(), *netname();
+static void	interfaces(struct route_context *ctx);
+static void	set_metric();
+static void	flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
+static void	print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
+static void	inet_makenetandmask();
 #ifdef INET6
-static int inet6_makenetandmask(struct sockaddr_in6 *, char *);
+static int	inet6_makenetandmask(struct sockaddr_in6 *, char *);
 #endif
-int	getaddr(), rtmsg(), x25_makemask();
-int	prefixlen();
-extern	char *iso_ntoa();
+static int	getaddr(), rtmsg();
+static int	prefixlen();
+extern char	*iso_ntoa();
 
-void usage(const char *) __dead2;
+static void usage(const char *) __dead2;
 
 void
 usage(cp)
@@ -132,27 +144,31 @@ main(argc, argv)
 	int argc;
 	char **argv;
 {
+	struct route_context *ctx;
 	int ch;
 
+	ctx = &route_context;
+	ctx->aflen = sizeof (struct sockaddr_in);
+
 	if (argc < 2)
 		usage((char *)NULL);
 
 	while ((ch = getopt(argc, argv, "nqdtv")) != -1)
 		switch(ch) {
 		case 'n':
-			nflag = 1;
+			ctx->nflag = 1;
 			break;
 		case 'q':
-			qflag = 1;
+			ctx->qflag = 1;
 			break;
 		case 'v':
-			verbose = 1;
+			ctx->verbose = 1;
 			break;
 		case 't':
-			tflag = 1;
+			ctx->tflag = 1;
 			break;
 		case 'd':
-			debugonly = 1;
+			ctx->debugonly = 1;
 			break;
 		case '?':
 		default:
@@ -161,34 +177,34 @@ main(argc, argv)
 	argc -= optind;
 	argv += optind;
 
-	pid = getpid();
-	uid = geteuid();
-	if (tflag)
-		s = open(_PATH_DEVNULL, O_WRONLY, 0);
+	ctx->pid = getpid();
+	ctx->uid = geteuid();
+	if (ctx->tflag)
+		ctx->s = open(_PATH_DEVNULL, O_WRONLY, 0);
 	else
-		s = socket(PF_ROUTE, SOCK_RAW, 0);
-	if (s < 0)
+		ctx->s = socket(PF_ROUTE, SOCK_RAW, 0);
+	if (ctx->s < 0)
 		err(EX_OSERR, "socket");
 	if (*argv)
 		switch (keyword(*argv)) {
 		case K_GET:
 		case K_SHOW:
-			uid = 0;
+			ctx->uid = 0;
 			/* FALLTHROUGH */
 
 		case K_CHANGE:
 		case K_ADD:
 		case K_DEL:
 		case K_DELETE:
-			newroute(argc, argv);
+			newroute(ctx, argc, argv);
 			/* NOTREACHED */
 
 		case K_MONITOR:
-			monitor();
+			monitor(ctx);
 			/* NOTREACHED */
 
 		case K_FLUSH:
-			flushroutes(argc, argv);
+			flushroutes(ctx, argc, argv);
 			exit(0);
 			/* NOTREACHED */
 		}
@@ -201,7 +217,8 @@ main(argc, argv)
  * associated with network interfaces.
  */
 void
-flushroutes(argc, argv)
+flushroutes(ctx, argc, argv)
+	struct route_context *ctx;
 	int argc;
 	char *argv[];
 {
@@ -210,27 +227,27 @@ flushroutes(argc, argv)
 	char *buf, *next, *lim;
 	struct rt_msghdr *rtm;
 
-	if (uid && !debugonly) {
+	if (ctx->uid && !ctx->debugonly) {
 		errx(EX_NOPERM, "must be root to alter routing table");
 	}
-	shutdown(s, SHUT_RD); /* Don't want to read back our messages */
+	shutdown(ctx->s, SHUT_RD); /* Don't want to read back our messages */
 	if (argc > 1) {
 		argv++;
 		if (argc == 2 && **argv == '-')
 		    switch (keyword(*argv + 1)) {
 			case K_INET:
-				af = AF_INET;
+				ctx->af = AF_INET;
 				break;
 #ifdef INET6
 			case K_INET6:
-				af = AF_INET6;
+				ctx->af = AF_INET6;
 				break;
 #endif
 			case K_ATALK:
-				af = AF_APPLETALK;
+				ctx->af = AF_APPLETALK;
 				break;
 			case K_LINK:
-				af = AF_LINK;
+				ctx->af = AF_LINK;
 				break;
 			default:
 				goto bad;
@@ -258,26 +275,26 @@ retry:
 		err(EX_OSERR, "route-sysctl-get");
 	}
 	lim = buf + needed;
-	if (verbose)
+	if (ctx->verbose)
 		(void) printf("Examining routing table from sysctl\n");
 	seqno = 0;		/* ??? */
 	for (next = buf; next < lim; next += rtm->rtm_msglen) {
 		rtm = (struct rt_msghdr *)next;
-		if (verbose)
-			print_rtmsg(rtm, rtm->rtm_msglen);
+		if (ctx->verbose)
+			print_rtmsg(ctx, rtm, rtm->rtm_msglen);
 		if ((rtm->rtm_flags & RTF_GATEWAY) == 0)
 			continue;
-		if (af) {
+		if (ctx->af) {
 			struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
 
-			if (sa->sa_family != af)
+			if (sa->sa_family != ctx->af)
 				continue;
 		}
-		if (debugonly)
+		if (ctx->debugonly)
 			continue;
 		rtm->rtm_type = RTM_DELETE;
 		rtm->rtm_seq = seqno;
-		rlen = write(s, next, rtm->rtm_msglen);
+		rlen = write(ctx->s, next, rtm->rtm_msglen);
 		if (rlen < 0 && errno == EPERM)
 			err(1, "write to routing socket");
 		if (rlen < (int)rtm->rtm_msglen) {
@@ -288,14 +305,14 @@ retry:
 			break;
 		}
 		seqno++;
-		if (qflag)
+		if (ctx->qflag)
 			continue;
-		if (verbose)
-			print_rtmsg(rtm, rlen);
+		if (ctx->verbose)
+			print_rtmsg(ctx, rtm, rlen);
 		else {
 			struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
 			(void) printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ?
-			    routename(sa) : netname(sa));
+			    routename(sa) : netname(ctx, sa));
 			sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa);
 			(void) printf("%-20.20s ", routename(sa));
 			(void) printf("done\n");
@@ -304,7 +321,8 @@ retry:
 }
 
 const char *
-routename(sa)
+routename(ctx, sa)
+	struct route_context *ctx;
 	struct sockaddr *sa;
 {
 	char *cp;
@@ -334,7 +352,7 @@ routename(sa)
 		cp = 0;
 		if (in.s_addr == INADDR_ANY || sa->sa_len < 4)
 			cp = "default";
-		if (cp == 0 && !nflag) {
+		if (cp == 0 && !ctx->nflag) {
 			hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),
 				AF_INET);
 			if (hp) {
@@ -373,7 +391,7 @@ routename(sa)
 			sin6.sin6_addr.s6_addr[3] = 0;
 		}
 #endif
-		if (nflag)
+		if (ctx->nflag)
 			niflags |= NI_NUMERICHOST;
 		if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
 		    line, sizeof(line), NULL, 0, niflags) != 0)
@@ -413,7 +431,8 @@ routename(sa)
  * The address is assumed to be that of a net or subnet, not a host.
  */
 const char *
-netname(sa)
+netname(ctx, sa)
+	struct route_context *ctx;
 	struct sockaddr *sa;
 {
 	char *cp = 0;
@@ -432,7 +451,7 @@ netname(sa)
 		i = in.s_addr = ntohl(in.s_addr);
 		if (in.s_addr == 0)
 			cp = "default";
-		else if (!nflag) {
+		else if (!ctx->nflag) {
 			if (IN_CLASSA(i)) {
 				mask = IN_CLASSA_NET;
 				subnetshift = 8;
@@ -498,7 +517,7 @@ netname(sa)
 			sin6.sin6_addr.s6_addr[3] = 0;
 		}
 #endif
-		if (nflag)
+		if (ctx->nflag)
 			niflags |= NI_NUMERICHOST;
 		if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
 		    line, sizeof(line), NULL, 0, niflags) != 0)
@@ -535,7 +554,8 @@ netname(sa)
 }
 
 void
-set_metric(value, key)
+set_metric(ctx, value, key)
+	struct route_context *ctx;
 	char *value;
 	int key;
 {
@@ -543,7 +563,7 @@ set_metric(value, key)
 	u_long noval, *valp = &noval;
 
 	switch (key) {
-#define caseof(x, y, z)	case x: valp = &rt_metrics.z; flag = y; break
+#define caseof(x, y, z)	case x: valp = &ctx->rt_metrics.z; flag = y; break
 	caseof(K_MTU, RTV_MTU, rmx_mtu);
 	caseof(K_HOPCOUNT, RTV_HOPCOUNT, rmx_hopcount);
 	caseof(K_EXPIRE, RTV_EXPIRE, rmx_expire);
@@ -554,16 +574,17 @@ set_metric(value, key)
 	caseof(K_RTTVAR, RTV_RTTVAR, rmx_rttvar);
 	caseof(K_WEIGHT, RTV_WEIGHT, rmx_weight);
 	}
-	rtm_inits |= flag;
-	if (lockrest || locking)
-		rt_metrics.rmx_locks |= flag;
-	if (locking)
-		locking = 0;
+	ctx->rtm_inits |= flag;
+	if (ctx->lockrest || ctx->locking)
+		ctx->rt_metrics.rmx_locks |= flag;
+	if (ctx->locking)
+		ctx->locking = 0;
 	*valp = atoi(value);
 }
 
 void
-newroute(argc, argv)
+newroute(ctx, argc, argv)
+	struct route_context *ctx;
 	int argc;
 	char **argv;
 {
@@ -572,53 +593,53 @@ newroute(argc, argv)
 	int key;
 	struct hostent *hp = 0;
 
-	if (uid) {
+	if (ctx->uid) {
 		errx(EX_NOPERM, "must be root to alter routing table");
 	}
 	cmd = argv[0];
 	if (*cmd != 'g' && *cmd != 's')
-		shutdown(s, SHUT_RD); /* Don't want to read back our messages */
+		shutdown(ctx->s, SHUT_RD); /* Don't want to read back our messages */
 
 	while (--argc > 0) {
 		if (**(++argv)== '-') {
 			switch (key = keyword(1 + *argv)) {
 			case K_LINK:
-				af = AF_LINK;
-				aflen = sizeof(struct sockaddr_dl);
+				ctx->af = AF_LINK;
+				ctx->aflen = sizeof(struct sockaddr_dl);
 				break;
 			case K_INET:
-				af = AF_INET;
-				aflen = sizeof(struct sockaddr_in);
+				ctx->af = AF_INET;
+				ctx->aflen = sizeof(struct sockaddr_in);
 				break;
 #ifdef INET6
 			case K_INET6:
-				af = AF_INET6;
-				aflen = sizeof(struct sockaddr_in6);
+				ctx->af = AF_INET6;
+				ctx->aflen = sizeof(struct sockaddr_in6);
 				break;
 #endif
 			case K_ATALK:
-				af = AF_APPLETALK;
-				aflen = sizeof(struct sockaddr_at);
+				ctx->af = AF_APPLETALK;
+				ctx->aflen = sizeof(struct sockaddr_at);
 				break;
 			case K_SA:
-				af = PF_ROUTE;
-				aflen = sizeof(union sockunion);
+				ctx->af = PF_ROUTE;
+				ctx->aflen = sizeof(union sockunion);
 				break;
 			case K_IFACE:
 			case K_INTERFACE:
-				iflag++;
+				ctx->iflag++;
 				break;
 			case K_NOSTATIC:
 				flags &= ~RTF_STATIC;
 				break;
 			case K_LOCK:
-				locking = 1;
+				ctx->locking = 1;
 				break;
 			case K_LOCKREST:
-				lockrest = 1;
+				ctx->lockrest = 1;
 				break;
 			case K_HOST:
-				forcehost++;
+				ctx->forcehost++;
 				break;
 			case K_REJECT:
 				flags |= RTF_REJECT;
@@ -679,16 +700,16 @@ newroute(argc, argv)
 				(void) getaddr(RTA_NETMASK, *++argv, 0);
 				/* FALLTHROUGH */
 			case K_NET:
-				forcenet++;
+				ctx->forcenet++;
 				break;
 			case K_PREFIXLEN:
 				if (!--argc)
 					usage((char *)NULL);
-				if (prefixlen(*++argv) == -1) {
-					forcenet = 0;
+				if (prefixlen(ctx, *++argv) == -1) {
+					ctx->forcenet = 0;
 					ishost = 1;
 				} else {
-					forcenet = 1;
+					ctx->forcenet = 1;
 					ishost = 0;
 				}
 				break;
@@ -703,67 +724,67 @@ newroute(argc, argv)
 			case K_WEIGHT:
 				if (!--argc)
 					usage((char *)NULL);
-				set_metric(*++argv, key);
+				set_metric(ctx, *++argv, key);
 				break;
 			default:
 				usage(1+*argv);
 			}
 		} else {
-			if ((rtm_addrs & RTA_DST) == 0) {
+			if ((ctx->rtm_addrs & RTA_DST) == 0) {
 				dest = *argv;
 				ishost = getaddr(RTA_DST, *argv, &hp);
-			} else if ((rtm_addrs & RTA_GATEWAY) == 0) {
+			} else if ((ctx->rtm_addrs & RTA_GATEWAY) == 0) {
 				gateway = *argv;
 				(void) getaddr(RTA_GATEWAY, *argv, &hp);
 			} else {
 				(void) getaddr(RTA_NETMASK, *argv, 0);
-				forcenet = 1;
+				ctx->forcenet = 1;
 			}
 		}
 	}
-	if (forcehost) {
+	if (ctx->forcehost) {
 		ishost = 1;
 #ifdef INET6
-		if (af == AF_INET6) {
-			rtm_addrs &= ~RTA_NETMASK;
-				memset((void *)&so_mask, 0, sizeof(so_mask));
+		if (ctx->af == AF_INET6) {
+			ctx->rtm_addrs &= ~RTA_NETMASK;
+				memset((void *)&ctx->so_mask, 0, sizeof(ctx->so_mask));
 		}
 #endif 
 	}
-	if (forcenet)
+	if (ctx->forcenet)
 		ishost = 0;
 	flags |= RTF_UP;
 	if (ishost)
 		flags |= RTF_HOST;
-	if (iflag == 0)
+	if (ctx->iflag == 0)
 		flags |= RTF_GATEWAY;
 	if (proxy) {
-		so_dst.sinarp.sin_other = SIN_PROXY;
+		ctx->so_dst.sinarp.sin_other = SIN_PROXY;
 		flags |= RTF_ANNOUNCE;
 	}
 	for (attempts = 1; ; attempts++) {
 		errno = 0;
-		if ((ret = rtmsg(*cmd, flags)) == 0)
+		if ((ret = rtmsg(ctx, *cmd, flags)) == 0)
 			break;
 		if (errno != ENETUNREACH && errno != ESRCH)
 			break;
-		if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {
+		if (ctx->af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {
 			hp->h_addr_list++;
-			memmove(&so_gate.sin.sin_addr, hp->h_addr_list[0],
-			    MIN(hp->h_length, sizeof(so_gate.sin.sin_addr)));
+			memmove(&ctx->so_gate.sin.sin_addr, hp->h_addr_list[0],
+			    MIN(hp->h_length, sizeof(ctx->so_gate.sin.sin_addr)));
 		} else
 			break;
 	}
 	if (*cmd == 'g' || *cmd == 's')
 		exit(ret != 0);
-	if (!qflag) {
+	if (!ctx->qflag) {
 		oerrno = errno;
 		(void) printf("%s %s %s", cmd, ishost? "host" : "net", dest);
 		if (*gateway) {
 			(void) printf(": gateway %s", gateway);
-			if (attempts > 1 && ret == 0 && af == AF_INET)
+			if (attempts > 1 && ret == 0 && ctx->af == AF_INET)
 			    (void) printf(" (%s)",
-				inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));
+				inet_ntoa(((struct sockaddr_in *)&ctx->route.rt_gateway)->sin_addr));
 		}
 		if (ret == 0) {
 			(void) printf("\n");
@@ -796,14 +817,15 @@ newroute(argc, argv)
 }
 
 void
-inet_makenetandmask(net, sin, bits)
+inet_makenetandmask(ctx, net, sin, bits)
+	struct route_context *ctx;
 	u_long net, bits;
 	struct sockaddr_in *sin;
 {
 	u_long addr, mask = 0;
 	char *cp;
 
-	rtm_addrs |= RTA_NETMASK;
+	ctx->rtm_addrs |= RTA_NETMASK;
 	/* 
 	 * XXX: This approach unable to handle 0.0.0.1/32 correctly
 	 * as inet_network() converts 0.0.0.1 and 1 equally.
@@ -835,7 +857,7 @@ inet_makenetandmask(net, sin, bits)
 		mask = 0xffffffff << (32 - bits);
 
 	sin->sin_addr.s_addr = htonl(addr);
-	sin = &so_mask.sin;
+	sin = &ctx->so_mask.sin;
 	sin->sin_addr.s_addr = htonl(mask);
 	sin->sin_len = 0;
 	sin->sin_family = 0;
@@ -871,8 +893,8 @@ inet6_makenetandmask(sin6, plen)
 
 	if (!plen || strcmp(plen, "128") == 0)
 		return 1;
-	rtm_addrs |= RTA_NETMASK;
-	(void)prefixlen(plen);
+	ctx->rtm_addrs |= RTA_NETMASK;
+	(void)prefixlen(ctx, plen);
 	return 0;
 }
 #endif
@@ -882,7 +904,8 @@ inet6_makenetandmask(sin6, plen)
  * returning 1 if a host address, 0 if a network address.
  */
 int
-getaddr(which, s, hpp)
+getaddr(ctx, which, s, hpp)
+	struct route_context *ctx;
 	int which;
 	char *s;
 	struct hostent **hpp;
@@ -894,19 +917,19 @@ getaddr(which, s, hpp)
 	char *q;
 	int afamily;  /* local copy of af so we can change it */
 
-	if (af == 0) {
-		af = AF_INET;
-		aflen = sizeof(struct sockaddr_in);
+	if (ctx->af == 0) {
+		ctx->af = AF_INET;
+		ctx->aflen = sizeof(struct sockaddr_in);
 	}
-	afamily = af;
-	rtm_addrs |= which;
+	afamily = ctx->af;
+	ctx->rtm_addrs |= which;
 	switch (which) {
 	case RTA_DST:
-		su = &so_dst;
+		su = &ctx->so_dst;
 		break;
 	case RTA_GATEWAY:
-		su = &so_gate;
-		if (iflag) {
+		su = &ctx->so_gate;
+		if (ctx->iflag) {
 			struct ifaddrs *ifap, *ifa;
 			struct sockaddr_dl *sdl = NULL;
 
@@ -938,23 +961,23 @@ getaddr(which, s, hpp)
 		}
 		break;
 	case RTA_NETMASK:
-		su = &so_mask;
+		su = &ctx->so_mask;
 		break;
 	case RTA_GENMASK:
-		su = &so_genmask;
+		su = &ctx->so_genmask;
 		break;
 	case RTA_IFP:
-		su = &so_ifp;
+		su = &ctx->so_ifp;
 		afamily = AF_LINK;
 		break;
 	case RTA_IFA:
-		su = &so_ifa;
+		su = &ctx->so_ifa;
 		break;
 	default:
 		usage("internal error");
 		/*NOTREACHED*/
 	}
-	su->sa.sa_len = aflen;
+	su->sa.sa_len = ctx->aflen;
 	su->sa.sa_family = afamily; /* cases that don't want it have left already */
 	if (strcmp(s, "default") == 0) {
 		/*
@@ -962,7 +985,7 @@ getaddr(which, s, hpp)
 		 */
 		switch (which) {
 		case RTA_DST:
-			forcenet++;
+			ctx->forcenet++;
 #if 0
 			bzero(su, sizeof(*su));	/* for readability */
 #endif
@@ -1018,8 +1041,8 @@ getaddr(which, s, hpp)
 	case AF_APPLETALK:
 		if (!atalk_aton(s, &su->sat.sat_addr))
 			errx(EX_NOHOST, "bad address: %s", s);
-		rtm_addrs |= RTA_NETMASK;
-		return(forcehost || su->sat.sat_addr.s_node != 0);
+		ctx->rtm_addrs |= RTA_NETMASK;
+		return(ctx->forcehost || su->sat.sat_addr.s_node != 0);
 
 	case AF_LINK:
 		link_addr(s, &su->sdl);
@@ -1045,15 +1068,15 @@ getaddr(which, s, hpp)
 		*q = '\0';
 		if ((val = inet_network(s)) != INADDR_NONE) {
 			inet_makenetandmask(
-				val, &su->sin, strtoul(q+1, 0, 0));
+				ctx, val, &su->sin, strtoul(q+1, 0, 0));
 			return (0);
 		}
 		*q = '/';
 	}
-	if ((which != RTA_DST || forcenet == 0) &&
+	if ((which != RTA_DST || ctx->forcenet == 0) &&
 	    inet_aton(s, &su->sin.sin_addr)) {
 		val = su->sin.sin_addr.s_addr;
-		if (which != RTA_DST || forcehost ||
+		if (which != RTA_DST || ctx->forcehost ||
 		    inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
 			return (1);
 		else {
@@ -1061,11 +1084,11 @@ getaddr(which, s, hpp)
 			goto netdone;
 		}
 	}
-	if (which == RTA_DST && forcehost == 0 &&
+	if (which == RTA_DST && ctx->forcehost == 0 &&
 	    ((val = inet_network(s)) != INADDR_NONE ||
 	    ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0))) {
 netdone:
-		inet_makenetandmask(val, &su->sin, 0);
+		inet_makenetandmask(ctx, val, &su->sin, 0);
 		return (0);
 	}
 	hp = gethostbyname(s);
@@ -1080,24 +1103,25 @@ netdone:
 }
 
 int
-prefixlen(s)
+prefixlen(ctx, s)
+	struct route_context *ctx;
 	char *s;
 {
 	int len = atoi(s), q, r;
 	int max;
 	char *p;
 
-	rtm_addrs |= RTA_NETMASK;	
-	switch (af) {
+	ctx->rtm_addrs |= RTA_NETMASK;	
+	switch (ctx->af) {
 #ifdef INET6
 	case AF_INET6:
 		max = 128;
-		p = (char *)&so_mask.sin6.sin6_addr;
+		p = (char *)&ctx->so_mask.sin6.sin6_addr;
 		break;
 #endif
 	case AF_INET:
 		max = 32;
-		p = (char *)&so_mask.sin.sin_addr;
+		p = (char *)&ctx->so_mask.sin.sin_addr;
 		break;
 	default:
 		(void) fprintf(stderr, "prefixlen not supported in this af\n");
@@ -1112,8 +1136,8 @@ prefixlen(s)
 	
 	q = len >> 3;
 	r = len & 7;
-	so_mask.sa.sa_family = af;
-	so_mask.sa.sa_len = aflen;
+	ctx->so_mask.sa.sa_family = ctx->af;
+	ctx->so_mask.sa.sa_len = ctx->aflen;
 	memset((void *)p, 0, max / 8);
 	if (q > 0)
 		memset((void *)p, 0xff, q);
@@ -1126,7 +1150,7 @@ prefixlen(s)
 }
 
 void
-interfaces()
+interfaces(struct route_context *ctx)
 {
 	size_t needed;
 	int mib[6];
@@ -1156,88 +1180,84 @@ retry2:
 	lim = buf + needed;
 	for (next = buf; next < lim; next += rtm->rtm_msglen) {
 		rtm = (struct rt_msghdr *)next;
-		print_rtmsg(rtm, rtm->rtm_msglen);
+		print_rtmsg(ctx, rtm, rtm->rtm_msglen);
 	}
 }
 
 void
-monitor()
+monitor(struct route_context *ctx)
 {
 	int n;
 	char msg[2048];
 
-	verbose = 1;
-	if (debugonly) {
-		interfaces();
+	ctx->verbose = 1;
+	if (ctx->debugonly) {
+		interfaces(ctx);
 		exit(0);
 	}
 	for(;;) {
 		time_t now;
-		n = read(s, msg, 2048);
+		n = read(ctx->s, msg, 2048);
 		now = time(NULL);
 		(void) printf("\ngot message of size %d on %s", n, ctime(&now));
-		print_rtmsg((struct rt_msghdr *)msg, n);
+		print_rtmsg(ctx, (struct rt_msghdr *)msg, n);
 	}
 }
 
-struct {
-	struct	rt_msghdr m_rtm;
-	char	m_space[512];
-} m_rtmsg;
-
 int
-rtmsg(cmd, flags)
+rtmsg(ctx, cmd, flags)
+	struct route_context *ctx;
 	int cmd, flags;
 {
 	static int seq;
 	int rlen;
-	char *cp = m_rtmsg.m_space;
+	char *cp = ctx->m_rtmsg.m_space;
 	int l;
 
 #define NEXTADDR(w, u) \
-	if (rtm_addrs & (w)) {\
+	if (ctx->rtm_addrs & (w)) {\
 	    l = SA_SIZE(&(u.sa)); memmove(cp, &(u), l); cp += l;\
-	    if (verbose) sodump(&(u),#u);\
+	    if (ctx->verbose) sodump(&(u),#u);\
 	}
 
 	errno = 0;
-	memset(&m_rtmsg, 0, sizeof(m_rtmsg));
+	memset(&ctx->m_rtmsg, 0, sizeof(ctx->m_rtmsg));
 	if (cmd == 'a')
 		cmd = RTM_ADD;
 	else if (cmd == 'c')
 		cmd = RTM_CHANGE;
 	else if (cmd == 'g' || cmd == 's') {
 		cmd = RTM_GET;
-		if (so_ifp.sa.sa_family == 0) {
-			so_ifp.sa.sa_family = AF_LINK;
-			so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
-			rtm_addrs |= RTA_IFP;
+		if (ctx->so_ifp.sa.sa_family == 0) {
+			ctx->so_ifp.sa.sa_family = AF_LINK;
+			ctx->so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
+			ctx->rtm_addrs |= RTA_IFP;
 		}
 	} else
 		cmd = RTM_DELETE;
-#define rtm m_rtmsg.m_rtm
+#define rtm ctx->m_rtmsg.m_rtm
 	rtm.rtm_type = cmd;
 	rtm.rtm_flags = flags;
 	rtm.rtm_version = RTM_VERSION;
 	rtm.rtm_seq = ++seq;
-	rtm.rtm_addrs = rtm_addrs;
-	rtm.rtm_rmx = rt_metrics;
-	rtm.rtm_inits = rtm_inits;
+	rtm.rtm_addrs = ctx->rtm_addrs;
+	rtm.rtm_rmx = ctx->rt_metrics;
+	rtm.rtm_inits = ctx->rtm_inits;
 
-	if (rtm_addrs & RTA_NETMASK)
-		mask_addr();
-	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);
-	rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
-	if (verbose)
-		print_rtmsg(&rtm, l);
-	if (debugonly)
+	if (ctx->rtm_addrs & RTA_NETMASK)
+		mask_addr(ctx);
+	NEXTADDR(RTA_DST, ctx->so_dst);
+	NEXTADDR(RTA_GATEWAY, ctx->so_gate);
+	NEXTADDR(RTA_NETMASK, ctx->so_mask);
+	NEXTADDR(RTA_GENMASK, ctx->so_genmask);
+	NEXTADDR(RTA_IFP, ctx->so_ifp);
+	NEXTADDR(RTA_IFA, ctx->so_ifa);
+	rtm.rtm_msglen = l = cp - (char *)&ctx->m_rtmsg;
+	if (ctx->verbose)
+		print_rtmsg(ctx, &rtm, l);
+	if (ctx->debugonly)
 		return (0);
-	if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
+	if ((rlen = write(ctx->s, (char *)&ctx->m_rtmsg, l)) < 0) {
 		if (errno == EPERM)
 			err(1, "writing to routing socket");
 		warn("writing to routing socket");
@@ -1245,31 +1265,32 @@ rtmsg(cmd, flags)
 	}
 	if (cmd == RTM_GET) {
 		do {
-			l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
-		} while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
+			l = read(ctx->s, (char *)&ctx->m_rtmsg, sizeof(ctx->m_rtmsg));
+		} while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != ctx->pid));
 		if (l < 0)
 			warn("read from routing socket");
 		else
-			print_getmsg(&rtm, l);
+			print_getmsg(ctx, &rtm, l);
 	}
 #undef rtm
 	return (0);
 }
 
 void
-mask_addr()
+mask_addr(ctx)
+	struct route_context *ctx;
 {
-	int olen = so_mask.sa.sa_len;
-	char *cp1 = olen + (char *)&so_mask, *cp2;
+	int olen = ctx->so_mask.sa.sa_len;
+	char *cp1 = olen + (char *)&ctx->so_mask, *cp2;
 
-	for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; )
+	for (ctx->so_mask.sa.sa_len = 0; cp1 > (char *)&ctx->so_mask; )
 		if (*--cp1 != 0) {
-			so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask;
+			ctx->so_mask.sa.sa_len = 1 + cp1 - (char *)&ctx->so_mask;
 			break;
 		}
-	if ((rtm_addrs & RTA_DST) == 0)
+	if ((ctx->rtm_addrs & RTA_DST) == 0)
 		return;
-	switch (so_dst.sa.sa_family) {
+	switch (ctx->so_dst.sa.sa_family) {
 	case AF_INET:
 #ifdef INET6
 	case AF_INET6:
@@ -1278,16 +1299,16 @@ mask_addr()
 	case 0:
 		return;
 	}
-	cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst;
-	cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst;
+	cp1 = ctx->so_mask.sa.sa_len + 1 + (char *)&ctx->so_dst;
+	cp2 = ctx->so_dst.sa.sa_len + 1 + (char *)&ctx->so_dst;
 	while (cp2 > cp1)
 		*--cp2 = 0;
-	cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask;
-	while (cp1 > so_dst.sa.sa_data)
+	cp2 = ctx->so_mask.sa.sa_len + 1 + (char *)&ctx->so_mask;
+	while (cp1 > ctx->so_dst.sa.sa_data)
 		*--cp1 &= *--cp2;
 }
 
-char *msgtypes[] = {
+static const char *msgtypes[] = {
 	"",
 	"RTM_ADD: Add Route",
 	"RTM_DELETE: Delete Route",
@@ -1309,23 +1330,24 @@ char *msgtypes[] = {
 	0,
 };
 
-char metricnames[] =
+static const char metricnames[] =
 "\011weight\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire"
 "\1mtu";
-char routeflags[] =
+static const char routeflags[] =
 "\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE"
 "\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE"
 "\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3"
 "\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY";
-char ifnetflags[] =
+static const char ifnetflags[] =
 "\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP"
 "\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1"
 "\017LINK2\020MULTICAST";
-char addrnames[] =
+static const char addrnames[] =
 "\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
 
 void
-print_rtmsg(rtm, msglen)
+print_rtmsg(ctx, rtm, msglen)
+	struct route_context *ctx;
 	struct rt_msghdr *rtm;
 	int msglen;
 {
@@ -1337,7 +1359,7 @@ print_rtmsg(rtm, msglen)
 	struct if_announcemsghdr *ifan;
 	char *state;
 
-	if (verbose == 0)
+	if (ctx->verbose == 0)
 		return;
 	if (rtm->rtm_version != RTM_VERSION) {
 		(void) printf("routing message version %d not understood\n",
@@ -1408,7 +1430,8 @@ print_rtmsg(rtm, msglen)
 }
 
 void
-print_getmsg(rtm, msglen)
+print_getmsg(ctx, rtm, msglen)
+	struct route_context *ctx;
 	struct rt_msghdr *rtm;
 	int msglen;
 {
@@ -1418,7 +1441,7 @@ print_getmsg(rtm, msglen)
 	char *cp;
 	int i;
 
-	(void) printf("   route to: %s\n", routename(&so_dst));
+	(void) printf("   route to: %s\n", routename(&ctx->so_dst));
 	if (rtm->rtm_version != RTM_VERSION) {
 		warnx("routing message version %d not understood",
 		     rtm->rtm_version);
@@ -1461,11 +1484,11 @@ print_getmsg(rtm, msglen)
 	if (dst)
 		(void)printf("destination: %s\n", routename(dst));
 	if (mask) {
-		int savenflag = nflag;
+		int savenflag = ctx->nflag;
 
-		nflag = 1;
+		ctx->nflag = 1;
 		(void)printf("       mask: %s\n", routename(mask));
-		nflag = savenflag;
+		ctx->nflag = savenflag;
 	}
 	if (gate && rtm->rtm_flags & RTF_GATEWAY)
 		(void)printf("    gateway: %s\n", routename(gate));
@@ -1492,7 +1515,7 @@ print_getmsg(rtm, msglen)
 #undef lock
 #undef msec
 #define	RTA_IGN	(RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD)
-	if (verbose)
+	if (ctx->verbose)
 		pmsg_common(rtm);
 	else if (rtm->rtm_addrs &~ RTA_IGN) {
 		(void) printf("sockaddrs: ");
@@ -1571,7 +1594,7 @@ int
 keyword(cp)
 	char *cp;
 {
-	struct keytab *kt = keywords;
+	const struct keytab *kt = keywords;
 
 	while (kt->kt_cp && strcmp(kt->kt_cp, cp))
 		kt++;
-- 
1.7.7


--------------080606050100070303070204--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?525D5A35.4040005>