aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/ip.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2003-06-12 02:12:58 +0000
committerBruce Momjian <bruce@momjian.us>2003-06-12 02:12:58 +0000
commitb78961b0da946e67c0f46156c193d27e63aa3de9 (patch)
treeb0633beed7f5203a8abfe4cef2cb53a7ba7275a8 /src/backend/libpq/ip.c
parent310c084921930f5a01601dc11b5bc0fb363c71e4 (diff)
downloadpostgresql-b78961b0da946e67c0f46156c193d27e63aa3de9.tar.gz
postgresql-b78961b0da946e67c0f46156c193d27e63aa3de9.zip
Here is a patch that allows CIDR netmasks in pg_hba.conf. It allows two
address/mask forms: . address/maskbits, or . address netmask (as now) If the patch is accepted I will submit a documentation patch to cover it. This is submitted by agreement with Kurt Roeckx, who has worked on a patch that covers this and other IPv6 issues. Andrew Dunstan
Diffstat (limited to 'src/backend/libpq/ip.c')
-rw-r--r--src/backend/libpq/ip.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c
index 948fb576141..2573829fd88 100644
--- a/src/backend/libpq/ip.c
+++ b/src/backend/libpq/ip.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.9 2003/06/09 17:59:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.10 2003/06/12 02:12:58 momjian Exp $
*
* This file and the IPV6 implementation were initially provided by
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
@@ -251,6 +251,59 @@ SockAddr_pton(SockAddr *sa, const char *src)
}
}
+/*
+ * SockAddr_cidr_mask - make a network mask of the appropriate family
+ * and required number of significant bits
+ */
+
+int
+SockAddr_cidr_mask(SockAddr *mask, char *numbits, int family)
+{
+ int i;
+ long bits;
+ char * endptr;
+
+ bits = strtol(numbits,&endptr,10);
+
+ if (*numbits == '\0' || *endptr != '\0')
+ return -1;
+
+
+ if ((bits < 0) || (family == AF_INET && bits > 32)
+#ifdef HAVE_IPV6
+ || (family == AF_INET6 && bits > 128)
+#endif
+ )
+ return -1;
+
+ mask->sa.sa_family = family;
+
+ switch (family)
+ {
+ case AF_INET:
+ mask->in.sin_addr.s_addr = htonl((0xffffffffUL << (32 - bits)) & 0xffffffffUL);
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ for (i = 0; i < 16; i++)
+ {
+ if (bits <= 0)
+ mask->in6.sin6_addr.s6_addr[i]=0;
+ else if (bits >= 8)
+ mask->in6.sin6_addr.s6_addr[i]=0xff;
+ else
+ mask->in6.sin6_addr.s6_addr[i]=(0xff << (8 - bits)) & 0xff;
+ bits -= 8;
+
+ }
+ break;
+#endif
+ default:
+ return -1;
+ }
+ return 0;
+
+}
/*
* isAF_INETx - check to see if sa is AF_INET or AF_INET6