[Nut-upsdev] Re: [nut-commits] svn commit r708 - in trunk: .
clients server
Peter Selinger
selinger at mathstat.dal.ca
Sat Jan 6 03:49:34 CET 2007
With the Ipv6 patch (r708), I get:
upsclient.c: In function `upscli_connect':
upsclient.c:469: `AI_ADDRCONFIG' undeclared (first use in this function)
upsclient.c:469: (Each undeclared identifier is reported only once
upsclient.c:469: for each function it appears in.)
Even if it doesn't break IPv4 support, it may break portability, as
IPv6 seems to require specific functions that are not as standardized
as the IPv4 ones. For example it uses "struct addrinfo" and not
"struct sockaddr_in". Moreover, it seems that my version of
getaddrinfo() recognizes different flags than this patch assumes.
Ideally the availability of IPv6 functions should be detected at
configuration time. Unfortunately, the patch uses the new interface
even for IPv4 support, so there is no easy way of enclosing the
non-portable stuff in #ifdef's.
Perhaps it would be better to develop this patch in a branch, and
reverse the commit on the main branch until the portability issues are
resolved? The ideal situation would be to enclose all the IPv6 stuff
in #ifdef's, and leave the IPv4 stuff as it was before.
-- Peter
Arjen de Korte wrote:
>
> Author: adkorte-guest
> Date: Fri Jan 5 21:06:59 2007
> New Revision: 708
>
> 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:
> - added IPv6 support (Alioth Patches #304310) (IPv4 still seems to
> work after applying this patch, but can't test IPv6)
>
> Any volunteers for testing IPv6 support?
>
> Modified: trunk/ChangeLog
> ==============================================================================
> --- trunk/ChangeLog (original)
> +++ trunk/ChangeLog Fri Jan 5 21:06:59 2007
> @@ -1,3 +1,8 @@
> +Fri Jan 5 19:57:46 UTC 2007 / Arjen de Korte <arjen at de-korte.org>
> +
> + - added IPv6 support (Alioth Patches #304310) (IPv4 still seems to
> + work after applying this patch, but can't test IPv6)
> +
> Fri Jan 5 19:15:13 UTC 2007 / Arjen de Korte <arjen at de-korte.org>
>
> - data/cmdvartab: added ups.realpower, ups.realpower.nominal,
>
> Modified: trunk/clients/upsc.c
> ==============================================================================
> --- trunk/clients/upsc.c (original)
> +++ trunk/clients/upsc.c Fri Jan 5 21:06:59 2007
> @@ -25,6 +25,10 @@
>
> #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 Fri Jan 5 21:06:59 2007
> @@ -38,6 +38,9 @@
> #define shutdown_how 2
> #endif
>
> +/* From IPv6 patch (doesn't seem to be used)
> +extern int opt_af;
> + */
> struct {
> int flags;
> const char *str;
> @@ -421,8 +424,8 @@
>
> int upscli_connect(UPSCONN *ups, const char *host, int port, int flags)
> {
> - struct sockaddr_in local, server;
> - struct hostent *serv;
> + struct addrinfo hints, *r, *rtmp;
> + char *service;
>
> /* clear out any lingering junk */
> ups->fd = -1;
> @@ -449,78 +452,86 @@
> return -1;
> }
>
> - if ((serv = gethostbyname(host)) == (struct hostent *) NULL) {
> -
> - ups->upserror = UPSCLI_ERR_NOSUCHHOST;
> + service = malloc (sizeof (char) * 6);
> + if (service == NULL) {
> + ups->upserror = UPSCLI_ERR_NOMEM;
> return -1;
> }
>
> - if ((ups->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
> - ups->upserror = UPSCLI_ERR_SOCKFAILURE;
> - ups->syserrno = errno;
> + if (snprintf (service, 6, "%hu", (unsigned short int)port) < 1) {
> 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;
> + memset (&hints, 0, sizeof (struct addrinfo));
> + hints.ai_family = flags & UPSCLI_CONN_INET ? AF_INET : (flags & UPSCLI_CONN_INET6 ? AF_INET6 : AF_UNSPEC);
> + hints.ai_socktype = SOCK_STREAM;
> + hints.ai_protocol = IPPROTO_TCP;
> + hints.ai_flags = AI_ADDRCONFIG;
>
> + if (getaddrinfo (host, service, &hints, &r) != 0) {
> + ups->upserror = UPSCLI_ERR_NOSUCHHOST;
> + free (service);
> return -1;
> }
> + free (service);
>
> - 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;
> + for (rtmp = r; r != NULL; r = r->ai_next) {
> + ups->fd = socket (r->ai_family, r->ai_socktype, r->ai_protocol);
> + if (ups->fd < 0) {
> + if (r->ai_next == NULL) {
> + ups->upserror = UPSCLI_ERR_SOCKFAILURE;
> + ups->syserrno = errno;
> + break;
> + }
> + continue;
> + }
>
> - return -1;
> - }
> + if (connect (ups->fd, r->ai_addr, r->ai_addrlen) == -1) {
> + close (ups->fd);
> + ups->fd = -1;
> + if (r->ai_next == NULL) {
> + ups->upserror = UPSCLI_ERR_CONNFAILURE;
> + ups->syserrno = errno;
> + break;
> + }
> + continue;
> + }
> + freeaddrinfo (rtmp);
>
> - /* don't use xstrdup for cleaner linking (fewer dependencies) */
> - ups->host = strdup(host);
> + /* don't use xstrdup for cleaner linking (fewer dependencies) */
> + ups->host = strdup(host);
>
> - if (!ups->host) {
> - close(ups->fd);
> - ups->fd = -1;
> + if (!ups->host) {
> + close(ups->fd);
> + ups->fd = -1;
>
> - ups->upserror = UPSCLI_ERR_NOMEM;
> - return -1;
> - }
> + ups->upserror = UPSCLI_ERR_NOMEM;
> + return -1;
> + }
>
> - ups->port = port;
> + ups->port = port;
>
> - if (flags & UPSCLI_CONN_TRYSSL) {
> - upscli_sslinit(ups);
> + if (flags & UPSCLI_CONN_TRYSSL) {
> + upscli_sslinit(ups);
>
> - /* see if something made us die inside sslinit */
> - if (ups->upserror != 0)
> - return -1;
> - }
> + /* 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;
> + if (flags & UPSCLI_CONN_REQSSL) {
> + if (upscli_sslinit(ups) != 1) {
> + ups->upserror = UPSCLI_ERR_SSLFAIL;
> + upscli_closefd(ups);
> + return -1;
> + }
> }
> +
> + return 0;
> }
> + freeaddrinfo (rtmp);
>
> - return 0;
> + return -1;
> }
>
> /* map upsd error strings back to upsclient internal numbers */
> @@ -861,31 +872,48 @@
>
> ptr = ap;
>
> - cp = strchr(ptr, ':');
> + if (*ptr != '[') {
> + cp = strchr(ptr, ':');
> + if (cp) {
> + *cp++ = '\0';
> + *hostname = strdup(ptr);
> +
> + if (!*hostname) {
> + fprintf(stderr, "upscli_splitname: strdup failed\n");
> + return -1;
> + }
>
> - if (cp) {
> - *cp++ = '\0';
> - *hostname = strdup(ptr);
> + ptr = cp;
> +
> + *port = strtol(ptr, (char **) NULL, 10);
>
> - if (!*hostname) {
> - fprintf(stderr, "upscli_splitname: strdup failed\n");
> - return -1;
> - }
> + } else {
>
> - ptr = cp;
> + *hostname = strdup(ptr);
>
> - *port = strtol(ptr, (char **) NULL, 10);
> + if (!*hostname) {
> + fprintf(stderr, "upscli_splitname: strdup failed\n");
> + return -1;
> + }
>
> + *port = PORT;
> + }
> } else {
> -
> - *hostname = strdup(ptr);
> -
> - if (!*hostname) {
> - fprintf(stderr, "upscli_splitname: strdup failed\n");
> + ptr++;
> + cp = strchr(ptr, ']');
> + if (cp) {
> + *cp = '\0';
> + *hostname = strdup (ptr);
> + ptr = ++cp;
> + cp = strchr (ptr, ':');
> + if (cp != NULL)
> + *port = strtol (++cp, (char **)NULL, 10);
> + else
> + *port = PORT;
> + } else {
> + fprintf (stderr, "upscli_splitname: strchr(']') failed\n");
> return -1;
> }
> -
> - *port = PORT;
> }
>
> return 0;
>
> Modified: trunk/clients/upsclient.h
> ==============================================================================
> --- trunk/clients/upsclient.h (original)
> +++ trunk/clients/upsclient.h Fri Jan 5 21:06:59 2007
> @@ -148,6 +148,8 @@
>
> #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 __cplusplus
> }
>
> Modified: trunk/server/access.c
> ==============================================================================
> --- trunk/server/access.c (original)
> +++ trunk/server/access.c Fri Jan 5 21:06:59 2007
> @@ -25,33 +25,72 @@
> #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;
> +
> +/*
> + * Stolen from privoxy code :]
> + */
> +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);
> + break;
> + case AF_INET6:
> + if (AF_INET6 == net_addr->ss_family) {
> + struct in6_addr ip, net;
> + register unsigned char i;
> +
> + memcpy (&ip, &((struct sockaddr_in6 *)ip_addr)->sin6_addr, sizeof (struct in6_addr));
> + memcpy (&net, &((struct sockaddr_in6 *)net_addr)->sin6_addr, sizeof (struct in6_addr));
> +
> + i = prefix/8;
> + if (prefix%8)
> + ip.s6_addr[i++] &= 0xff<<(8-(prefix%8));
> + for (; i < sizeof ip.s6_addr; i++)
> + ip.s6_addr[i] = 0;
> +
> + return (memcmp (ip.s6_addr, net.s6_addr, sizeof ip.s6_addr)==0);
> + }
> + else if (AF_INET == net_addr->ss_family) { /* IPv4 mapped IPv6 */
> + struct in6_addr *ip6 = &((struct sockaddr_in6 *)ip_addr)->sin6_addr;
> + struct in_addr *net = &((struct sockaddr_in *)net_addr)->sin_addr;
> +
> + if ((ip6->s6_addr32[3] & (u_int32_t)prefix) == net->s_addr &&
> +#if BYTE_ORDER == LITTLE_ENDIAN
> + (ip6->s6_addr32[2] == (u_int32_t)0xffff0000) &&
> +#else
> + (ip6->s6_addr32[2] == (u_int32_t)0x0000ffff) &&
> +#endif
> + (ip6->s6_addr32[1] == 0) && (ip6->s6_addr32[0] == 0))
> + return(1);
> + else
> + return(0);
> + }
> + default:
> + fatal_with_errno("mask_cmp: Unknown address family");
> + return(0);
> + }
> +}
>
> /* see if <addr> matches the acl <aclname> */
> -int acl_check(const char *aclname, const struct sockaddr_in *addr)
> +int acl_check(const char *aclname, const struct sockaddr_storage *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 */
> - }
> -
> + if (!strcmp(tmp->name, aclname))
> + if (mask_cmp (addr, tmp->mask, &tmp->addr))
> + return 1;
> tmp = tmp->next;
> }
> -
> +
> return 0; /* not found */
> }
>
> /* return ACCEPT/REJECT based on source address */
> -int access_check(const struct sockaddr_in *addr)
> +int access_check(const struct sockaddr_storage *addr)
> {
> struct access_t *tmp;
> int ret;
> @@ -108,21 +147,83 @@
> tmp = tmp->next;
> }
>
> + /* memset (&saddr, 0, sizeof (struct sockaddr_storage)); */
> tmp = xmalloc(sizeof(struct acl_t));
> + memset (tmp, 0, 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 */
> + if (*addr == '[') {
> + struct sockaddr_in6 s6;
> + char *stmp;
> +
> + stmp = strchr (addr, ']');
> + if (stmp == NULL) {
> + free (tmp);
> + fatal_with_errno("Expecting \']\' in \"%s\"", addr);
> + }
> +
> + *stmp = '\0';
> + addr++;
> +
> + memset (&s6, 0, sizeof (struct sockaddr_in6));
> + s6.sin6_family = AF_INET6;
> +
> + if (inet_pton (AF_INET6, addr, &s6.sin6_addr) < 1) {
> + free (tmp);
> + fatal_with_errno("Invalid IPv6 address: \"%s\"", addr);
> + }
> +
> + /* prefix */
> + tmp->mask = strtol (mask, NULL, 10);
> +
> + if (tmp->mask < 0 || tmp->mask > 128) {
> + free (tmp);
> + fatal_with_errno("Invalid IPv6 prefix");
> + }
> +
> + { register unsigned char i;
> + i = (tmp->mask)/8;
> + if ((tmp->mask)%8)
> + s6.sin6_addr.s6_addr[i++] &= 0xff<<(8-((tmp->mask)%8));
> + for (; i < sizeof s6.sin6_addr.s6_addr; i++)
> + s6.sin6_addr.s6_addr[i] = 0;
> + }
> +
> + memcpy (&(tmp->addr), &s6, sizeof (struct sockaddr_in6));
> + /* tmp->addr.ss_len = sizeof (struct sockaddr_in6); */
> + tmp->addr.ss_family = AF_INET6;
> + } else {
> + struct sockaddr_in s4;
> +
> + /* mask */
> + if (inet_pton (AF_INET, mask, &s4.sin_addr) < 1) {
> + /* must be a /nn CIDR type block */
> + tmp->mask = strtol (mask, NULL, 10);
> +
> + if (tmp->mask < 0 || tmp->mask > 32) {
> + free (tmp);
> + fatal_with_errno("Invalid CIDR type block: Must be > 0 && < 32");
> + }
> + tmp->mask = 0xffffffff << (32 - tmp->mask);
> + } else {
> + tmp->mask = ntohl (s4.sin_addr.s_addr);
> + }
> +
> + memset (&s4, 0, sizeof (struct sockaddr_in));
> + s4.sin_family = AF_INET;
> +
> + if (inet_pton (AF_INET, addr, &s4.sin_addr) < 1) {
> + free (tmp);
> + fatal_with_errno("Invalid IPv4 address: \"%s\"", addr);
> + }
> +
> + s4.sin_addr.s_addr &= htonl (tmp->mask);
> +
> + memcpy (&(tmp->addr), &s4, sizeof (struct sockaddr_in));
> + /* tmp->addr.ss_len = sizeof (struct sockaddr_in); */
> + tmp->addr.ss_family = AF_INET;
> }
> - else
> - tmp->mask = ntohl(inet_addr(mask));
>
> if (last == NULL) /* first */
> acl_head = tmp;
>
> Modified: trunk/server/access.h
> ==============================================================================
> --- trunk/server/access.h (original)
> +++ trunk/server/access.h Fri Jan 5 21:06:59 2007
> @@ -26,8 +26,8 @@
> /* ACL structure */
> struct acl_t {
> char *name;
> - unsigned int addr;
> - unsigned int mask;
> + struct sockaddr_storage addr;
> + unsigned int mask; /* prefix - if IPv6 */
> void *next;
> };
>
> @@ -38,8 +38,8 @@
> void *next;
> };
>
> -int acl_check(const char *aclname, const struct sockaddr_in *addr);
> -int access_check(const struct sockaddr_in *addr);
> +int acl_check(const char *aclname, const struct sockaddr_storage *addr);
> +int access_check(const struct sockaddr_storage *addr);
> 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 Fri Jan 5 21:06:59 2007
> @@ -32,7 +32,7 @@
> char *addr;
> int fd;
> int delete; /* set after a write fails */
> - struct sockaddr_in sock;
> + struct sockaddr_storage sock;
> char rq[SMALLBUF];
> size_t rqpos;
> char *loginups;
>
> Modified: trunk/server/upsd.c
> ==============================================================================
> --- trunk/server/upsd.c (original)
> +++ trunk/server/upsd.c Fri Jan 5 21:06:59 2007
> @@ -26,6 +26,7 @@
>
> #include <sys/un.h>
> #include <sys/socket.h>
> +#include <netdb.h>
>
> #ifdef HAVE_SSL
> #include <openssl/err.h>
> @@ -60,7 +61,11 @@
> static int listenfd, net_port = PORT;
>
> /* default is to listen on all local interfaces */
> -static struct in_addr listenaddr;
> +static char *listenaddr = NULL;
> +
> +/* AF_ */
> +
> +static int opt_af = AF_UNSPEC;
>
> /* signal handlers */
> static struct sigaction sa;
> @@ -72,6 +77,20 @@
> /* set by signal handlers */
> static int reload_flag = 0, exit_flag = 0;
>
> +const char *inet_ntopW (struct sockaddr_storage *s) {
> + static char str[40];
> +
> + switch (s->ss_family) {
> + case AF_INET:
> + return inet_ntop (AF_INET, &(((struct sockaddr_in *)s)->sin_addr), str, 16);
> + case AF_INET6:
> + return inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)s)->sin6_addr), str, 40);
> + default:
> + errno = EAFNOSUPPORT;
> + return NULL;
> + }
> +}
> +
> /* return a pointer to the named ups if possible */
> upstype *get_ups_ptr(const char *name)
> {
> @@ -131,35 +150,61 @@
> /* create a listening socket for tcp connections */
> static void setuptcp(void)
> {
> - struct sockaddr_in server;
> + struct addrinfo hints, *r, *rtmp;
> + char *service;
> 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);
> + memset (&hints, 0, sizeof (struct addrinfo));
> + hints.ai_family = opt_af;
> + hints.ai_flags = AI_PASSIVE;
> + hints.ai_protocol = IPPROTO_TCP;
> + hints.ai_socktype = SOCK_STREAM;
> +
> + service = xmalloc (sizeof (char) * 6);
> +
> + if (snprintf (service, 6, "%hu", (unsigned short int)net_port) < 1)
> + fatal_with_errno("snprintf");
> +
> + if (getaddrinfo (listenaddr, service, &hints, &r) != 0) {
> + free (service);
> + fatal_with_errno("getaddrinfo");
> + }
> + free (service);
> +
> + for (rtmp = r; r != NULL; r = r->ai_next) {
> + listenfd = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
> + if (listenfd < 0) {
> + if (r->ai_next == NULL)
> + fatal_with_errno("socket");
> + continue;
> + }
>
> - if ((res = fcntl(listenfd, F_GETFL, 0)) == -1)
> - fatal_with_errno("fcntl(get)");
> + res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one));
> + if (res != 0)
> + fatal_with_errno("setsockopt(SO_REUSEADDR)");
> +
> + if (bind (listenfd, r->ai_addr, r->ai_addrlen) == -1) {
> + if (r->ai_next == NULL)
> + fatal_with_errno("Can't bind TCP port number %u", net_port);
> + close (listenfd);
> + continue;
> + }
>
> - if (fcntl(listenfd, F_SETFL, res | O_NDELAY) == -1)
> - fatal_with_errno("fcntl(set)");
> + if ((res = fcntl(listenfd, F_GETFL, 0)) == -1)
> + fatal_with_errno("fcntl(get)");
>
> - if (listen(listenfd, 16))
> - fatal_with_errno("listen");
> + if (fcntl(listenfd, F_SETFL, res | O_NDELAY) == -1)
> + fatal_with_errno("fcntl(set)");
>
> + if (listen(listenfd, 16) == -1) {
> + if (r->ai_next == NULL)
> + fatal_with_errno("listen");
> + close (listenfd);
> + continue;
> + }
> + break;
> + }
> + freeaddrinfo (rtmp);
> return;
> }
>
> @@ -412,7 +457,7 @@
> static void answertcp(void)
> {
> int acc;
> - struct sockaddr_in csock;
> + struct sockaddr_storage csock;
> ctype *tmp, *last;
> socklen_t clen;
>
> @@ -424,7 +469,7 @@
>
> if (!access_check(&csock)) {
> upslogx(LOG_NOTICE, "Rejecting TCP connection from %s",
> - inet_ntoa(csock.sin_addr));
> + inet_ntopW(&csock));
> shutdown(acc, shutdown_how);
> close(acc);
> return;
> @@ -439,10 +484,10 @@
>
> tmp = xmalloc(sizeof(ctype));
>
> - tmp->addr = xstrdup(inet_ntoa(csock.sin_addr));
> + tmp->addr = xstrdup(inet_ntopW(&csock));
> tmp->fd = acc;
> tmp->delete = 0;
> - memcpy(&tmp->sock, &csock, sizeof(struct sockaddr_in));
> + memcpy(&tmp->sock, &csock, sizeof(struct sockaddr_storage));
>
> tmp->rqpos = 0;
> memset(tmp->rq, '\0', sizeof(tmp->rq));
> @@ -463,7 +508,7 @@
> else
> last->next = tmp;
>
> - upslogx(LOG_INFO, "Connection from %s", inet_ntoa(csock.sin_addr));
> + upslogx(LOG_INFO, "Connection from %s", tmp->addr);
> }
>
> /* read tcp messages and handle them */
> @@ -668,6 +713,8 @@
> 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");
> + printf(" -4 IPv4 only\n");
> + printf(" -6 IPv6 only\n");
>
> exit(EXIT_SUCCESS);
> }
> @@ -737,13 +784,11 @@
> datapath = xstrdup(DATADIR);
>
> /* set up some things for later */
> -
> - listenaddr.s_addr = INADDR_ANY;
> snprintf(pidfn, sizeof(pidfn), "%s/upsd.pid", altpidpath());
>
> printf("Network UPS Tools upsd %s\n", UPS_VERSION);
>
> - while ((i = getopt(argc, argv, "+hp:r:i:fu:Vc:D")) != EOF) {
> + while ((i = getopt(argc, argv, "+h46p:r:i:fu:Vc:D")) != EOF) {
> switch (i) {
> case 'h':
> help(progname);
> @@ -752,8 +797,7 @@
> net_port = atoi(optarg);
> break;
> case 'i':
> - if (!inet_aton(optarg, &listenaddr))
> - fatal_with_errno("Invalid IP address");
> + listenaddr = xstrdup(optarg);
> break;
> case 'r':
> chroot_path = optarg;
> @@ -784,6 +828,15 @@
> do_background = 0;
> nut_debug_level++;
> break;
> +
> + case '4':
> + opt_af = AF_INET;
> + break;
> +
> + case '6':
> + opt_af = AF_INET6;
> + break;
> +
> default:
> help(progname);
> break;
>
> Modified: trunk/server/user.c
> ==============================================================================
> --- trunk/server/user.c (original)
> +++ trunk/server/user.c Fri Jan 5 21:06:59 2007
> @@ -290,7 +290,7 @@
> users = NULL;
> }
>
> -static int user_matchacl(ulist_t *user, const struct sockaddr_in *addr)
> +static int user_matchacl(ulist_t *user, const struct sockaddr_storage *addr)
> {
> acllist *tmp;
>
> @@ -328,7 +328,7 @@
> return 0; /* fail */
> }
>
> -int user_checkinstcmd(const struct sockaddr_in *addr,
> +int user_checkinstcmd(const struct sockaddr_storage *addr,
> const char *un, const char *pw, const char *cmd)
> {
> ulist_t *tmp = users;
> @@ -385,7 +385,7 @@
> return 0; /* fail */
> }
>
> -int user_checkaction(const struct sockaddr_in *addr,
> +int user_checkaction(const struct sockaddr_storage *addr,
> 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 Fri Jan 5 21:06:59 2007
> @@ -19,10 +19,10 @@
>
> void user_load(void);
>
> -int user_checkinstcmd(const struct sockaddr_in *addr,
> +int user_checkinstcmd(const struct sockaddr_storage *addr,
> const char *un, const char *pw, const char *cmd);
>
> -int user_checkaction(const struct sockaddr_in *addr,
> +int user_checkaction(const struct sockaddr_storage *addr,
> const char *un, const char *pw, const char *action);
>
> void user_flush(void);
>
> _______________________________________________
> nut-commits mailing list
> nut-commits at lists.alioth.debian.org
> http://lists.alioth.debian.org/mailman/listinfo/nut-commits
>
More information about the Nut-upsdev
mailing list