[EMAIL PROTECTED] writes:
> So I'm guessing there is something wrong with the way 0.0.0.0/0 is being
> recognized? 

Hmm, I'm betting you are on a machine where shifting a 32-bit quantity
left 32 bits doesn't reliably give zero.  This misbehavior is actually
allowed by the C standard :-( ... but it's certainly caught many a
programmer.  Including us.  I've applied the attached patch, if you
want to fix it locally --- or you could just avoid the bug by using a
separate all-zeroes mask field, for now.

Thanks for the report!

                        regards, tom lane

Index: ip.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/ip.c,v
retrieving revision 1.23.2.1
diff -c -r1.23.2.1 ip.c
*** ip.c        24 Apr 2004 20:10:47 -0000      1.23.2.1
--- ip.c        8 Nov 2004 01:45:01 -0000
***************
*** 344,380 ****
  {
        long            bits;
        char       *endptr;
-       struct sockaddr_in mask4;
- 
- #ifdef        HAVE_IPV6
-       struct sockaddr_in6 mask6;
- #endif
  
        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;
- 
        switch (family)
        {
                case AF_INET:
!                       mask4.sin_addr.s_addr =
!                               htonl((0xffffffffUL << (32 - bits))
!                                         & 0xffffffffUL);
!                       memcpy(mask, &mask4, sizeof(mask4));
!                       break;
  #ifdef HAVE_IPV6
                case AF_INET6:
                        {
                                int                     i;
  
                                for (i = 0; i < 16; i++)
                                {
                                        if (bits <= 0)
--- 344,383 ----
  {
        long            bits;
        char       *endptr;
  
        bits = strtol(numbits, &endptr, 10);
  
        if (*numbits == '\0' || *endptr != '\0')
                return -1;
  
        switch (family)
        {
                case AF_INET:
!                       {
!                               struct sockaddr_in mask4;
!                               long            maskl;
! 
!                               if (bits < 0 || bits > 32)
!                                       return -1;
!                               /* avoid "x << 32", which is not portable */
!                               if (bits > 0)
!                                       maskl = (0xffffffffUL << (32 - (int) 
bits))
!                                               & 0xffffffffUL;
!                               else
!                                       maskl = 0;
!                               mask4.sin_addr.s_addr = htonl(maskl);
!                               memcpy(mask, &mask4, sizeof(mask4));
!                               break;
!                       }
! 
  #ifdef HAVE_IPV6
                case AF_INET6:
                        {
+                               struct sockaddr_in6 mask6;
                                int                     i;
  
+                               if (bits < 0 || bits > 128)
+                                       return -1;
                                for (i = 0; i < 16; i++)
                                {
                                        if (bits <= 0)
***************
*** 384,390 ****
                                        else
                                        {
                                                mask6.sin6_addr.s6_addr[i] =
!                                                       (0xff << (8 - bits)) & 
0xff;
                                        }
                                        bits -= 8;
                                }
--- 387,393 ----
                                        else
                                        {
                                                mask6.sin6_addr.s6_addr[i] =
!                                                       (0xff << (8 - (int) 
bits)) & 0xff;
                                        }
                                        bits -= 8;
                                }

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

Reply via email to