Index: src/backend/libpq/hba.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/libpq/hba.c,v
retrieving revision 1.100
diff -c -r1.100 hba.c
*** src/backend/libpq/hba.c	2003/04/25 01:24:00	1.100
--- src/backend/libpq/hba.c	2003/05/09 22:49:35
***************
*** 588,593 ****
--- 588,594 ----
  	else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") == 0)
  	{
  		SockAddr file_ip_addr, mask;
+ 		char * cidr_slash;
  
  		if (strcmp(token, "hostssl") == 0)
  		{
***************
*** 618,643 ****
  			goto hba_syntax;
  		user = lfirst(line);
  
! 		/* Read the IP address field. */
  		line = lnext(line);
  		if (!line)
  			goto hba_syntax;
  		token = lfirst(line);
  
  		if(SockAddr_pton(&file_ip_addr, token) < 0)
  			goto hba_syntax;
  
! 		/* Read the mask field. */
! 		line = lnext(line);
! 		if (!line)
! 			goto hba_syntax;
! 		token = lfirst(line);
  
! 		if(SockAddr_pton(&mask, token) < 0)
! 			goto hba_syntax;
  
! 		if(file_ip_addr.sa.sa_family != mask.sa.sa_family)
! 			goto hba_syntax;
  
  		/* Read the rest of the line. */
  		line = lnext(line);
--- 619,666 ----
  			goto hba_syntax;
  		user = lfirst(line);
  
! 		/* Read the IP address field. (with or without CIDR netmask) */
  		line = lnext(line);
  		if (!line)
  			goto hba_syntax;
  		token = lfirst(line);
  
+ 		/* Check if it has a CIDR suffix and if so isolate it */
+ 		cidr_slash = index(token,'/');
+ 		if (cidr_slash)
+ 			*cidr_slash = '\0';
+ 
+ 		/* Get the IP address either way */
  		if(SockAddr_pton(&file_ip_addr, token) < 0)
+ 		{
+ 			if (cidr_slash)
+ 				*cidr_slash = '/';
  			goto hba_syntax;
+ 		}
  
! 		/* Get the netmask */
! 		if (cidr_slash)
! 		{
! 			*cidr_slash = '/';
! 			if (SockAddr_cidr_mask(&mask, ++cidr_slash, file_ip_addr.sa.sa_family) < 0)
! 				goto hba_syntax;
! 		}
! 		else
! 		{
! 			/* Read the mask field. */
! 			line = lnext(line);
! 			if (!line)
! 				goto hba_syntax;
! 			token = lfirst(line);
  
! 			if(SockAddr_pton(&mask, token) < 0)
! 				goto hba_syntax;
  
! 			if(file_ip_addr.sa.sa_family != mask.sa.sa_family)
! 				goto hba_syntax;
! 		}
! 
! 
  
  		/* Read the rest of the line. */
  		line = lnext(line);
Index: src/backend/libpq/ip.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/libpq/ip.c,v
retrieving revision 1.7
diff -c -r1.7 ip.c
*** src/backend/libpq/ip.c	2003/04/22 03:52:56	1.7
--- src/backend/libpq/ip.c	2003/05/09 22:49:35
***************
*** 236,241 ****
--- 236,294 ----
  	}
  }
  
+ /*
+  *  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
Index: src/include/libpq/ip.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/libpq/ip.h,v
retrieving revision 1.3
diff -c -r1.3 ip.h
*** src/include/libpq/ip.h	2003/04/02 00:49:28	1.3
--- src/include/libpq/ip.h	2003/05/09 22:49:35
***************
*** 25,30 ****
--- 25,32 ----
  						   int v4conv);
  extern int   SockAddr_pton(SockAddr *sa, const char *src);
  
+ extern int SockAddr_cidr_mask(SockAddr *mask, char *numbits, int family);
+ 
  extern int   isAF_INETx(const int family);
  extern int   rangeSockAddr(const SockAddr *addr, const SockAddr *netaddr,
  						   const SockAddr *netmask);
