11/*
2- *PostgreSQL type definitions for the INET type. This
2+ *PostgreSQL type definitions for the INET type. This
33 *is for IP V4 CIDR notation, but prepared for V6: just
44 *add the necessary bits where the comments indicate.
55 *
6- *$Id: inet.c,v 1.8 1998/10/2104:25:25 momjian Exp $
6+ *$Id: inet.c,v 1.9 1998/10/2116:06:45 momjian Exp $
77 *Jon Postel RIP 16 Oct 1998
88 */
99
2222#include <utils/builtins.h>
2323#include <utils/inet.h>
2424
25- static int v4bitncmp (unsignedint a1 ,unsignedint a2 ,int bits );
25+ static int v4bitncmp (unsignedint a1 ,unsignedint a2 ,int bits );
2626
2727/*
2828 *Access macros.Add IPV6 support.
@@ -37,11 +37,14 @@ static int v4bitncmp(unsigned int a1, unsigned int a2, int bits);
3737#define ip_bits (inetptr ) \
3838(((inet_struct *)VARDATA(inetptr))->bits)
3939
40+ #define ip_type (inetptr ) \
41+ (((inet_struct *)VARDATA(inetptr))->type)
42+
4043#define ip_v4addr (inetptr ) \
4144(((inet_struct *)VARDATA(inetptr))->addr.ipv4_addr)
4245
4346/*
44- *IP address reader.
47+ *INET address reader.
4548 */
4649
4750inet *
@@ -70,11 +73,12 @@ inet_in(char *src)
7073+ ((char * )& ip_v4addr (dst )- (char * )VARDATA (dst ))
7174+ ip_addrsize (dst );
7275ip_bits (dst )= bits ;
76+ ip_type (dst )= 0 ;
7377return (dst );
7478}
7579
7680/*
77- *IP address output function.
81+ *INET address output function.
7882 */
7983
8084char *
@@ -99,6 +103,8 @@ inet_out(inet *src)
99103elog (ERROR ,"unknown address family (%d)" ,ip_family (src ));
100104return (NULL );
101105}
106+ if (ip_type (src )== 0 && ip_bits (src )== 32 && (dst = strchr (tmp ,'/' ))!= NULL )
107+ * dst = 0 ;
102108dst = palloc (strlen (tmp )+ 1 );
103109if (dst == NULL )
104110{
@@ -109,6 +115,39 @@ inet_out(inet *src)
109115return (dst );
110116}
111117
118+ /*
119+ *CIDR uses all of INET's funcs, just has a separate input func.
120+ */
121+
122+ inet *
123+ cidr_in (char * src )
124+ {
125+ int bits ;
126+ inet * dst ;
127+
128+ dst = palloc (VARHDRSZ + sizeof (inet_struct ));
129+ if (dst == NULL )
130+ {
131+ elog (ERROR ,"unable to allocate memory in cidr_in()" );
132+ return (NULL );
133+ }
134+ /* First, try for an IP V4 address: */
135+ ip_family (dst )= AF_INET ;
136+ bits = inet_net_pton (ip_family (dst ),src ,& ip_v4addr (dst ),ip_addrsize (dst ));
137+ if ((bits < 0 )|| (bits > 32 ))
138+ {
139+ /* Go for an IPV6 address here, before faulting out: */
140+ elog (ERROR ,"could not parse \"%s\"" ,src );
141+ pfree (dst );
142+ return (NULL );
143+ }
144+ VARSIZE (dst )= VARHDRSZ
145+ + ((char * )& ip_v4addr (dst )- (char * )VARDATA (dst ))
146+ + ip_addrsize (dst );
147+ ip_bits (dst )= bits ;
148+ return (dst );
149+ }
150+
112151/*
113152 *Boolean tests for magnitude. Add V4/V6 testing!
114153 */
@@ -267,20 +306,23 @@ inet_cmp(inet *a1, inet *a2)
267306}
268307
269308text *
270- inet_netmask (inet * ip )
309+ inet_host (inet * ip )
271310{
272- text * ret ;
273- int len ;
311+ text * ret ;
312+ int len ;
274313char * ptr ,
275314tmp [sizeof ("255.255.255.255/32" )];
276315
316+ if (ip_type (ip ))
317+ {
318+ elog (ERROR ,"CIDR type has no host part" );
319+ return NULL ;
320+ }
321+
277322if (ip_family (ip )== AF_INET )
278323{
279324/* It's an IP V4 address: */
280- int addr = htonl ((-1 << (32 - ip_bits (ip )))& 0xffffffff );
281-
282- /* a little wasteful by why reinvent the wheel? */
283- if (inet_net_ntop (AF_INET ,& addr ,32 ,tmp ,sizeof (tmp ))< 0 )
325+ if (inet_net_ntop (AF_INET ,& ip_v4addr (ip ),32 ,tmp ,sizeof (tmp ))< 0 )
284326{
285327elog (ERROR ,"unable to print netmask (%s)" ,strerror (errno ));
286328return (NULL );
@@ -298,7 +340,7 @@ inet_netmask(inet *ip)
298340ret = palloc (len );
299341if (ret == NULL )
300342{
301- elog (ERROR ,"unable to allocate memory ininet_netmask ()" );
343+ elog (ERROR ,"unable to allocate memory ininet_host ()" );
302344return (NULL );
303345}
304346VARSIZE (ret )= len ;
@@ -307,23 +349,24 @@ inet_netmask(inet *ip)
307349}
308350
309351int4
310- inet_masklen (inet * ip )
352+ inet_netmasklen (inet * ip )
311353{
312354return ip_bits (ip );
313355}
314356
315357text *
316358inet_broadcast (inet * ip )
317359{
318- text * ret ;
319- int len ;
360+ text * ret ;
361+ int len ;
320362char * ptr ,
321363tmp [sizeof ("255.255.255.255/32" )]= "Hello" ;
322364
323365if (ip_family (ip )== AF_INET )
324366{
325367/* It's an IP V4 address: */
326- int addr = htonl (ntohl (ip_v4addr (ip )) | (0xffffffff >>ip_bits (ip )));
368+ int addr = htonl (ntohl (ip_v4addr (ip )) | (0xffffffff >>ip_bits (ip )));
369+
327370/* int addr = htonl(ip_v4addr(ip) | (0xffffffff >> ip_bits(ip))); */
328371
329372if (inet_net_ntop (AF_INET ,& addr ,32 ,tmp ,sizeof (tmp ))< 0 )
@@ -352,6 +395,45 @@ inet_broadcast(inet *ip)
352395return (ret );
353396}
354397
398+ text *
399+ inet_netmask (inet * ip )
400+ {
401+ text * ret ;
402+ int len ;
403+ char * ptr ,
404+ tmp [sizeof ("255.255.255.255/32" )];
405+
406+ if (ip_family (ip )== AF_INET )
407+ {
408+ /* It's an IP V4 address: */
409+ int addr = htonl ((-1 << (32 - ip_bits (ip )))& 0xffffffff );
410+
411+ if (inet_net_ntop (AF_INET ,& addr ,32 ,tmp ,sizeof (tmp ))< 0 )
412+ {
413+ elog (ERROR ,"unable to print netmask (%s)" ,strerror (errno ));
414+ return (NULL );
415+ }
416+ }
417+ else
418+ {
419+ /* Go for an IPV6 address here, before faulting out: */
420+ elog (ERROR ,"unknown address family (%d)" ,ip_family (ip ));
421+ return (NULL );
422+ }
423+ if ((ptr = strchr (tmp ,'/' ))!= NULL )
424+ * ptr = 0 ;
425+ len = VARHDRSZ + strlen (tmp );
426+ ret = palloc (len );
427+ if (ret == NULL )
428+ {
429+ elog (ERROR ,"unable to allocate memory in inet_netmask()" );
430+ return (NULL );
431+ }
432+ VARSIZE (ret )= len ;
433+ strcpy (VARDATA (ret ),tmp );
434+ return (ret );
435+ }
436+
355437/*
356438 *Bitwise comparison for V4 addresses. Add V6 implementation!
357439 */
@@ -372,4 +454,3 @@ v4bitncmp(unsigned int a1, unsigned int a2, int bits)
372454return (1 );
373455return (0 );
374456}
375-