1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#include <ngx_config.h>
9e18a033bSKonstantin Ananyev#include <ngx_core.h>
10e18a033bSKonstantin Ananyev
11e18a033bSKonstantin Ananyev
12e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u);
13e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u);
14e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u);
15e18a033bSKonstantin Ananyev
16e18a033bSKonstantin Ananyev
17e18a033bSKonstantin Ananyevin_addr_t
18e18a033bSKonstantin Ananyevngx_inet_addr(u_char *text, size_t len)
19e18a033bSKonstantin Ananyev{
20e18a033bSKonstantin Ananyev    u_char      *p, c;
21e18a033bSKonstantin Ananyev    in_addr_t    addr;
22e18a033bSKonstantin Ananyev    ngx_uint_t   octet, n;
23e18a033bSKonstantin Ananyev
24e18a033bSKonstantin Ananyev    addr = 0;
25e18a033bSKonstantin Ananyev    octet = 0;
26e18a033bSKonstantin Ananyev    n = 0;
27e18a033bSKonstantin Ananyev
28e18a033bSKonstantin Ananyev    for (p = text; p < text + len; p++) {
29e18a033bSKonstantin Ananyev        c = *p;
30e18a033bSKonstantin Ananyev
31e18a033bSKonstantin Ananyev        if (c >= '0' && c <= '9') {
32e18a033bSKonstantin Ananyev            octet = octet * 10 + (c - '0');
33e18a033bSKonstantin Ananyev
34e18a033bSKonstantin Ananyev            if (octet > 255) {
35e18a033bSKonstantin Ananyev                return INADDR_NONE;
36e18a033bSKonstantin Ananyev            }
37e18a033bSKonstantin Ananyev
38e18a033bSKonstantin Ananyev            continue;
39e18a033bSKonstantin Ananyev        }
40e18a033bSKonstantin Ananyev
41e18a033bSKonstantin Ananyev        if (c == '.') {
42e18a033bSKonstantin Ananyev            addr = (addr << 8) + octet;
43e18a033bSKonstantin Ananyev            octet = 0;
44e18a033bSKonstantin Ananyev            n++;
45e18a033bSKonstantin Ananyev            continue;
46e18a033bSKonstantin Ananyev        }
47e18a033bSKonstantin Ananyev
48e18a033bSKonstantin Ananyev        return INADDR_NONE;
49e18a033bSKonstantin Ananyev    }
50e18a033bSKonstantin Ananyev
51e18a033bSKonstantin Ananyev    if (n == 3) {
52e18a033bSKonstantin Ananyev        addr = (addr << 8) + octet;
53e18a033bSKonstantin Ananyev        return htonl(addr);
54e18a033bSKonstantin Ananyev    }
55e18a033bSKonstantin Ananyev
56e18a033bSKonstantin Ananyev    return INADDR_NONE;
57e18a033bSKonstantin Ananyev}
58e18a033bSKonstantin Ananyev
59e18a033bSKonstantin Ananyev
60e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6)
61e18a033bSKonstantin Ananyev
62e18a033bSKonstantin Ananyevngx_int_t
63e18a033bSKonstantin Ananyevngx_inet6_addr(u_char *p, size_t len, u_char *addr)
64e18a033bSKonstantin Ananyev{
65e18a033bSKonstantin Ananyev    u_char      c, *zero, *digit, *s, *d;
66e18a033bSKonstantin Ananyev    size_t      len4;
67e18a033bSKonstantin Ananyev    ngx_uint_t  n, nibbles, word;
68e18a033bSKonstantin Ananyev
69e18a033bSKonstantin Ananyev    if (len == 0) {
70e18a033bSKonstantin Ananyev        return NGX_ERROR;
71e18a033bSKonstantin Ananyev    }
72e18a033bSKonstantin Ananyev
73e18a033bSKonstantin Ananyev    zero = NULL;
74e18a033bSKonstantin Ananyev    digit = NULL;
75e18a033bSKonstantin Ananyev    len4 = 0;
76e18a033bSKonstantin Ananyev    nibbles = 0;
77e18a033bSKonstantin Ananyev    word = 0;
78e18a033bSKonstantin Ananyev    n = 8;
79e18a033bSKonstantin Ananyev
80e18a033bSKonstantin Ananyev    if (p[0] == ':') {
81e18a033bSKonstantin Ananyev        p++;
82e18a033bSKonstantin Ananyev        len--;
83e18a033bSKonstantin Ananyev    }
84e18a033bSKonstantin Ananyev
85e18a033bSKonstantin Ananyev    for (/* void */; len; len--) {
86e18a033bSKonstantin Ananyev        c = *p++;
87e18a033bSKonstantin Ananyev
88e18a033bSKonstantin Ananyev        if (c == ':') {
89e18a033bSKonstantin Ananyev            if (nibbles) {
90e18a033bSKonstantin Ananyev                digit = p;
91e18a033bSKonstantin Ananyev                len4 = len;
92e18a033bSKonstantin Ananyev                *addr++ = (u_char) (word >> 8);
93e18a033bSKonstantin Ananyev                *addr++ = (u_char) (word & 0xff);
94e18a033bSKonstantin Ananyev
95e18a033bSKonstantin Ananyev                if (--n) {
96e18a033bSKonstantin Ananyev                    nibbles = 0;
97e18a033bSKonstantin Ananyev                    word = 0;
98e18a033bSKonstantin Ananyev                    continue;
99e18a033bSKonstantin Ananyev                }
100e18a033bSKonstantin Ananyev
101e18a033bSKonstantin Ananyev            } else {
102e18a033bSKonstantin Ananyev                if (zero == NULL) {
103e18a033bSKonstantin Ananyev                    digit = p;
104e18a033bSKonstantin Ananyev                    len4 = len;
105e18a033bSKonstantin Ananyev                    zero = addr;
106e18a033bSKonstantin Ananyev                    continue;
107e18a033bSKonstantin Ananyev                }
108e18a033bSKonstantin Ananyev            }
109e18a033bSKonstantin Ananyev
110e18a033bSKonstantin Ananyev            return NGX_ERROR;
111e18a033bSKonstantin Ananyev        }
112e18a033bSKonstantin Ananyev
113e18a033bSKonstantin Ananyev        if (c == '.' && nibbles) {
114e18a033bSKonstantin Ananyev            if (n < 2 || digit == NULL) {
115e18a033bSKonstantin Ananyev                return NGX_ERROR;
116e18a033bSKonstantin Ananyev            }
117e18a033bSKonstantin Ananyev
118e18a033bSKonstantin Ananyev            word = ngx_inet_addr(digit, len4 - 1);
119e18a033bSKonstantin Ananyev            if (word == INADDR_NONE) {
120e18a033bSKonstantin Ananyev                return NGX_ERROR;
121e18a033bSKonstantin Ananyev            }
122e18a033bSKonstantin Ananyev
123e18a033bSKonstantin Ananyev            word = ntohl(word);
124e18a033bSKonstantin Ananyev            *addr++ = (u_char) ((word >> 24) & 0xff);
125e18a033bSKonstantin Ananyev            *addr++ = (u_char) ((word >> 16) & 0xff);
126e18a033bSKonstantin Ananyev            n--;
127e18a033bSKonstantin Ananyev            break;
128e18a033bSKonstantin Ananyev        }
129e18a033bSKonstantin Ananyev
130e18a033bSKonstantin Ananyev        if (++nibbles > 4) {
131e18a033bSKonstantin Ananyev            return NGX_ERROR;
132e18a033bSKonstantin Ananyev        }
133e18a033bSKonstantin Ananyev
134e18a033bSKonstantin Ananyev        if (c >= '0' && c <= '9') {
135e18a033bSKonstantin Ananyev            word = word * 16 + (c - '0');
136e18a033bSKonstantin Ananyev            continue;
137e18a033bSKonstantin Ananyev        }
138e18a033bSKonstantin Ananyev
139e18a033bSKonstantin Ananyev        c |= 0x20;
140e18a033bSKonstantin Ananyev
141e18a033bSKonstantin Ananyev        if (c >= 'a' && c <= 'f') {
142e18a033bSKonstantin Ananyev            word = word * 16 + (c - 'a') + 10;
143e18a033bSKonstantin Ananyev            continue;
144e18a033bSKonstantin Ananyev        }
145e18a033bSKonstantin Ananyev
146e18a033bSKonstantin Ananyev        return NGX_ERROR;
147e18a033bSKonstantin Ananyev    }
148e18a033bSKonstantin Ananyev
149e18a033bSKonstantin Ananyev    if (nibbles == 0 && zero == NULL) {
150e18a033bSKonstantin Ananyev        return NGX_ERROR;
151e18a033bSKonstantin Ananyev    }
152e18a033bSKonstantin Ananyev
153e18a033bSKonstantin Ananyev    *addr++ = (u_char) (word >> 8);
154e18a033bSKonstantin Ananyev    *addr++ = (u_char) (word & 0xff);
155e18a033bSKonstantin Ananyev
156e18a033bSKonstantin Ananyev    if (--n) {
157e18a033bSKonstantin Ananyev        if (zero) {
158e18a033bSKonstantin Ananyev            n *= 2;
159e18a033bSKonstantin Ananyev            s = addr - 1;
160e18a033bSKonstantin Ananyev            d = s + n;
161e18a033bSKonstantin Ananyev            while (s >= zero) {
162e18a033bSKonstantin Ananyev                *d-- = *s--;
163e18a033bSKonstantin Ananyev            }
164e18a033bSKonstantin Ananyev            ngx_memzero(zero, n);
165e18a033bSKonstantin Ananyev            return NGX_OK;
166e18a033bSKonstantin Ananyev        }
167e18a033bSKonstantin Ananyev
168e18a033bSKonstantin Ananyev    } else {
169e18a033bSKonstantin Ananyev        if (zero == NULL) {
170e18a033bSKonstantin Ananyev            return NGX_OK;
171e18a033bSKonstantin Ananyev        }
172e18a033bSKonstantin Ananyev    }
173e18a033bSKonstantin Ananyev
174e18a033bSKonstantin Ananyev    return NGX_ERROR;
175e18a033bSKonstantin Ananyev}
176e18a033bSKonstantin Ananyev
177e18a033bSKonstantin Ananyev#endif
178e18a033bSKonstantin Ananyev
179e18a033bSKonstantin Ananyev
180e18a033bSKonstantin Ananyevsize_t
181e18a033bSKonstantin Ananyevngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text, size_t len,
182e18a033bSKonstantin Ananyev    ngx_uint_t port)
183e18a033bSKonstantin Ananyev{
184e18a033bSKonstantin Ananyev    u_char               *p;
185e18a033bSKonstantin Ananyev    struct sockaddr_in   *sin;
186e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6)
187e18a033bSKonstantin Ananyev    size_t                n;
188e18a033bSKonstantin Ananyev    struct sockaddr_in6  *sin6;
189e18a033bSKonstantin Ananyev#endif
190e18a033bSKonstantin Ananyev#if (NGX_HAVE_UNIX_DOMAIN)
191e18a033bSKonstantin Ananyev    struct sockaddr_un   *saun;
192e18a033bSKonstantin Ananyev#endif
193e18a033bSKonstantin Ananyev
194e18a033bSKonstantin Ananyev    switch (sa->sa_family) {
195e18a033bSKonstantin Ananyev
196e18a033bSKonstantin Ananyev    case AF_INET:
197e18a033bSKonstantin Ananyev
198e18a033bSKonstantin Ananyev        sin = (struct sockaddr_in *) sa;
199e18a033bSKonstantin Ananyev        p = (u_char *) &sin->sin_addr;
200e18a033bSKonstantin Ananyev
201e18a033bSKonstantin Ananyev        if (port) {
202e18a033bSKonstantin Ananyev            p = ngx_snprintf(text, len, "%ud.%ud.%ud.%ud:%d",
203e18a033bSKonstantin Ananyev                             p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
204e18a033bSKonstantin Ananyev        } else {
205e18a033bSKonstantin Ananyev            p = ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
206e18a033bSKonstantin Ananyev                             p[0], p[1], p[2], p[3]);
207e18a033bSKonstantin Ananyev        }
208e18a033bSKonstantin Ananyev
209e18a033bSKonstantin Ananyev        return (p - text);
210e18a033bSKonstantin Ananyev
211e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6)
212e18a033bSKonstantin Ananyev
213e18a033bSKonstantin Ananyev    case AF_INET6:
214e18a033bSKonstantin Ananyev
215e18a033bSKonstantin Ananyev        sin6 = (struct sockaddr_in6 *) sa;
216e18a033bSKonstantin Ananyev
217e18a033bSKonstantin Ananyev        n = 0;
218e18a033bSKonstantin Ananyev
219e18a033bSKonstantin Ananyev        if (port) {
220e18a033bSKonstantin Ananyev            text[n++] = '[';
221e18a033bSKonstantin Ananyev        }
222e18a033bSKonstantin Ananyev
223e18a033bSKonstantin Ananyev        n = ngx_inet6_ntop(sin6->sin6_addr.s6_addr, &text[n], len);
224e18a033bSKonstantin Ananyev
225e18a033bSKonstantin Ananyev        if (port) {
226e18a033bSKonstantin Ananyev            n = ngx_sprintf(&text[1 + n], "]:%d",
227e18a033bSKonstantin Ananyev                            ntohs(sin6->sin6_port)) - text;
228e18a033bSKonstantin Ananyev        }
229e18a033bSKonstantin Ananyev
230e18a033bSKonstantin Ananyev        return n;
231e18a033bSKonstantin Ananyev#endif
232e18a033bSKonstantin Ananyev
233e18a033bSKonstantin Ananyev#if (NGX_HAVE_UNIX_DOMAIN)
234e18a033bSKonstantin Ananyev
235e18a033bSKonstantin Ananyev    case AF_UNIX:
236e18a033bSKonstantin Ananyev        saun = (struct sockaddr_un *) sa;
237e18a033bSKonstantin Ananyev
238e18a033bSKonstantin Ananyev        /* on Linux sockaddr might not include sun_path at all */
239e18a033bSKonstantin Ananyev
240e18a033bSKonstantin Ananyev        if (socklen <= (socklen_t) offsetof(struct sockaddr_un, sun_path)) {
241e18a033bSKonstantin Ananyev            p = ngx_snprintf(text, len, "unix:%Z");
242e18a033bSKonstantin Ananyev
243e18a033bSKonstantin Ananyev        } else {
244e18a033bSKonstantin Ananyev            p = ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path);
245e18a033bSKonstantin Ananyev        }
246e18a033bSKonstantin Ananyev
247e18a033bSKonstantin Ananyev        /* we do not include trailing zero in address length */
248e18a033bSKonstantin Ananyev
249e18a033bSKonstantin Ananyev        return (p - text - 1);
250e18a033bSKonstantin Ananyev
251e18a033bSKonstantin Ananyev#endif
252e18a033bSKonstantin Ananyev
253e18a033bSKonstantin Ananyev    default:
254e18a033bSKonstantin Ananyev        return 0;
255e18a033bSKonstantin Ananyev    }
256e18a033bSKonstantin Ananyev}
257e18a033bSKonstantin Ananyev
258e18a033bSKonstantin Ananyev
259e18a033bSKonstantin Ananyevsize_t
260e18a033bSKonstantin Ananyevngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
261e18a033bSKonstantin Ananyev{
262e18a033bSKonstantin Ananyev    u_char  *p;
263e18a033bSKonstantin Ananyev
264e18a033bSKonstantin Ananyev    switch (family) {
265e18a033bSKonstantin Ananyev
266e18a033bSKonstantin Ananyev    case AF_INET:
267e18a033bSKonstantin Ananyev
268e18a033bSKonstantin Ananyev        p = addr;
269e18a033bSKonstantin Ananyev
270e18a033bSKonstantin Ananyev        return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
271e18a033bSKonstantin Ananyev                            p[0], p[1], p[2], p[3])
272e18a033bSKonstantin Ananyev               - text;
273e18a033bSKonstantin Ananyev
274e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6)
275e18a033bSKonstantin Ananyev
276e18a033bSKonstantin Ananyev    case AF_INET6:
277e18a033bSKonstantin Ananyev        return ngx_inet6_ntop(addr, text, len);
278e18a033bSKonstantin Ananyev
279e18a033bSKonstantin Ananyev#endif
280e18a033bSKonstantin Ananyev
281e18a033bSKonstantin Ananyev    default:
282e18a033bSKonstantin Ananyev        return 0;
283e18a033bSKonstantin Ananyev    }
284e18a033bSKonstantin Ananyev}
285e18a033bSKonstantin Ananyev
286e18a033bSKonstantin Ananyev
287e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6)
288e18a033bSKonstantin Ananyev
289e18a033bSKonstantin Ananyevsize_t
290e18a033bSKonstantin Ananyevngx_inet6_ntop(u_char *p, u_char *text, size_t len)
291e18a033bSKonstantin Ananyev{
292e18a033bSKonstantin Ananyev    u_char      *dst;
293e18a033bSKonstantin Ananyev    size_t       max, n;
294e18a033bSKonstantin Ananyev    ngx_uint_t   i, zero, last;
295e18a033bSKonstantin Ananyev
296e18a033bSKonstantin Ananyev    if (len < NGX_INET6_ADDRSTRLEN) {
297e18a033bSKonstantin Ananyev        return 0;
298e18a033bSKonstantin Ananyev    }
299e18a033bSKonstantin Ananyev
300e18a033bSKonstantin Ananyev    zero = (ngx_uint_t) -1;
301e18a033bSKonstantin Ananyev    last = (ngx_uint_t) -1;
302e18a033bSKonstantin Ananyev    max = 1;
303e18a033bSKonstantin Ananyev    n = 0;
304e18a033bSKonstantin Ananyev
305e18a033bSKonstantin Ananyev    for (i = 0; i < 16; i += 2) {
306e18a033bSKonstantin Ananyev
307e18a033bSKonstantin Ananyev        if (p[i] || p[i + 1]) {
308e18a033bSKonstantin Ananyev
309e18a033bSKonstantin Ananyev            if (max < n) {
310e18a033bSKonstantin Ananyev                zero = last;
311e18a033bSKonstantin Ananyev                max = n;
312e18a033bSKonstantin Ananyev            }
313e18a033bSKonstantin Ananyev
314e18a033bSKonstantin Ananyev            n = 0;
315e18a033bSKonstantin Ananyev            continue;
316e18a033bSKonstantin Ananyev        }
317e18a033bSKonstantin Ananyev
318e18a033bSKonstantin Ananyev        if (n++ == 0) {
319e18a033bSKonstantin Ananyev            last = i;
320e18a033bSKonstantin Ananyev        }
321e18a033bSKonstantin Ananyev    }
322e18a033bSKonstantin Ananyev
323e18a033bSKonstantin Ananyev    if (max < n) {
324e18a033bSKonstantin Ananyev        zero = last;
325e18a033bSKonstantin Ananyev        max = n;
326e18a033bSKonstantin Ananyev    }
327e18a033bSKonstantin Ananyev
328e18a033bSKonstantin Ananyev    dst = text;
329e18a033bSKonstantin Ananyev    n = 16;
330e18a033bSKonstantin Ananyev
331e18a033bSKonstantin Ananyev    if (zero == 0) {
332e18a033bSKonstantin Ananyev
333e18a033bSKonstantin Ananyev        if ((max == 5 && p[10] == 0xff && p[11] == 0xff)
334e18a033bSKonstantin Ananyev            || (max == 6)
335e18a033bSKonstantin Ananyev            || (max == 7 && p[14] != 0 && p[15] != 1))
336e18a033bSKonstantin Ananyev        {
337e18a033bSKonstantin Ananyev            n = 12;
338e18a033bSKonstantin Ananyev        }
339e18a033bSKonstantin Ananyev
340e18a033bSKonstantin Ananyev        *dst++ = ':';
341e18a033bSKonstantin Ananyev    }
342e18a033bSKonstantin Ananyev
343e18a033bSKonstantin Ananyev    for (i = 0; i < n; i += 2) {
344e18a033bSKonstantin Ananyev
345e18a033bSKonstantin Ananyev        if (i == zero) {
346e18a033bSKonstantin Ananyev            *dst++ = ':';
347e18a033bSKonstantin Ananyev            i += (max - 1) * 2;
348e18a033bSKonstantin Ananyev            continue;
349e18a033bSKonstantin Ananyev        }
350e18a033bSKonstantin Ananyev
351e18a033bSKonstantin Ananyev        dst = ngx_sprintf(dst, "%xd", p[i] * 256 + p[i + 1]);
352e18a033bSKonstantin Ananyev
353e18a033bSKonstantin Ananyev        if (i < 14) {
354e18a033bSKonstantin Ananyev            *dst++ = ':';
355e18a033bSKonstantin Ananyev        }
356e18a033bSKonstantin Ananyev    }
357e18a033bSKonstantin Ananyev
358e18a033bSKonstantin Ananyev    if (n == 12) {
359e18a033bSKonstantin Ananyev        dst = ngx_sprintf(dst, "%ud.%ud.%ud.%ud", p[12], p[13], p[14], p[15]);
360e18a033bSKonstantin Ananyev    }
361e18a033bSKonstantin Ananyev
362e18a033bSKonstantin Ananyev    return dst - text;
363e18a033bSKonstantin Ananyev}
364e18a033bSKonstantin Ananyev
365e18a033bSKonstantin Ananyev#endif
366e18a033bSKonstantin Ananyev
367e18a033bSKonstantin Ananyev
368e18a033bSKonstantin Ananyevngx_int_t
369e18a033bSKonstantin Ananyevngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr)
370e18a033bSKonstantin Ananyev{
371e18a033bSKonstantin Ananyev    u_char      *addr, *mask, *last;
372e18a033bSKonstantin Ananyev    size_t       len;
373e18a033bSKonstantin Ananyev    ngx_int_t    shift;
374e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6)
375e18a033bSKonstantin Ananyev    ngx_int_t    rc;
376e18a033bSKonstantin Ananyev    ngx_uint_t   s, i;
377e18a033bSKonstantin Ananyev#endif
378e18a033bSKonstantin Ananyev
379e18a033bSKonstantin Ananyev    addr = text->data;
380e18a033bSKonstantin Ananyev    last = addr + text->len;
381e18a033bSKonstantin Ananyev
382e18a033bSKonstantin Ananyev    mask = ngx_strlchr(addr, last, '/');
383e18a033bSKonstantin Ananyev    len = (mask ? mask : last) - addr;
384e18a033bSKonstantin Ananyev
385e18a033bSKonstantin Ananyev    cidr->u.in.addr = ngx_inet_addr(addr, len);
386e18a033bSKonstantin Ananyev
387e18a033bSKonstantin Ananyev    if (cidr->u.in.addr != INADDR_NONE) {
388e18a033bSKonstantin Ananyev        cidr->family = AF_INET;
389e18a033bSKonstantin Ananyev
390e18a033bSKonstantin Ananyev        if (mask == NULL) {
391e18a033bSKonstantin Ananyev            cidr->u.in.mask = 0xffffffff;
392e18a033bSKonstantin Ananyev            return NGX_OK;
393e18a033bSKonstantin Ananyev        }
394e18a033bSKonstantin Ananyev
395e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6)
396e18a033bSKonstantin Ananyev    } else if (ngx_inet6_addr(addr, len, cidr->u.in6.addr.s6_addr) == NGX_OK) {
397e18a033bSKonstantin Ananyev        cidr->family = AF_INET6;
398e18a033bSKonstantin Ananyev
399e18a033bSKonstantin Ananyev        if (mask == NULL) {
400e18a033bSKonstantin Ananyev            ngx_memset(cidr->u.in6.mask.s6_addr, 0xff, 16);
401e18a033bSKonstantin Ananyev            return NGX_OK;
402e18a033bSKonstantin Ananyev        }
403e18a033bSKonstantin Ananyev
404e18a033bSKonstantin Ananyev#endif
405e18a033bSKonstantin Ananyev    } else {
406e18a033bSKonstantin Ananyev        return NGX_ERROR;
407e18a033bSKonstantin Ananyev    }
408e18a033bSKonstantin Ananyev
409e18a033bSKonstantin Ananyev    mask++;
410e18a033bSKonstantin Ananyev
411e18a033bSKonstantin Ananyev    shift = ngx_atoi(mask, last - mask);
412e18a033bSKonstantin Ananyev    if (shift == NGX_ERROR) {
413e18a033bSKonstantin Ananyev        return NGX_ERROR;
414e18a033bSKonstantin Ananyev    }
415e18a033bSKonstantin Ananyev
416e18a033bSKonstantin Ananyev    switch (cidr->family) {
417e18a033bSKonstantin Ananyev
418e18a033bSKonstantin Ananyev#if (NGX_HAVE_INET6)
419e18a033bSKonstantin Ananyev    case AF_INET6:
420e18a033bSKonstantin Ananyev        if (shift > 128) {
421e18a033bSKonstantin Ananyev            return NGX_ERROR;
422e18a033bSKonstantin Ananyev        }
423e18a033bSKonstantin Ananyev
424e18a033bSKonstantin Ananyev        addr = cidr->u.in6.addr.s6_addr;
425