@@ -268,41 +268,15 @@ Datum
268268inet_to_cidr (PG_FUNCTION_ARGS )
269269{
270270inet * src = PG_GETARG_INET_PP (0 );
271- inet * dst ;
272271int bits ;
273- int byte ;
274- int nbits ;
275- int maxbytes ;
276272
277273bits = ip_bits (src );
278274
279275/* safety check */
280276if ((bits < 0 )|| (bits > ip_maxbits (src )))
281277elog (ERROR ,"invalid inet bit length: %d" ,bits );
282278
283- /* clone the original data */
284- dst = (inet * )palloc (VARSIZE_ANY (src ));
285- memcpy (dst ,src ,VARSIZE_ANY (src ));
286-
287- /* zero out any bits to the right of the netmask */
288- byte = bits /8 ;
289-
290- nbits = bits %8 ;
291- /* clear the first byte, this might be a partial byte */
292- if (nbits != 0 )
293- {
294- ip_addr (dst )[byte ] &= ~(0xFF >>nbits );
295- byte ++ ;
296- }
297- /* clear remaining bytes */
298- maxbytes = ip_addrsize (dst );
299- while (byte < maxbytes )
300- {
301- ip_addr (dst )[byte ]= 0 ;
302- byte ++ ;
303- }
304-
305- PG_RETURN_INET_P (dst );
279+ PG_RETURN_INET_P (cidr_set_masklen_internal (src ,bits ));
306280}
307281
308282Datum
@@ -334,10 +308,6 @@ cidr_set_masklen(PG_FUNCTION_ARGS)
334308{
335309inet * src = PG_GETARG_INET_PP (0 );
336310int bits = PG_GETARG_INT32 (1 );
337- inet * dst ;
338- int byte ;
339- int nbits ;
340- int maxbytes ;
341311
342312if (bits == -1 )
343313bits = ip_maxbits (src );
@@ -347,31 +317,36 @@ cidr_set_masklen(PG_FUNCTION_ARGS)
347317(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
348318errmsg ("invalid mask length: %d" ,bits )));
349319
350- /* clone the original data */
351- dst = (inet * )palloc (VARSIZE_ANY (src ));
352- memcpy (dst ,src ,VARSIZE_ANY (src ));
320+ PG_RETURN_INET_P (cidr_set_masklen_internal (src ,bits ));
321+ }
353322
354- ip_bits (dst )= bits ;
323+ /*
324+ * Copy src and set mask length to 'bits' (which must be valid for the family)
325+ */
326+ inet *
327+ cidr_set_masklen_internal (const inet * src ,int bits )
328+ {
329+ inet * dst = (inet * )palloc0 (sizeof (inet ));
355330
356- /* zero out any bits to the right of the new netmask */
357- byte = bits / 8 ;
331+ ip_family ( dst ) = ip_family ( src );
332+ ip_bits ( dst ) = bits ;
358333
359- nbits = bits %8 ;
360- /* clear the first byte, this might be a partial byte */
361- if (nbits != 0 )
334+ if (bits > 0 )
362335{
363- ip_addr (dst )[byte ] &= ~(0xFF >>nbits );
364- byte ++ ;
365- }
366- /* clear remaining bytes */
367- maxbytes = ip_addrsize (dst );
368- while (byte < maxbytes )
369- {
370- ip_addr (dst )[byte ]= 0 ;
371- byte ++ ;
336+ Assert (bits <=ip_maxbits (dst ));
337+
338+ /* Clone appropriate bytes of the address, leaving the rest 0 */
339+ memcpy (ip_addr (dst ),ip_addr (src ), (bits + 7 ) /8 );
340+
341+ /* Clear any unwanted bits in the last partial byte */
342+ if (bits %8 )
343+ ip_addr (dst )[bits /8 ] &= ~(0xFF >> (bits %8 ));
372344}
373345
374- PG_RETURN_INET_P (dst );
346+ /* Set varlena header correctly */
347+ SET_INET_VARSIZE (dst );
348+
349+ return dst ;
375350}
376351
377352/*
@@ -719,11 +694,7 @@ network_broadcast(PG_FUNCTION_ARGS)
719694/* make sure any unused bits are zeroed */
720695dst = (inet * )palloc0 (sizeof (inet ));
721696
722- if (ip_family (ip )== PGSQL_AF_INET )
723- maxbytes = 4 ;
724- else
725- maxbytes = 16 ;
726-
697+ maxbytes = ip_addrsize (ip );
727698bits = ip_bits (ip );
728699a = ip_addr (ip );
729700b = ip_addr (dst );
@@ -853,11 +824,7 @@ network_hostmask(PG_FUNCTION_ARGS)
853824/* make sure any unused bits are zeroed */
854825dst = (inet * )palloc0 (sizeof (inet ));
855826
856- if (ip_family (ip )== PGSQL_AF_INET )
857- maxbytes = 4 ;
858- else
859- maxbytes = 16 ;
860-
827+ maxbytes = ip_addrsize (ip );
861828bits = ip_maxbits (ip )- ip_bits (ip );
862829b = ip_addr (dst );
863830
@@ -907,8 +874,7 @@ Datum
907874inet_merge (PG_FUNCTION_ARGS )
908875{
909876inet * a1 = PG_GETARG_INET_PP (0 ),
910- * a2 = PG_GETARG_INET_PP (1 ),
911- * result ;
877+ * a2 = PG_GETARG_INET_PP (1 );
912878int commonbits ;
913879
914880if (ip_family (a1 )!= ip_family (a2 ))
@@ -919,24 +885,7 @@ inet_merge(PG_FUNCTION_ARGS)
919885commonbits = bitncommon (ip_addr (a1 ),ip_addr (a2 ),
920886Min (ip_bits (a1 ),ip_bits (a2 )));
921887
922- /* Make sure any unused bits are zeroed. */
923- result = (inet * )palloc0 (sizeof (inet ));
924-
925- ip_family (result )= ip_family (a1 );
926- ip_bits (result )= commonbits ;
927-
928- /* Clone appropriate bytes of the address. */
929- if (commonbits > 0 )
930- memcpy (ip_addr (result ),ip_addr (a1 ), (commonbits + 7 ) /8 );
931-
932- /* Clean any unwanted bits in the last partial byte. */
933- if (commonbits %8 != 0 )
934- ip_addr (result )[commonbits /8 ] &= ~(0xFF >> (commonbits %8 ));
935-
936- /* Set varlena header correctly. */
937- SET_INET_VARSIZE (result );
938-
939- PG_RETURN_INET_P (result );
888+ PG_RETURN_INET_P (cidr_set_masklen_internal (a1 ,commonbits ));
940889}
941890
942891/*