aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_inet.c
diff options
context:
space:
mode:
authorDmitry Volyntsev <xeioex@nginx.com>2016-09-07 13:56:53 +0300
committerDmitry Volyntsev <xeioex@nginx.com>2016-09-07 13:56:53 +0300
commita613df5b3f470369e7ce7ebe34e82056b6fc0919 (patch)
treeb8759158ae920818f1c9d67159b42aa4a3623ddc /src/core/ngx_inet.c
parent41e7bda773bd21e7a6991cea22d9931b9be45090 (diff)
downloadnginx-a613df5b3f470369e7ce7ebe34e82056b6fc0919.tar.gz
nginx-a613df5b3f470369e7ce7ebe34e82056b6fc0919.zip
Core: introduced ngx_cidr_match() function.
Diffstat (limited to 'src/core/ngx_inet.c')
-rw-r--r--src/core/ngx_inet.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index c4aaf3a84..dbd1f4611 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -466,6 +466,93 @@ ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr)
ngx_int_t
+ngx_cidr_match(struct sockaddr *sa, ngx_array_t *cidrs)
+{
+#if (NGX_HAVE_INET6)
+ u_char *p;
+#endif
+ in_addr_t inaddr;
+ ngx_cidr_t *cidr;
+ ngx_uint_t family, i;
+#if (NGX_HAVE_INET6)
+ ngx_uint_t n;
+ struct in6_addr *inaddr6;
+#endif
+
+#if (NGX_SUPPRESS_WARN)
+ inaddr = 0;
+#if (NGX_HAVE_INET6)
+ inaddr6 = NULL;
+#endif
+#endif
+
+ family = sa->sa_family;
+
+ if (family == AF_INET) {
+ inaddr = ((struct sockaddr_in *) sa)->sin_addr.s_addr;
+ }
+
+#if (NGX_HAVE_INET6)
+ else if (family == AF_INET6) {
+ inaddr6 = &((struct sockaddr_in6 *) sa)->sin6_addr;
+
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+ family = AF_INET;
+
+ p = inaddr6->s6_addr;
+
+ inaddr = p[12] << 24;
+ inaddr += p[13] << 16;
+ inaddr += p[14] << 8;
+ inaddr += p[15];
+
+ inaddr = htonl(inaddr);
+ }
+ }
+#endif
+
+ for (cidr = cidrs->elts, i = 0; i < cidrs->nelts; i++) {
+ if (cidr[i].family != family) {
+ goto next;
+ }
+
+ switch (family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ for (n = 0; n < 16; n++) {
+ if ((inaddr6->s6_addr[n] & cidr[i].u.in6.mask.s6_addr[n])
+ != cidr[i].u.in6.addr.s6_addr[n])
+ {
+ goto next;
+ }
+ }
+ break;
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+ case AF_UNIX:
+ break;
+#endif
+
+ default: /* AF_INET */
+ if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) {
+ goto next;
+ }
+ break;
+ }
+
+ return NGX_OK;
+
+ next:
+ continue;
+ }
+
+ return NGX_DECLINED;
+}
+
+
+ngx_int_t
ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)
{
in_addr_t inaddr;