88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/libpq/ip.c,v 1.29 2004/09/27 23:24:30 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/libpq/ip.c,v 1.30 2004/11/08 01:54:40 tgl Exp $
1212 *
1313 * This file and the IPV6 implementation were initially provided by
1414 * Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
@@ -340,37 +340,40 @@ SockAddr_cidr_mask(struct sockaddr_storage * mask, char *numbits, int family)
340340{
341341longbits ;
342342char * endptr ;
343- struct sockaddr_in mask4 ;
344-
345- #ifdef HAVE_IPV6
346- struct sockaddr_in6 mask6 ;
347- #endif
348343
349344bits = strtol (numbits ,& endptr ,10 );
350345
351346if (* numbits == '\0' || * endptr != '\0' )
352347return - 1 ;
353348
354- if ((bits < 0 )|| (family == AF_INET && bits > 32 )
355- #ifdef HAVE_IPV6
356- || (family == AF_INET6 && bits > 128 )
357- #endif
358- )
359- return - 1 ;
360-
361349switch (family )
362350{
363351case AF_INET :
364- mask4 .sin_addr .s_addr =
365- htonl ((0xffffffffUL << (32 - bits ))
366- & 0xffffffffUL );
367- memcpy (mask ,& mask4 ,sizeof (mask4 ));
368- break ;
352+ {
353+ struct sockaddr_in mask4 ;
354+ longmaskl ;
355+
356+ if (bits < 0 || bits > 32 )
357+ return - 1 ;
358+ /* avoid "x << 32", which is not portable */
359+ if (bits > 0 )
360+ maskl = (0xffffffffUL << (32 - (int )bits ))
361+ & 0xffffffffUL ;
362+ else
363+ maskl = 0 ;
364+ mask4 .sin_addr .s_addr = htonl (maskl );
365+ memcpy (mask ,& mask4 ,sizeof (mask4 ));
366+ break ;
367+ }
368+
369369#ifdef HAVE_IPV6
370370case AF_INET6 :
371371{
372+ struct sockaddr_in6 mask6 ;
372373int i ;
373374
375+ if (bits < 0 || bits > 128 )
376+ return - 1 ;
374377for (i = 0 ;i < 16 ;i + + )
375378{
376379if (bits <=0 )
@@ -380,7 +383,7 @@ SockAddr_cidr_mask(struct sockaddr_storage * mask, char *numbits, int family)
380383else
381384{
382385mask6 .sin6_addr .s6_addr [i ]=
383- (0xff << (8 - bits ))& 0xff ;
386+ (0xff << (8 - ( int ) bits ))& 0xff ;
384387}
385388bits - = 8 ;
386389}