aboutsummaryrefslogtreecommitdiff
path: root/contrib/ip_and_mac/ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ip_and_mac/ip.c')
-rw-r--r--contrib/ip_and_mac/ip.c231
1 files changed, 211 insertions, 20 deletions
diff --git a/contrib/ip_and_mac/ip.c b/contrib/ip_and_mac/ip.c
index b0320bae38d..e9aaba3b8e3 100644
--- a/contrib/ip_and_mac/ip.c
+++ b/contrib/ip_and_mac/ip.c
@@ -1,7 +1,7 @@
/*
* PostgreSQL type definitions for IP addresses.
*
- * $Id: ip.c,v 1.3 1998/02/26 04:27:37 momjian Exp $
+ * $Id: ip.c,v 1.4 1998/06/16 04:34:29 momjian Exp $
*/
#include <stdio.h>
@@ -81,10 +81,18 @@ ipaddr_in(char *str)
elog(ERROR, "ipaddr_in: error in parsing \"%s\"", str);
return (NULL);
}
-
+ if ( count == 3 ) {
+ d = 0;
+ count = 4;
+ };
if (count == 4)
+ {
w = 32;
-
+ if ( a >= 192 && a < 224 && d == 0 ) w = 24;
+ if ( a >= 128 && a < 192 && d == 0 && c == 0 ) w = 16;
+ if ( a > 0 && a < 128 && c == 0 && b == 0 && a < 128 ) w = 8;
+ if ( a == 0 && b == 0 && c == 0 && d == 0 ) w = 0;
+ };
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
(w < 0) || (w > 32))
@@ -95,13 +103,12 @@ ipaddr_in(char *str)
}
else
{
- a = b = c = d = w = 0; /* special case for missing address */
+ a = b = c = d = w = 255; /* special case for missing address */
}
result = (ipaddr *) palloc(sizeof(ipaddr));
result->address = (uint32) ((a << 24) | (b << 16) | (c << 8) | d);
- result->address &= build_mask(w);
result->width = w;
return (result);
@@ -116,27 +123,30 @@ char *
ipaddr_out(ipaddr * addr)
{
char *result;
-
+ int a, b, c, d, w;
if (addr == NULL)
return (NULL);
result = (char *) palloc(32);
- if (addr->address > 0)
+ w = addr->width;
+ a = (addr->address >> 24) & 0xff;
+ b = (addr->address >> 16) & 0xff;
+ c = (addr->address >> 8) & 0xff;
+ d = (addr->address >> 0) & 0xff;
+ /* Check by missing address (w > 32 ) */
+ if ( w >= 0 && w <= 32 )
{
- if (addr->width == 32)
- sprintf(result, "%d.%d.%d.%d",
- (addr->address >> 24) & 0xff,
- (addr->address >> 16) & 0xff,
- (addr->address >> 8) & 0xff,
- addr->address & 0xff);
+ /* In case of NATURAL network don't output the prefix */
+ if ( (a == 0 && b == 0 && c == 0 && d == 0 && w == 0 ) ||
+ (a < 128 && b == 0 && c == 0 && d == 0 && w == 8 ) ||
+ (a < 192 && c == 0 && d == 0 && w == 16 ) ||
+ (a < 224 && d == 0 && w == 24 ) ||
+ ( d != 0 ) ) w = -1;
+ if (w == -1 )
+ sprintf(result, "%d.%d.%d.%d",a,b,c,d);
else
- sprintf(result, "%d.%d.%d.%d/%d",
- (addr->address >> 24) & 0xff,
- (addr->address >> 16) & 0xff,
- (addr->address >> 8) & 0xff,
- addr->address & 0xff,
- addr->width);
+ sprintf(result, "%d.%d.%d.%d/%d",a,b,c,d,w);
}
else
{
@@ -146,42 +156,109 @@ ipaddr_out(ipaddr * addr)
}
/*
+ * Print ipaddr by format
+ * %A - address
+ * %M - maska
+ * %P - prefix
+ * %B - negated maska
+ */
+# define TXT_LEN_0 4
+text *
+ipaddr_print(ipaddr * addr, text *fmt)
+{
+ text *result;
+ char *p, *op;
+ uint32 aaa;
+ int a, b, c, d;
+ if (addr == NULL)
+ return (NULL);
+
+ result = (text *) palloc( sizeof(text) + 64 );
+
+ /* Check by missing address (w > 32 ) */
+ for ( p = fmt->vl_dat, op = result->vl_dat; *p && (p - fmt->vl_dat) < (fmt->vl_len - TXT_LEN_0) && (op - result->vl_dat) < 48; p++) {
+ if ( *p != '%' ) {
+ *op++ = *p;
+ continue;
+ };
+ p++;
+ if ( *p == 'A' )
+ {
+ aaa = addr->address;
+ goto pta;
+ };
+ if ( *p == 'M' ) {
+ aaa = build_mask(addr->width);
+ goto pta;
+ }
+ if ( *p == 'B' ) {
+ aaa = build_mask(32 - addr->width) >> addr->width;
+ goto pta;
+ }
+ if ( *p == 'P' ) {
+ sprintf(op,"%d",addr->width);
+ while ( *op) op++;
+ continue;
+ };
+ *op++ = *p;
+ continue;
+pta:
+ a = (aaa >> 24) & 0xff;
+ b = (aaa >> 16) & 0xff;
+ c = (aaa >> 8) & 0xff;
+ d = (aaa >> 0) & 0xff;
+ sprintf(op, "%d.%d.%d.%d",a,b,c,d);
+ while ( *op ) op++;
+ continue;
+ };
+ *op = 0;
+ result->vl_len = (op - result->vl_dat) + TXT_LEN_0;
+ return (result);
+}
+
+/*
* Boolean tests for magnitude.
*/
bool
ipaddr_lt(ipaddr * a1, ipaddr * a2)
{
+ if ( a1->address == a2->address ) return(a1->width < a2->width);
return (a1->address < a2->address);
};
bool
ipaddr_le(ipaddr * a1, ipaddr * a2)
{
+ if ( a1->address == a2->address ) return(a1->width <= a2->width);
return (a1->address <= a2->address);
};
bool
ipaddr_eq(ipaddr * a1, ipaddr * a2)
{
+ if ( a1->address == a2->address ) return(a1->width == a2->width);
return (a1->address == a2->address);
};
bool
ipaddr_ge(ipaddr * a1, ipaddr * a2)
{
+ if ( a1->address == a2->address ) return(a1->width >= a2->width);
return (a1->address >= a2->address);
};
bool
ipaddr_gt(ipaddr * a1, ipaddr * a2)
{
+ if ( a1->address == a2->address ) return(a1->width > a2->width);
return (a1->address > a2->address);
};
bool
ipaddr_ne(ipaddr * a1, ipaddr * a2)
{
+ if ( a1->address == a2->address ) return(a1->width != a2->width);
return (a1->address != a2->address);
};
@@ -197,7 +274,42 @@ ipaddr_cmp(ipaddr * a1, ipaddr * a2)
else if (a1->address > a2->address)
return 1;
else
- return 0;
+ {
+ if (a1->width < a2->width)
+ return -1;
+ else if (a1->width > a2->width)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * The number of hosts in the network
+ */
+int4
+ipaddr_len(ipaddr * a)
+{
+ if ( a->width > 32 || a->width < 0 ) return(0);
+ return(1 << (32 - a->width));
+}
+
+/*
+ * The number of network bits
+ */
+int4
+ipaddr_pref(ipaddr * a)
+{
+ if ( a->width > 32 || a->width < 0 ) return(0);
+ return(a->width);
+}
+
+/*
+ * The host addr as an integer
+ */
+int4
+ipaddr_integer(ipaddr * a)
+{
+ return(a->address);
}
/*
@@ -220,6 +332,23 @@ ipaddr_in_net(ipaddr * a1, ipaddr * a2)
}
/*
+ * Test whether an address is the network or a host in the network:
+ */
+
+bool
+ipaddr_is_net(ipaddr * a)
+{
+ uint32 maskbits;
+
+ if (a->width == 32)
+ return FALSE;
+ maskbits = build_mask(a->width);
+ if ( (a->address & maskbits) == a->address )
+ return TRUE;
+ return FALSE;
+}
+
+/*
* Pick out just the mask of a network:
*/
@@ -253,5 +382,67 @@ ipaddr_bcast(ipaddr * a)
}
/*
+ * Return the base network of the address/network:
+ */
+
+ipaddr *
+ipaddr_net(ipaddr * a)
+{
+ ipaddr *result;
+
+ result = (ipaddr *) palloc(sizeof(ipaddr));
+ result->address = a->address;
+ result->address &= build_mask(a->width);
+ result->width = a->width;
+
+ return result;
+}
+
+/*
+ * Compose ipaddr from ADDR and PREFIX
+ */
+ipaddr *
+ipaddr_compose(int4 addr, int4 pref)
+{
+ ipaddr *result;
+
+ result = (ipaddr *) palloc(sizeof(ipaddr));
+ if ( pref < 0 || pref > 32 ) {
+ pref = 255;
+ addr = 0;
+ };
+ result->address = addr;
+ result->width = pref;
+ return result;
+}
+
+/*
+ * Plus and Minus operators
+ */
+ipaddr *
+ipaddr_plus(ipaddr * a, int4 i)
+{
+ ipaddr *result;
+
+ result = (ipaddr *) palloc(sizeof(ipaddr));
+ result->address = a->address + i;
+ result->width = a->width;
+
+ return result;
+}
+
+ipaddr *
+ipaddr_minus(ipaddr * a, int4 i)
+{
+ ipaddr *result;
+
+ result = (ipaddr *) palloc(sizeof(ipaddr));
+ result->address = a->address - i;
+ result->width = a->width;
+
+ return result;
+}
+
+/*
* eof
*/