# HG changeset patch # User Igor Sysoev # Date 1257255745 0 # Node ID f8ec17eeeaa6986a64fb32ba37e9101dd5811919 # Parent beaf94f2f265a12369c56046fcaa814ca0b9199a ngx_ptocidr() supports IPv6 diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -354,31 +354,47 @@ ngx_inet6_ntop(u_char *p, u_char *text, #endif -/* AF_INET only */ - ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr) { - u_char *addr, *mask, *last; - ngx_int_t shift; + u_char *addr, *mask, *last; + size_t len; + ngx_int_t shift; +#if (NGX_HAVE_INET6) + ngx_int_t rc; + ngx_uint_t s, i; +#endif addr = text->data; last = addr + text->len; mask = ngx_strlchr(addr, last, '/'); + len = (mask ? mask : last) - addr; - cidr->u.in.addr = ngx_inet_addr(addr, (mask ? mask : last) - addr); + cidr->u.in.addr = ngx_inet_addr(addr, len); + + if (cidr->u.in.addr != INADDR_NONE) { + cidr->family = AF_INET; + + if (mask == NULL) { + cidr->u.in.mask = 0xffffffff; + return NGX_OK; + } - if (cidr->u.in.addr == INADDR_NONE) { +#if (NGX_HAVE_INET6) + } else if (ngx_inet6_addr(addr, len, cidr->u.in6.addr.s6_addr) == NGX_OK) { + cidr->family = AF_INET6; + + if (mask == NULL) { + ngx_memset(cidr->u.in6.mask.s6_addr, 0xff, 16); + return NGX_OK; + } + +#endif + } else { return NGX_ERROR; } - if (mask == NULL) { - cidr->family = AF_INET; - cidr->u.in.mask = 0xffffffff; - return NGX_OK; - } - mask++; shift = ngx_atoi(mask, last - mask); @@ -386,30 +402,48 @@ ngx_ptocidr(ngx_str_t *text, ngx_cidr_t return NGX_ERROR; } - cidr->family = AF_INET; + switch (cidr->family) { - if (shift == 0) { +#if (NGX_HAVE_INET6) + case AF_INET6: + addr = cidr->u.in6.addr.s6_addr; + mask = cidr->u.in6.mask.s6_addr; + rc = NGX_OK; + + for (i = 0; i < 16; i++) { + + s = (shift > 8) ? 8 : shift; + shift -= s; + + mask[i] = (u_char) (0 - (1 << (8 - s))); - /* the x86 compilers use the shl instruction that shifts by modulo 32 */ + if (addr[i] != (addr[i] & mask[i])) { + rc = NGX_DONE; + addr[i] &= mask[i]; + } + } + + return rc; +#endif - cidr->u.in.mask = 0; + default: /* AF_INET */ + + if (shift) { + cidr->u.in.mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift)))); - if (cidr->u.in.addr == 0) { + } else { + /* x86 compilers use a shl instruction that shifts by modulo 32 */ + cidr->u.in.mask = 0; + } + + if (cidr->u.in.addr == (cidr->u.in.addr & cidr->u.in.mask)) { return NGX_OK; } + cidr->u.in.addr &= cidr->u.in.mask; + return NGX_DONE; } - - cidr->u.in.mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift)))); - - if (cidr->u.in.addr == (cidr->u.in.addr & cidr->u.in.mask)) { - return NGX_OK; - } - - cidr->u.in.addr &= cidr->u.in.mask; - - return NGX_DONE; } @@ -422,6 +456,12 @@ ngx_parse_addr(ngx_pool_t *pool, ngx_add #if (NGX_HAVE_INET6) struct in6_addr inaddr6; struct sockaddr_in6 *sin6; + + /* + * prevent MSVC8 waring: + * potentially uninitialized local variable 'inaddr6' used + */ + ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr)); #endif inaddr = ngx_inet_addr(text, len);