From owner-freebsd-hackers@FreeBSD.ORG Tue Oct 15 15:14:04 2013 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 4F9BE146 for ; Tue, 15 Oct 2013 15:14:04 +0000 (UTC) (envelope-from sebastian.huber@embedded-brains.de) Received: from mail.embedded-brains.de (host-82-135-62-35.customer.m-online.net [82.135.62.35]) by mx1.freebsd.org (Postfix) with ESMTP id 313092DC1 for ; Tue, 15 Oct 2013 15:14:02 +0000 (UTC) Received: by mail.embedded-brains.de (Postfix, from userid 65534) id 3C814652CFB; Tue, 15 Oct 2013 17:07:35 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on fidibusdmz X-Spam-Level: X-Spam-Status: No, score=-4.0 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.2.5 Received: from [192.168.96.64] (eb0024.eb.z [192.168.96.64]) by mail.embedded-brains.de (Postfix) with ESMTP id E3FFF65219E for ; Tue, 15 Oct 2013 17:07:33 +0200 (CEST) Message-ID: <525D5A35.4040005@embedded-brains.de> Date: Tue, 15 Oct 2013 17:07:33 +0200 From: Sebastian Huber User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 MIME-Version: 1.0 To: FreeBSD Hackers Subject: Global variables in system programs Content-Type: multipart/mixed; boundary="------------080606050100070303070204" X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Oct 2013 15:14:04 -0000 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 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 #include -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--