33 *is for IP V4 CIDR notation, but prepared for V6: just
44 *add the necessary bits where the comments indicate.
55 *
6- *$Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.17 2000/02/21 18:47:07 tgl Exp $
7- *
6+ *$Id: network.c,v 1.18 2000/02/21 18:49:54 tgl Exp $
87 *Jon Postel RIP 16 Oct 1998
98 */
109
11- #include "postgres.h"
12-
1310#include <sys/types.h>
1411#include <sys/socket.h>
12+
1513#include <errno.h>
14+
1615#include <netinet/in.h>
1716#include <arpa/inet.h>
1817
18+ #include "postgres.h"
1919#include "utils/builtins.h"
2020
21-
22- static int v4bitncmp (unsigned long a1 ,unsigned long a2 ,int bits );
21+ static int v4bitncmp (unsignedint a1 ,unsignedint a2 ,int bits );
2322
2423/*
2524 *Access macros.Add IPV6 support.
@@ -40,7 +39,6 @@ static intv4bitncmp(unsigned long a1, unsigned long a2, int bits);
4039#define ip_v4addr (inetptr ) \
4140(((inet_struct *)VARDATA(inetptr))->addr.ipv4_addr)
4241
43-
4442/* Common input routine */
4543static inet *
4644network_in (char * src ,int type )
@@ -129,85 +127,92 @@ cidr_out(inet *src)
129127}
130128
131129/*
132- *Boolean tests for ordering operators --- must agree with sorting
133- *operator network_cmp().
130+ *Boolean tests for magnitude. Add V4/V6 testing!
134131 */
135132
136133bool
137134network_lt (inet * a1 ,inet * a2 )
138135{
139136if (!PointerIsValid (a1 )|| !PointerIsValid (a2 ))
140137return FALSE;
141- return (bool ) (network_cmp (a1 ,a2 )< 0 );
138+ if ((ip_family (a1 )== AF_INET )&& (ip_family (a2 )== AF_INET ))
139+ {
140+ int order = v4bitncmp (ip_v4addr (a1 ),ip_v4addr (a2 ),ip_bits (a2 ));
141+
142+ return ((order < 0 )|| ((order == 0 )&& (ip_bits (a1 )< ip_bits (a2 ))));
143+ }
144+ else
145+ {
146+ /* Go for an IPV6 address here, before faulting out: */
147+ elog (ERROR ,"cannot compare address families %d and %d" ,
148+ ip_family (a1 ),ip_family (a2 ));
149+ return FALSE;
150+ }
142151}
143152
144153bool
145154network_le (inet * a1 ,inet * a2 )
146155{
147156if (!PointerIsValid (a1 )|| !PointerIsValid (a2 ))
148157return FALSE;
149- return (bool ) ( network_cmp ( a1 ,a2 )<= 0 );
158+ return (network_lt ( a1 ,a2 )|| network_eq ( a1 , a2 ) );
150159}
151160
152161bool
153162network_eq (inet * a1 ,inet * a2 )
154163{
155164if (!PointerIsValid (a1 )|| !PointerIsValid (a2 ))
156165return FALSE;
157- return (bool ) (network_cmp (a1 ,a2 )== 0 );
166+ if ((ip_family (a1 )== AF_INET )&& (ip_family (a2 )== AF_INET ))
167+ {
168+ return ((ip_bits (a1 )== ip_bits (a2 ))
169+ && (v4bitncmp (ip_v4addr (a1 ),ip_v4addr (a2 ),ip_bits (a1 ))== 0 ));
170+ }
171+ else
172+ {
173+ /* Go for an IPV6 address here, before faulting out: */
174+ elog (ERROR ,"cannot compare address families %d and %d" ,
175+ ip_family (a1 ),ip_family (a2 ));
176+ return FALSE;
177+ }
158178}
159179
160180bool
161181network_ge (inet * a1 ,inet * a2 )
162182{
163183if (!PointerIsValid (a1 )|| !PointerIsValid (a2 ))
164184return FALSE;
165- return (bool ) ( network_cmp ( a1 ,a2 )>= 0 );
185+ return (network_gt ( a1 ,a2 )|| network_eq ( a1 , a2 ) );
166186}
167187
168188bool
169189network_gt (inet * a1 ,inet * a2 )
170190{
171191if (!PointerIsValid (a1 )|| !PointerIsValid (a2 ))
172192return FALSE;
173- return (bool ) (network_cmp (a1 ,a2 )> 0 );
174- }
175-
176- bool
177- network_ne (inet * a1 ,inet * a2 )
178- {
179- if (!PointerIsValid (a1 )|| !PointerIsValid (a2 ))
180- return FALSE;
181- return (bool ) (network_cmp (a1 ,a2 )!= 0 );
182- }
183-
184- /*
185- *Comparison function for sorting. Add V4/V6 testing!
186- */
187-
188- int4
189- network_cmp (inet * a1 ,inet * a2 )
190- {
191193if ((ip_family (a1 )== AF_INET )&& (ip_family (a2 )== AF_INET ))
192194{
193- int order = v4bitncmp (ip_v4addr (a1 ),ip_v4addr (a2 ),
194- (ip_bits (a1 )< ip_bits (a2 )) ?
195- ip_bits (a1 ) :ip_bits (a2 ));
196-
197- if (order )
198- return order ;
199- /* They agree in the first N bits, so shorter one comes first */
200- return (int )ip_bits (a1 )- (int )ip_bits (a2 );
195+ int order = v4bitncmp (ip_v4addr (a1 ),ip_v4addr (a2 ),ip_bits (a2 ));
196+
197+ return ((order > 0 )|| ((order == 0 )&& (ip_bits (a1 )> ip_bits (a2 ))));
201198}
202199else
203200{
204201/* Go for an IPV6 address here, before faulting out: */
205202elog (ERROR ,"cannot compare address families %d and %d" ,
206203ip_family (a1 ),ip_family (a2 ));
207- return 0 ;
204+ return FALSE ;
208205}
209206}
210207
208+ bool
209+ network_ne (inet * a1 ,inet * a2 )
210+ {
211+ if (!PointerIsValid (a1 )|| !PointerIsValid (a2 ))
212+ return FALSE;
213+ return (!network_eq (a1 ,a2 ));
214+ }
215+
211216bool
212217network_sub (inet * a1 ,inet * a2 )
213218{
@@ -288,6 +293,28 @@ network_supeq(inet *a1, inet *a2)
288293}
289294}
290295
296+ /*
297+ *Comparison function for sorting. Add V4/V6 testing!
298+ */
299+
300+ int4
301+ network_cmp (inet * a1 ,inet * a2 )
302+ {
303+ if (ntohl (ip_v4addr (a1 ))< ntohl (ip_v4addr (a2 )))
304+ return (-1 );
305+
306+ if (ntohl (ip_v4addr (a1 ))> ntohl (ip_v4addr (a2 )))
307+ return (1 );
308+
309+ if (ip_bits (a1 )< ip_bits (a2 ))
310+ return (-1 );
311+
312+ if (ip_bits (a1 )> ip_bits (a2 ))
313+ return (1 );
314+
315+ return 0 ;
316+ }
317+
291318text *
292319network_host (inet * ip )
293320{
@@ -449,7 +476,7 @@ network_netmask(inet *ip)
449476 */
450477
451478static int
452- v4bitncmp (unsignedlong a1 ,unsignedlong a2 ,int bits )
479+ v4bitncmp (unsignedint a1 ,unsignedint a2 ,int bits )
453480{
454481unsigned long mask = 0 ;
455482int i ;
@@ -458,11 +485,9 @@ v4bitncmp(unsigned long a1, unsigned long a2, int bits)
458485mask = (mask >>1 ) |0x80000000 ;
459486a1 = ntohl (a1 );
460487a2 = ntohl (a2 );
461- a1 &=mask ;
462- a2 &=mask ;
463- if (a1 < a2 )
488+ if ((a1 & mask )< (a2 & mask ))
464489return (-1 );
465- else if (a1 > a2 )
490+ else if (( a1 & mask ) > ( a2 & mask ) )
466491return (1 );
467492return (0 );
468493}