Peter Selinger
2007-Jan-06 20:35 UTC
[Nut-upsdev] Re: [nut-commits] svn commit r710 - in trunk: . clients server
Great, thanks Arjen! Now we need an autoconf test to set HAVE_IPV6 automatically. I will look into what functionality needs to be tested; the test can be refined as problems arise later. -- Peter Arjen de Korte wrote:> > Author: adkorte-guest > Date: Sat Jan 6 19:39:08 2007 > New Revision: 710 > > Modified: > trunk/ChangeLog > trunk/clients/upsc.c > trunk/clients/upsclient.c > trunk/clients/upsclient.h > trunk/server/access.c > trunk/server/access.h > trunk/server/ctype.h > trunk/server/upsd.c > trunk/server/user.c > trunk/server/user.h > Log: > - #ifdef'ed the new code that (presumably) adds IPv6 support (compile with -DHAVE_IPV6 to enable this), default to the old IPv4 only code (portability concerns of the IPv6 patch) > > > Modified: trunk/ChangeLog > =============================================================================> --- trunk/ChangeLog (original) > +++ trunk/ChangeLog Sat Jan 6 19:39:08 2007 > @@ -1,3 +1,9 @@ > +Sat Jan 6 18:29:36 UTC 2007 / Arjen de Korte <arjen@de-korte.org> > + > + - #ifdef'ed the new code that (presumably) adds IPv6 support (compile > + with -DHAVE_IPV6 to enable this), default to the old IPv4 only > + code (portability concerns of the IPv6 patch) > + > Sat Jan 6 02:35:33 UTC 2007 / Carlos Rodrigues <carlos.efr@mail.telepac.pt> > > - removed the "sms", "ippon", "mustek", "fentonups", "esupssmart" and > > Modified: trunk/clients/upsc.c > =============================================================================> --- trunk/clients/upsc.c (original) > +++ trunk/clients/upsc.c Sat Jan 6 19:39:08 2007 > @@ -25,10 +25,6 @@ > > #include "upsclient.h" > > -/* From IPv6 patch (doesn't seem to be used) > -static int opt_af = AF_UNSPEC; > - */ > - > static void help(const char *prog) > { > printf("Network UPS Tools upsc %s\n\n", UPS_VERSION); > > Modified: trunk/clients/upsclient.c > =============================================================================> --- trunk/clients/upsclient.c (original) > +++ trunk/clients/upsclient.c Sat Jan 6 19:39:08 2007 > @@ -38,9 +38,6 @@ > #define shutdown_how 2 > #endif > > -/* From IPv6 patch (doesn't seem to be used) > -extern int opt_af; > - */ > struct { > int flags; > const char *str; > @@ -424,8 +421,13 @@ > > int upscli_connect(UPSCONN *ups, const char *host, int port, int flags) > { > +#ifndef HAVE_IPV6 > + struct sockaddr_in local, server; > + struct hostent *serv; > +#else > struct addrinfo hints, *r, *rtmp; > char *service; > +#endif > > /* clear out any lingering junk */ > ups->fd = -1; > @@ -452,6 +454,80 @@ > return -1; > } > > +#ifndef HAVE_IPV6 > + if ((serv = gethostbyname(host)) == (struct hostent *) NULL) { > + > + ups->upserror = UPSCLI_ERR_NOSUCHHOST; > + return -1; > + } > + > + if ((ups->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { > + ups->upserror = UPSCLI_ERR_SOCKFAILURE; > + ups->syserrno = errno; > + return -1; > + } > + > + memset(&local, '\0', sizeof(struct sockaddr_in)); > + local.sin_family = AF_INET; > + local.sin_port = htons(INADDR_ANY); > + > + memset(&server, '\0', sizeof(struct sockaddr_in)); > + server.sin_family = AF_INET; > + server.sin_port = htons(port); > + > + memcpy(&server.sin_addr, serv->h_addr, serv->h_length); > + > + if (bind(ups->fd, (struct sockaddr *) &local, > + sizeof(struct sockaddr_in)) == -1) { > + ups->upserror = UPSCLI_ERR_BINDFAILURE; > + ups->syserrno = errno; > + close(ups->fd); > + ups->fd = -1; > + > + return -1; > + } > + > + if (connect(ups->fd, (struct sockaddr *) &server, > + sizeof(struct sockaddr_in)) == -1) { > + ups->upserror = UPSCLI_ERR_CONNFAILURE; > + ups->syserrno = errno; > + close(ups->fd); > + ups->fd = -1; > + > + return -1; > + } > + > + /* don't use xstrdup for cleaner linking (fewer dependencies) */ > + ups->host = strdup(host); > + > + if (!ups->host) { > + close(ups->fd); > + ups->fd = -1; > + > + ups->upserror = UPSCLI_ERR_NOMEM; > + return -1; > + } > + > + ups->port = port; > + > + if (flags & UPSCLI_CONN_TRYSSL) { > + upscli_sslinit(ups); > + > + /* see if something made us die inside sslinit */ > + if (ups->upserror != 0) > + return -1; > + } > + > + if (flags & UPSCLI_CONN_REQSSL) { > + if (upscli_sslinit(ups) != 1) { > + ups->upserror = UPSCLI_ERR_SSLFAIL; > + upscli_closefd(ups); > + return -1; > + } > + } > + > + return 0; > +#else > service = malloc (sizeof (char) * 6); > if (service == NULL) { > ups->upserror = UPSCLI_ERR_NOMEM; > @@ -532,6 +608,7 @@ > freeaddrinfo (rtmp); > > return -1; > +#endif > } > > /* map upsd error strings back to upsclient internal numbers */ > @@ -872,6 +949,34 @@ > > ptr = ap; > > +#ifndef HAVE_IPV6 > + cp = strchr(ptr, ':'); > + > + if (cp) { > + *cp++ = '\0'; > + *hostname = strdup(ptr); > + > + if (!*hostname) { > + fprintf(stderr, "upscli_splitname: strdup failed\n"); > + return -1; > + } > + > + ptr = cp; > + > + *port = strtol(ptr, (char **) NULL, 10); > + > + } else { > + > + *hostname = strdup(ptr); > + > + if (!*hostname) { > + fprintf(stderr, "upscli_splitname: strdup failed\n"); > + return -1; > + } > + > + *port = PORT; > + } > +#else > if (*ptr != '[') { > cp = strchr(ptr, ':'); > if (cp) { > @@ -915,6 +1020,7 @@ > return -1; > } > } > +#endif > > return 0; > } > > Modified: trunk/clients/upsclient.h > =============================================================================> --- trunk/clients/upsclient.h (original) > +++ trunk/clients/upsclient.h Sat Jan 6 19:39:08 2007 > @@ -148,8 +148,11 @@ > > #define UPSCLI_CONN_TRYSSL 0x0001 /* try SSL, OK if not supported */ > #define UPSCLI_CONN_REQSSL 0x0002 /* try SSL, fail if not supported */ > -#define UPSCLI_CONN_INET 0x0004 /* IPv4 only */ > -#define UPSCLI_CONN_INET6 0x0008 /* IPv6 only */ > + > +#ifdef HAVE_IPV6 > +#define UPSCLI_CONN_INET 0x0004 /* IPv4 only */ > +#define UPSCLI_CONN_INET6 0x0008 /* IPv6 only */ > +#endif > > #ifdef __cplusplus > } > > Modified: trunk/server/access.c > =============================================================================> --- trunk/server/access.c (original) > +++ trunk/server/access.c Sat Jan 6 19:39:08 2007 > @@ -25,13 +25,14 @@ > #include "common.h" > #include "access.h" > > -struct acl_t *acl_head = NULL; > -struct access_t *access_head = NULL; > + struct acl_t *acl_head = NULL; > + struct access_t *access_head = NULL; > > +#ifdef HAVE_IPV6 > /* > * Stolen from privoxy code :] > */ > -int mask_cmp (const struct sockaddr_storage* ip_addr, unsigned int prefix, const struct sockaddr_storage* net_addr) { > +static int mask_cmp (const struct sockaddr_storage* ip_addr, unsigned int prefix, const struct sockaddr_storage* net_addr) { > switch (ip_addr->ss_family) { > case AF_INET: > return((((struct sockaddr_in*)ip_addr)->sin_addr.s_addr & htonl(prefix)) == ((struct sockaddr_in*)net_addr)->sin_addr.s_addr); > @@ -72,8 +73,31 @@ > return(0); > } > } > +#endif > > /* see if <addr> matches the acl <aclname> */ > +#ifndef HAVE_IPV6 > +int acl_check(const char *aclname, const struct sockaddr_in *addr) > +{ > + struct acl_t *tmp; > + int aclchk, addrchk; > + > + tmp = acl_head; > + while (tmp != NULL) { > + if (!strcmp(tmp->name, aclname)) { > + aclchk = tmp->addr & tmp->mask; > + addrchk = ntohl(addr->sin_addr.s_addr) & tmp->mask; > + > + if (aclchk == addrchk) > + return 1; /* match */ > + } > + > + tmp = tmp->next; > + } > + > + return 0; /* not found */ > +} > +#else > int acl_check(const char *aclname, const struct sockaddr_storage *addr) > { > struct acl_t *tmp; > @@ -88,9 +112,14 @@ > > return 0; /* not found */ > } > +#endif > > /* return ACCEPT/REJECT based on source address */ > +#ifndef HAVE_IPV6 > +int access_check(const struct sockaddr_in *addr) > +#else > int access_check(const struct sockaddr_storage *addr) > +#endif > { > struct access_t *tmp; > int ret; > @@ -147,6 +176,23 @@ > tmp = tmp->next; > } > > +#ifndef HAVE_IPV6 > + tmp = xmalloc(sizeof(struct acl_t)); > + tmp->name = xstrdup(aclname); > + tmp->addr = ntohl(inet_addr(addr)); > + tmp->next = NULL; > + > + /* must be a /nn CIDR type block */ > + if (strstr(mask, ".") == NULL) { > + if (atoi(mask) != 32) > + tmp->mask = ((unsigned int) ((1 << atoi(mask)) - 1) << > + (32 - atoi(mask))); > + else > + tmp->mask = 0xffffffff; /* avoid overflow from 2^32 */ > + } > + else > + tmp->mask = ntohl(inet_addr(mask)); > +#else > /* memset (&saddr, 0, sizeof (struct sockaddr_storage)); */ > tmp = xmalloc(sizeof(struct acl_t)); > memset (tmp, 0, sizeof (struct acl_t)); > @@ -224,6 +270,7 @@ > /* tmp->addr.ss_len = sizeof (struct sockaddr_in); */ > tmp->addr.ss_family = AF_INET; > } > +#endif > > if (last == NULL) /* first */ > acl_head = tmp; > > Modified: trunk/server/access.h > =============================================================================> --- trunk/server/access.h (original) > +++ trunk/server/access.h Sat Jan 6 19:39:08 2007 > @@ -25,9 +25,15 @@ > > /* ACL structure */ > struct acl_t { > +#ifndef HAVE_IPV6 > + char *name; > + unsigned int addr; > + unsigned int mask; > +#else > char *name; > struct sockaddr_storage addr; > unsigned int mask; /* prefix - if IPv6 */ > +#endif > void *next; > }; > > @@ -38,8 +44,13 @@ > void *next; > }; > > +#ifndef HAVE_IPV6 > +int acl_check(const char *aclname, const struct sockaddr_in *addr); > +int access_check(const struct sockaddr_in *addr); > +#else > int acl_check(const char *aclname, const struct sockaddr_storage *addr); > int access_check(const struct sockaddr_storage *addr); > +#endif > void acl_add(const char *aclname, char *ipblock); > void access_add(int type, int numargs, const char **arg); > void acl_free(void); > > Modified: trunk/server/ctype.h > =============================================================================> --- trunk/server/ctype.h (original) > +++ trunk/server/ctype.h Sat Jan 6 19:39:08 2007 > @@ -32,7 +32,11 @@ > char *addr; > int fd; > int delete; /* set after a write fails */ > +#ifndef HAVE_IPV6 > + struct sockaddr_in sock; > +#else > struct sockaddr_storage sock; > +#endif > char rq[SMALLBUF]; > size_t rqpos; > char *loginups; > > Modified: trunk/server/upsd.c > =============================================================================> --- trunk/server/upsd.c (original) > +++ trunk/server/upsd.c Sat Jan 6 19:39:08 2007 > @@ -61,11 +61,15 @@ > static int listenfd, net_port = PORT; > > /* default is to listen on all local interfaces */ > +#ifndef HAVE_IPV6 > +static struct in_addr listenaddr; > +#else > static char *listenaddr = NULL; > > /* AF_ */ > > static int opt_af = AF_UNSPEC; > +#endif > > /* signal handlers */ > static struct sigaction sa; > @@ -77,6 +81,7 @@ > /* set by signal handlers */ > static int reload_flag = 0, exit_flag = 0; > > +#ifdef HAVE_IPV6 > const char *inet_ntopW (struct sockaddr_storage *s) { > static char str[40]; > > @@ -90,6 +95,7 @@ > return NULL; > } > } > +#endif > > /* return a pointer to the named ups if possible */ > upstype *get_ups_ptr(const char *name) > @@ -150,6 +156,38 @@ > /* create a listening socket for tcp connections */ > static void setuptcp(void) > { > +#ifndef HAVE_IPV6 > + struct sockaddr_in server; > + int res, one = 1; > + > + if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) > + fatal_with_errno("socket"); > + > + res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *) &one, > + sizeof(one)); > + > + if (res != 0) > + fatal_with_errno("setsockopt(SO_REUSEADDR)"); > + > + memset(&server, '\0', sizeof(server)); > + server.sin_addr = listenaddr; > + server.sin_family = AF_INET; > + server.sin_port = htons(net_port); > + > + if (bind(listenfd, (struct sockaddr *) &server, sizeof(server)) == -1) > + fatal_with_errno("Can't bind TCP port number %d", net_port); > + > + if ((res = fcntl(listenfd, F_GETFL, 0)) == -1) > + fatal_with_errno("fcntl(get)"); > + > + if (fcntl(listenfd, F_SETFL, res | O_NDELAY) == -1) > + fatal_with_errno("fcntl(set)"); > + > + if (listen(listenfd, 16)) > + fatal_with_errno("listen"); > + > + return; > +#else > struct addrinfo hints, *r, *rtmp; > char *service; > int res, one = 1; > @@ -206,6 +244,7 @@ > } > freeaddrinfo (rtmp); > return; > +#endif > } > > /* decrement the login counter for this ups */ > @@ -457,7 +496,11 @@ > static void answertcp(void) > { > int acc; > +#ifndef HAVE_IPV6 > + struct sockaddr_in csock; > +#else > struct sockaddr_storage csock; > +#endif > ctype *tmp, *last; > socklen_t clen; > > @@ -469,7 +512,11 @@ > > if (!access_check(&csock)) { > upslogx(LOG_NOTICE, "Rejecting TCP connection from %s", > +#ifndef HAVE_IPV6 > + inet_ntoa(csock.sin_addr)); > +#else > inet_ntopW(&csock)); > +#endif > shutdown(acc, shutdown_how); > close(acc); > return; > @@ -484,10 +531,18 @@ > > tmp = xmalloc(sizeof(ctype)); > > +#ifndef HAVE_IPV6 > + tmp->addr = xstrdup(inet_ntoa(csock.sin_addr)); > +#else > tmp->addr = xstrdup(inet_ntopW(&csock)); > +#endif > tmp->fd = acc; > tmp->delete = 0; > +#ifndef HAVE_IPV6 > + memcpy(&tmp->sock, &csock, sizeof(struct sockaddr_in)); > +#else > memcpy(&tmp->sock, &csock, sizeof(struct sockaddr_storage)); > +#endif > > tmp->rqpos = 0; > memset(tmp->rq, '\0', sizeof(tmp->rq)); > @@ -508,7 +563,11 @@ > else > last->next = tmp; > > +#ifndef HAVE_IPV6 > + upslogx(LOG_INFO, "Connection from %s", inet_ntoa(csock.sin_addr)); > +#else > upslogx(LOG_INFO, "Connection from %s", tmp->addr); > +#endif > } > > /* read tcp messages and handle them */ > @@ -713,8 +772,10 @@ > printf(" -r <dir> chroots to <dir>\n"); > printf(" -u <user> switch to <user> (if started as root)\n"); > printf(" -V display the version of this software\n"); > +#ifdef HAVE_IPV6 > printf(" -4 IPv4 only\n"); > printf(" -6 IPv6 only\n"); > +#endif > > exit(EXIT_SUCCESS); > } > @@ -784,11 +845,19 @@ > datapath = xstrdup(DATADIR); > > /* set up some things for later */ > +#ifndef HAVE_IPV6 > + > + listenaddr.s_addr = INADDR_ANY; > +#endif > snprintf(pidfn, sizeof(pidfn), "%s/upsd.pid", altpidpath()); > > printf("Network UPS Tools upsd %s\n", UPS_VERSION); > > +#ifndef HAVE_IPV6 > + while ((i = getopt(argc, argv, "+hp:r:i:fu:Vc:D")) != EOF) { > +#else > while ((i = getopt(argc, argv, "+h46p:r:i:fu:Vc:D")) != EOF) { > +#endif > switch (i) { > case 'h': > help(progname); > @@ -797,7 +866,12 @@ > net_port = atoi(optarg); > break; > case 'i': > +#ifndef HAVE_IPV6 > + if (!inet_aton(optarg, &listenaddr)) > + fatal_with_errno("Invalid IP address"); > +#else > listenaddr = xstrdup(optarg); > +#endif > break; > case 'r': > chroot_path = optarg; > @@ -829,6 +903,7 @@ > nut_debug_level++; > break; > > +#ifdef HAVE_IPV6 > case '4': > opt_af = AF_INET; > break; > @@ -836,6 +911,7 @@ > case '6': > opt_af = AF_INET6; > break; > +#endif > > default: > help(progname); > > Modified: trunk/server/user.c > =============================================================================> --- trunk/server/user.c (original) > +++ trunk/server/user.c Sat Jan 6 19:39:08 2007 > @@ -290,7 +290,11 @@ > users = NULL; > } > > +#ifndef HAVE_IPV6 > +static int user_matchacl(ulist_t *user, const struct sockaddr_in *addr) > +#else > static int user_matchacl(ulist_t *user, const struct sockaddr_storage *addr) > +#endif > { > acllist *tmp; > > @@ -328,7 +332,11 @@ > return 0; /* fail */ > } > > +#ifndef HAVE_IPV6 > +int user_checkinstcmd(const struct sockaddr_in *addr, > +#else > int user_checkinstcmd(const struct sockaddr_storage *addr, > +#endif > const char *un, const char *pw, const char *cmd) > { > ulist_t *tmp = users; > @@ -385,7 +393,11 @@ > return 0; /* fail */ > } > > +#ifndef HAVE_IPV6 > +int user_checkaction(const struct sockaddr_in *addr, > +#else > int user_checkaction(const struct sockaddr_storage *addr, > +#endif > const char *un, const char *pw, const char *action) > { > ulist_t *tmp = users; > > Modified: trunk/server/user.h > =============================================================================> --- trunk/server/user.h (original) > +++ trunk/server/user.h Sat Jan 6 19:39:08 2007 > @@ -19,10 +19,18 @@ > > void user_load(void); > > +#ifndef HAVE_IPV6 > +int user_checkinstcmd(const struct sockaddr_in *addr, > +#else > int user_checkinstcmd(const struct sockaddr_storage *addr, > +#endif > const char *un, const char *pw, const char *cmd); > > +#ifndef HAVE_IPV6 > +int user_checkaction(const struct sockaddr_in *addr, > +#else > int user_checkaction(const struct sockaddr_storage *addr, > +#endif > const char *un, const char *pw, const char *action); > > void user_flush(void); > > _______________________________________________ > nut-commits mailing list > nut-commits@lists.alioth.debian.org > http://lists.alioth.debian.org/mailman/listinfo/nut-commits >
Arjen de Korte
2007-Jan-06 21:05 UTC
[Nut-upsdev] Re: [nut-commits] svn commit r710 - in trunk: . clients server
Peter Selinger wrote:> Great, thanks Arjen! Now we need an autoconf test to set HAVE_IPV6 > automatically. I will look into what functionality needs to be tested; > the test can be refined as problems arise later. -- PeterThe #ifdef'ing is fairly suboptimal (we could merge a lot more code between the old and new code), but I didn't have enough time to sort that out. Anyway, we can always do that later, for the time being it works. If you can figure out the autoconf stuff (I'm not really familiar with that), that would be great. It seems we already have two reports on what needs to be available. Best regards, Arjen