Commit 29251149 authored by Bruce Momjian's avatar Bruce Momjian

try again

parent 92da1c3a
#
# PostgreSQL types for IP and MAC addresses
#
# $Id: Makefile,v 1.4 1998/06/16 04:34:29 momjian Exp $
# $Id: Makefile,v 1.5 1998/06/16 05:35:10 momjian Exp $
all: ip.so mac.so
......@@ -18,7 +18,7 @@ mac.o: mac.c mac.h
cc -g -O -fPIC -I/usr/local/pgsql/include -c mac.c
install: ip.so mac.so
install -c ip.so mac.so /usr/local/pgsql/modules
install -c ip.so mac.so /usr/local/pgsql/contrib/ip_and_macs
clean:
rm -f *.o *.so *.b
......
......@@ -5,8 +5,8 @@ written by (Bergen, Norway, 1998-01-31, Tom Ivar Helbekkmo
rewritten by me (alex@relcom.EU.net, Aleksei Roudnev, Moscow, Russia,
25.05.98) and written first by Bergen.
To see the description of macaddr type, read README.ORIG file.
To see the description of ipaddr type, read ipaddr.html file.
To see the description of macaddr type, read README.ORIG file. To see
the description of ipaddr type, read ipaddr.html file.
^^^^^^^^^^^
This ipaddr type differ slightly from the original one. First, if you
......
PostgreSQL type extensions for IP and MAC addresses.
---------------------------------------------------
$Id: README.ORIG,v 1.1 1998/06/16 04:34:29 momjian Exp $
$Id: README.ORIG,v 1.2 1998/06/16 05:35:10 momjian Exp $
I needed to record IP and MAC level ethernet addresses in a data
base, and I really didn't want to store them as plain strings, with
......
/*
* PostgreSQL type definitions for IP addresses.
*
* $Id: ip.c,v 1.4 1998/06/16 04:34:29 momjian Exp $
* $Id: ip.c,v 1.5 1998/06/16 05:35:10 momjian Exp $
*/
#include <stdio.h>
......
--
-- PostgreSQL code for IP addresses.
--
-- $Id: ip.sql,v 1.4 1998/06/16 04:34:30 momjian Exp $
-- $Id: ip.sql,v 1.5 1998/06/16 05:35:10 momjian Exp $
-- Invoced from 1998/02/14 17:58:04 scrappy
--
-- New - INPUT/OUTPUT, functions, indexing by btree, test.
-- PART # 1 - ip.sql - load new type, functions and operators.
-- Then you should execute ipi.sql - add ipaddr_ops class to allow indexing.
load '/usr/local/pgsql/modules/ip.so';
load '/usr/local/pgsql/contrib/ip_and_macs/ip.so';
--
-- Input and output functions and the type itself:
......@@ -20,14 +20,14 @@ load '/usr/local/pgsql/modules/ip.so';
create function ipaddr_in(opaque)
returns opaque
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
create function ipaddr_out(opaque)
returns opaque
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
create type ipaddr (
......@@ -46,7 +46,7 @@ create type ipaddr (
drop function ipaddr_print;
create function ipaddr_print(ipaddr, text)
returns text
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
);
......@@ -58,32 +58,32 @@ create function ipaddr_print(ipaddr, text)
create function ipaddr_lt(ipaddr, ipaddr)
returns bool
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
create function ipaddr_le(ipaddr, ipaddr)
returns bool
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
create function ipaddr_eq(ipaddr, ipaddr)
returns bool
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
create function ipaddr_ge(ipaddr, ipaddr)
returns bool
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
create function ipaddr_gt(ipaddr, ipaddr)
returns bool
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
create function ipaddr_ne(ipaddr, ipaddr)
returns bool
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -92,7 +92,7 @@ create function ipaddr_ne(ipaddr, ipaddr)
--
create function ipaddr_in_net(ipaddr, ipaddr)
returns bool
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -104,7 +104,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_net(ipaddr)
returns ipaddr
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -114,7 +114,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_is_net(ipaddr)
returns boolean
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -123,7 +123,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_len(ipaddr)
returns int4
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -132,7 +132,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_pref(ipaddr)
returns int4
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -142,7 +142,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_integer(ipaddr)
returns int4
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -152,7 +152,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_compose(int4,int4)
returns ipaddr
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -161,7 +161,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_mask(ipaddr)
returns ipaddr
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -170,7 +170,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_bcast(ipaddr)
returns ipaddr
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -180,7 +180,7 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_cmp(ipaddr,ipaddr)
returns int4
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......@@ -189,12 +189,12 @@ create function ipaddr_in_net(ipaddr, ipaddr)
create function ipaddr_plus(ipaddr,int4)
returns ipaddr
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
create function ipaddr_minus(ipaddr,int4)
returns ipaddr
as '/usr/local/pgsql/modules/ip.so'
as '/usr/local/pgsql/contrib/ip_and_macs/ip.so'
language 'c';
--
......
--
-- PostgreSQL code for IP addresses.
--
-- $Id: ip.sql.in,v 1.1 1998/04/22 04:20:30 scrappy Exp $
--
load '_OBJWD_/ip_DLSUFFIX_';
--
-- Input and output functions and the type itself:
--
create function ipaddr_in(opaque)
returns opaque
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_out(opaque)
returns opaque
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create type ipaddr (
internallength = 6,
externallength = variable,
input = ipaddr_in,
output = ipaddr_out
);
--
-- The various boolean tests:
--
create function ipaddr_lt(ipaddr, ipaddr)
returns bool
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_le(ipaddr, ipaddr)
returns bool
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_eq(ipaddr, ipaddr)
returns bool
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_ge(ipaddr, ipaddr)
returns bool
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_gt(ipaddr, ipaddr)
returns bool
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_ne(ipaddr, ipaddr)
returns bool
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_in_net(ipaddr, ipaddr)
returns bool
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_mask(ipaddr)
returns ipaddr
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
create function ipaddr_bcast(ipaddr)
returns ipaddr
as '_OBJWD_/ip_DLSUFFIX_'
language 'c';
--
-- Now the operators. Note how some of the parameters to some
-- of the 'create operator' commands are commented out. This
-- is because they reference as yet undefined operators, and
-- will be implicitly defined when those are, further down.
--
create operator < (
leftarg = ipaddr,
rightarg = ipaddr,
-- negator = >=,
procedure = ipaddr_lt
);
create operator <= (
leftarg = ipaddr,
rightarg = ipaddr,
-- negator = >,
procedure = ipaddr_le
);
create operator = (
leftarg = ipaddr,
rightarg = ipaddr,
commutator = =,
-- negator = <>,
procedure = ipaddr_eq
);
create operator >= (
leftarg = ipaddr,
rightarg = ipaddr,
negator = <,
procedure = ipaddr_ge
);
create operator > (
leftarg = ipaddr,
rightarg = ipaddr,
negator = <=,
procedure = ipaddr_gt
);
create operator <> (
leftarg = ipaddr,
rightarg = ipaddr,
negator = =,
procedure = ipaddr_ne
);
--
-- eof
--
/*
* PostgreSQL type definitions for IP addresses.
*
* $Id: ip_orig.c,v 1.1 1998/06/16 05:35:11 momjian Exp $
*/
#include <stdio.h>
#include <postgres.h>
#include <utils/palloc.h>
/*
* This is the internal storage format for IP addresses:
*/
typedef struct ipaddr
{
uint32 address;
int16 width;
} ipaddr;
/*
* Various forward declarations:
*/
ipaddr *ipaddr_in(char *str);
char *ipaddr_out(ipaddr * addr);
bool ipaddr_lt(ipaddr * a1, ipaddr * a2);
bool ipaddr_le(ipaddr * a1, ipaddr * a2);
bool ipaddr_eq(ipaddr * a1, ipaddr * a2);
bool ipaddr_ge(ipaddr * a1, ipaddr * a2);
bool ipaddr_gt(ipaddr * a1, ipaddr * a2);
bool ipaddr_ne(ipaddr * a1, ipaddr * a2);
int4 ipaddr_cmp(ipaddr * a1, ipaddr * a2);
bool ipaddr_in_net(ipaddr * a1, ipaddr * a2);
ipaddr *ipaddr_mask(ipaddr * a);
ipaddr *ipaddr_bcast(ipaddr * a);
/*
* Build a mask of a given width:
*/
unsigned long
build_mask(unsigned char bits)
{
unsigned long mask = 0;
int i;
for (i = 0; i < bits; i++)
mask = (mask >> 1) | 0x80000000;
return mask;
}
/*
* IP address reader. Note how the count returned by sscanf()
* is used to determine whether the mask size was specified.
*/
ipaddr *
ipaddr_in(char *str)
{
int a,
b,
c,
d,
w;
ipaddr *result;
int count;
if (strlen(str) > 0)
{
count = sscanf(str, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &w);
if (count < 4)
{
elog(ERROR, "ipaddr_in: error in parsing \"%s\"", str);
return (NULL);
}
if (count == 4)
w = 32;
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
(w < 0) || (w > 32))
{
elog(ERROR, "ipaddr_in: illegal address \"%s\"", str);
return (NULL);
}
}
else
{
a = b = c = d = w = 0; /* 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);
}
/*
* IP address output function. Note mask size specification
* generated only for subnets, not for plain host addresses.
*/
char *
ipaddr_out(ipaddr * addr)
{
char *result;
if (addr == NULL)
return (NULL);
result = (char *) palloc(32);
if (addr->address > 0)
{
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);
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);
}
else
{
result[0] = 0; /* special case for missing address */
}
return (result);
}
/*
* Boolean tests for magnitude.
*/
bool
ipaddr_lt(ipaddr * a1, ipaddr * a2)
{
return (a1->address < a2->address);
};
bool
ipaddr_le(ipaddr * a1, ipaddr * a2)
{
return (a1->address <= a2->address);
};
bool
ipaddr_eq(ipaddr * a1, ipaddr * a2)
{
return (a1->address == a2->address);
};
bool
ipaddr_ge(ipaddr * a1, ipaddr * a2)
{
return (a1->address >= a2->address);
};
bool
ipaddr_gt(ipaddr * a1, ipaddr * a2)
{
return (a1->address > a2->address);
};
bool
ipaddr_ne(ipaddr * a1, ipaddr * a2)
{
return (a1->address != a2->address);
};
/*
* Comparison function for sorting:
*/
int4
ipaddr_cmp(ipaddr * a1, ipaddr * a2)
{
if (a1->address < a2->address)
return -1;
else if (a1->address > a2->address)
return 1;
else
return 0;
}
/*
* Test whether an address is within a given subnet:
*/
bool
ipaddr_in_net(ipaddr * a1, ipaddr * a2)
{
uint32 maskbits;
if (a1->width < a2->width)
return FALSE;
if ((a1->width == 32) && (a2->width == 32))
return ipaddr_eq(a1, a2);
maskbits = build_mask(a2->width);
if ((a1->address & maskbits) == (a2->address & maskbits))
return TRUE;
return FALSE;
}
/*
* Pick out just the mask of a network:
*/
ipaddr *
ipaddr_mask(ipaddr * a)
{
ipaddr *result;
result = (ipaddr *) palloc(sizeof(ipaddr));
result->address = build_mask(a->width);
result->width = 32;
return result;
}
/*
* Return the broadcast address of a network:
*/
ipaddr *
ipaddr_bcast(ipaddr * a)
{
ipaddr *result;
result = (ipaddr *) palloc(sizeof(ipaddr));
result->address = a->address;
result->address |= (build_mask(32 - a->width) >> a->width);
result->width = 32;
return result;
}
/*
* eof
*/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.04Gold (X11; I; FreeBSD 2.2.5-RELEASE i386) [Netscape]">
</HEAD>
<BODY>
<H2>New object class for the IP ADDRESSES manipulations.</H2>
<H3>1. Description:</H3>
<UL>
<P>Type name: <B>ipaddr<BR>
</B>Data lenght: <B>6 bytes<BR>
</B>Data context: <B>ip address and prefix length</B></P>
</UL>
<H3><B>2. How to install:</B></H3>
<UL>
<P>Use script <B>ip.sql </B>to add new type, new functions and operators
to the data base.</P>
<P>Use script <B>ipi.sql </B>to add new type and new operator class ipaddr_ops
to the index system and allow indexing by this new type (with search by
'<B>&gt;</B>', '<B>&gt;=</B>', '<B>&lt;</B>', '<B>&lt;=</B>', '<B>=</B>'
boolean operators).</P>
<P>Use scripts '<B>test1.sql'</B> and '<B>test2.sql'</B> (edit second script
first) to check if indexing work properly.</P>
</UL>
<H3>3. Input / output formsts.</H3>
<P>New type stores IP address and IP prefix in the single data attribute.
To input data, you should use the form</P>
<UL>
<P><B><I>DDD</I>.<I>DDD</I>.<I>DDD</I>.<I>DDD</I>/<I>P</I>P</B></P>
</UL>
<P>for the address <B>DDD.DDD.DDD.DDD</B> and prefix <B>PP</B> (prefix
is len from 0 (for 0.0.0.0) to 32 (for 255.255.255.255)). You can miss
/PP n two cases:</P>
<UL>
<LI>You enter host address (this means /32 prefix) and this is not the
address of the natural class A, B or C network.</LI>
<LI>You enter natural class A, B, C network with the /8, /16 and /24 prefix.</LI>
</UL>
<P>For example, <B>193.124.23.0</B> should be read as '<B>193.124.23.0/24</B>'
network, and '<B>193.124.23.1</B>' should be read as <B>/32 </B>host address.
To enter interface address <B>193.124.23.6/24</B>, you should use exact
form '<B>193.124.23.6/24'</B>.</P>
<P>The address '0.0.0.0' means '0.0.0.0/0', this is <B>default</B> in terms
of routers.</P>
<P><B>ipaddr</B> type data are printed just in the same form (to allow
input/output compatibility) - <B>193.124.23.0/24</B> should be printed
as '<B>193.124.23.0</B>' and '<B>193.124.23.1/32</B>' should be printed
as '<B>193.124.23.1</B>'.</P>
<P>There is special function to convert ipaddr data into string by the
format:</P>
<UL>
<P>char ipaddr_print(ipaddr,format)</P>
</UL>
<P>format consist of plain text and %C special characters:</P>
<UL>
<P><B>%A</B> - address in form ddd.ddd.ddd.ddd,<BR>
<B>%M </B>- network mask in form ddd.ddd.ddd.ddd,<BR>
<B>%B </B>- negated mask ('0.0.0.7' for '/29' prefix, for example),<BR>
<B>%P</B> - prefix (withouth '/' delimiter).</P>
</UL>
<H3>4. Operators.</H3>
<TABLE ALIGN=ABSCENTER BORDER=2 CELLSPACING=0 CELLPADDING=0 >
<TR>
<TD>Left argument<BR>
A1</TD>
<TD>Op</TD>
<TD>Right argument<BR>
A2</TD>
<TD>Result<BR>
R</TD>
<TD>Description</TD>
</TR>
<TR>
<TD>ipaddr</TD>
<TD>&lt;</TD>
<TD>ipaddr</TD>
<TD>boolean</TD>
<TD>Compare addresses, if they are equal, compare prefixes,</TD>
</TR>
<TR>
<TD>ipaddr</TD>
<TD>&lt;=</TD>
<TD>ipaddr</TD>
<TD>boolean</TD>
<TD>Compare addresses, if they are equal, compare prefixes,</TD>
</TR>
<TR>
<TD>ipaddr</TD>
<TD>=</TD>
<TD>ipaddr</TD>
<TD>boolean</TD>
<TD>Compare addresses, if they are equal, compare prefixes,</TD>
</TR>
<TR>
<TD>ipaddr</TD>
<TD>&gt;=</TD>
<TD>ipaddr</TD>
<TD>boolean</TD>
<TD>Compare addresses, if they are equal, compare prefixes,</TD>
</TR>
<TR>
<TD>ipaddr</TD>
<TD>&gt;</TD>
<TD>ipaddr</TD>
<TD>boolean</TD>
<TD>Compare addresses, if they are equal, compare prefixes,</TD>
</TR>
<TR>
<TD>ipaddr</TD>
<TD>&lt;&gt;</TD>
<TD>ipaddr</TD>
<TD>boolean</TD>
<TD>Compare addresses, if they are equal, compare prefixes,</TD>
</TR>
<TR>
<TD>ipaddr</TD>
<TD>@</TD>
<TD>ipaddr</TD>
<TD>boolean</TD>
<TD>True if A1 is the part of network (subnetwork) A2 or if A1 = A2</TD>
</TR>
<TR>
<TD>ipaddr</TD>
<TD>+</TD>
<TD>int4</TD>
<TD>ipaddr</TD>
<TD>Increase address A1 on A2 value (A2 is integer).</TD>
</TR>
<TR>
<TD>ipaddr </TD>
<TD>-</TD>
<TD>int4</TD>
<TD>ipaddr</TD>
<TD>Decrease address A1 on A2.</TD>
</TR>
</TABLE>
<H3>5. Functions.</H3>
<P>There is a lot of functions defined for new ipaddr data type. Some of
them are duplicated by operators described above, some are not. </P>
<TABLE ALIGN=ABSCENTER BORDER=2 CELLSPACING=0 CELLPADDING=0 >
<TR>
<TD>Function(arguments)</TD>
<TD>Function type</TD>
<TD>Description</TD>
<TD>Operator</TD>
</TR>
<TR>
<TD>ipaddr_print(ipaddr, text)</TD>
<TD>text</TD>
<TD>Converts ipaddr to the text string by format from the second argument.
Format can contain %A - address, %M - mask, %B - reversed mask, %P - prefix,
and any other characters.</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_lt(ipaddr, ipaddr)</TD>
<TD>boolean</TD>
<TD>Compare by '&lt;'</TD>
<TD>&lt;</TD>
</TR>
<TR>
<TD>ipaddr_le(ipaddr,ipaddr)</TD>
<TD>boolean</TD>
<TD>Compare by '&lt;='</TD>
<TD>&lt;=</TD>
</TR>
<TR>
<TD>ipaddr_eq(ipaddr, ipaddr)</TD>
<TD>boolean</TD>
<TD>Compare by '='</TD>
<TD>=</TD>
</TR>
<TR>
<TD>ipaddr_ne(ipaddr, ipaddr)</TD>
<TD>boolean</TD>
<TD>Compare by '&lt;&gt;'</TD>
<TD>&lt;&gt;</TD>
</TR>
<TR>
<TD>ipaddr_ge(ipaddr, ipaddr)</TD>
<TD>boolean</TD>
<TD>Compare by '&gt;='</TD>
<TD>&gt;=</TD>
</TR>
<TR>
<TD>ipaddr_gt(ipaddr, ipaddr)</TD>
<TD>boolean</TD>
<TD>Compare by '&gt;'</TD>
<TD>&gt;</TD>
</TR>
<TR>
<TD>ipaddr_in_net(ipaddr, ipaddr)</TD>
<TD>boolean</TD>
<TD><B>True</B> if fisrt argument is the host or subnetwork of the second
argument (first address is equal or included into the second one)</TD>
<TD>@</TD>
</TR>
<TR>
<TD>ipaddr_net(ipaddr)</TD>
<TD>ipaddr</TD>
<TD>Return the network (with the 0 in host bits) for the argument; for
example ipaddr_net('193.124.23.1/24') = '193.124.23.0';</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_bcast(ipaddr)</TD>
<TD>ipaddr</TD>
<TD>Return broadcast address (with the /32 prefix) for the network described
by argument.</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_is_net(ipaddr)</TD>
<TD>boolean</TD>
<TD><B>True</B> if ipaddr is network address; <B>false</B> if its' the
host in the network. For the /32 addresses, returns <B>false</B>.</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_mask(ipaddr)</TD>
<TD>ipaddr</TD>
<TD>Return netmask (with /32 prefix) for the network.</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_prefix(ipaddr)</TD>
<TD>int4</TD>
<TD>Return the prefix size (from 0 to 32).</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_len(ipaddr)</TD>
<TD>int4</TD>
<TD>Return the number of addresses in the particular network (for example,
256 for /24 prefix).</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_integer(ipaddr)</TD>
<TD>int4</TD>
<TD>Return IP address (withouth the prefix) as integer.</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_compose(int4,int4)</TD>
<TD>ipaddr</TD>
<TD>Compose ipaddr object from ip address (first argument) and prefix lenght
(second argument). ipaddr_compose(ipaddr_integer(a),ipaddr_prefix(a)) =
a.</TD>
<TD></TD>
</TR>
<TR>
<TD>ipaddr_plus(ipaddr, int4)</TD>
<TD>ipaddr</TD>
<TD>Operator PLUS (addres increased, prefix does not changed)</TD>
<TD>+</TD>
</TR>
<TR>
<TD>ipaddr_minus(ipaddr, int4)</TD>
<TD>ipaddr</TD>
<TD>Operator MINUS (address decreased, prefix does not changed).</TD>
<TD>-</TD>
</TR>
<TR>
<TD>ipaddr_cmp(ipaddr, ipaddr)</TD>
<TD>int4</TD>
<TD>Compare it's arguments and return -1, 0 or +1.</TD>
<TD></TD>
</TR>
</TABLE>
<H3>5. Usage.</H3>
<P>New type opens many interesting futures for the ip routing or ip accounting
networks. For example, you can search all interfaces connected to the same
phisical network by comparing ipaddr_net(interface_address) /if you store
address as address/prefix pair in the single attribute, and so on.</P>
<P>Unfortunately, I had not time (and was not too familiar with RTree ideas
used in Postgres) to check if it's possible to use RTree indexing for the
fast routing lookups by data base. It's important task because usial usage
of this future is _determine the nearest network the particular address
contain to, and link the accounting record to this network_. And so on.</P>
<P>Write any questions or wishes to me by e-mail. This is BETA version
of this package for now, because we are building our IP routing data base
just now and did not tested all this fucntions under heavy conditions;
through I hope this functions are too simple for the hidden bugs, and they
was tested carefully at the simple tests.</P>
<H3>6. Installation.</H3>
<OL>
<LI>Translate shared library ip.so:<BR>
make</LI>
<LI>Install shared library to the proper place (/usr/local/pgsql/contrib/ip_and_macs)<BR>
make install<BR>
(in case if your system is not FreeBSD, it can be nessesary modify 'Makefile'
before).</LI>
<LI>Public to the accessible place scripts ip.sql (installation of data
type), ipi.sql (describing of this data type for the proper indexing),
test1.sql, test2.sql, test.DATA (test and data). Modify test1.sql in accordance
to real location of the data files.</LI>
<LI>To add new data type into your data base, exec scripts in this data
base:<BR>
psql DATA_BASE<BR>
\i ip.sql -- change this to the real location<BR>
\i ipi.sql -- change this to the real location</LI>
<LI>To test this data type, exec test1.sql and test2.sql SQL scripts.</LI>
</OL>
<H3>7. Download.</H3>
<P>You can download this data type from <B>http://relcom.EU.net/ip_class.tar.gz</B></P>
<H3><BR>
</H3>
<P>
<HR WIDTH="100%"></P>
<P>Aleksei Roudnev, The Network Operation Centre, Relcom Network; Moscow,
Russia.</P>
<UL><B></B></UL>
<UL></UL>
</BODY>
</HTML>
begin;
select pgam.oid from pg_am pgam
where amname = 'btree';
--
-- Temporary oper table
--
-- drop table tmp_op;
create table tmp_op ( oprname name, opi int2);
--
-- Fill in this table
--
insert into tmp_op values('<','1');
insert into tmp_op values('<=','2');
insert into tmp_op values('=','3');
insert into tmp_op values('>=','4');
insert into tmp_op values('>','5');
select * from tmp_op;
--
-- Add record to the pg_opclass
--
DELETE FROM pg_opclass WHERE opcname = 'ipaddr_ops';
INSERT INTO pg_opclass (opcname,opcdeftype)
select 'ipaddr_ops',oid from pg_type where typname = 'ipaddr';
--
-- And determine oid
--
SELECT opc.oid,opc.opcname
FROM pg_opclass opc
WHERE opc.opcname = 'ipaddr_ops';
--
SELECT o.oid AS opoid, o.oprname
INTO TABLE ipaddr_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid and t.typname = 'ipaddr';
SELECT * FROM ipaddr_tmp;
--
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy, amopselect, amopnpages)
SELECT am.oid,opcl.oid,c.opoid,t.opi,'btreesel'::regproc, 'btreenpage'::regproc
FROM pg_am am, pg_opclass opcl, ipaddr_tmp c, tmp_op t
WHERE t.oprname = c.oprname
and amname = 'btree'
and opcname = 'ipaddr_ops';
--
SELECT prc.oid, prc.proname FROM pg_proc prc
WHERE prc.proname = 'ipaddr_cmp';
--
INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
SELECT pgam.oid, opc.oid,prc.oid,'1'::int2
FROM pg_am pgam,
pg_opclass opc,
pg_proc prc
WHERE prc.proname = 'ipaddr_cmp'
and pgam.amname = 'btree'
and opc.opcname = 'ipaddr_ops';
drop table tmp_op;
DROP TABLE ipaddr_tmp;
COMMIT;
-- *****************************************************************
-- * Now you should test this by running test1.sql and test2.sql *
-- * In test2, be sure the 'explain' operator show you *
-- * search by index in the last line of output *
-- *****************************************************************
--
-- PostgreSQL code for MAC addresses.
--
-- $Id: mac.sql.in,v 1.1 1998/04/22 04:20:36 scrappy Exp $
-- $Id: mac.sql,v 1.4 1998/06/16 05:35:11 momjian Exp $
--
load '_OBJWD_/mac_DLSUFFIX_';
load '/usr/local/pgsql/contrib/ip_and_macs/mac.so';
--
-- Input and output functions and the type itself:
......@@ -12,12 +12,12 @@ load '_OBJWD_/mac_DLSUFFIX_';
create function macaddr_in(opaque)
returns opaque
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
create function macaddr_out(opaque)
returns opaque
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
create type macaddr (
......@@ -33,32 +33,32 @@ create type macaddr (
create function macaddr_lt(macaddr, macaddr)
returns bool
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
create function macaddr_le(macaddr, macaddr)
returns bool
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
create function macaddr_eq(macaddr, macaddr)
returns bool
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
create function macaddr_ge(macaddr, macaddr)
returns bool
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
create function macaddr_gt(macaddr, macaddr)
returns bool
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
create function macaddr_ne(macaddr, macaddr)
returns bool
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
--
......@@ -117,7 +117,7 @@ create operator <> (
create function macaddr_manuf(macaddr)
returns text
as '_OBJWD_/mac_DLSUFFIX_'
as '/usr/local/pgsql/contrib/ip_and_macs/mac.so'
language 'c';
--
......
insert into xx values('193.124.23.2','host2');
insert into xx values('193.124.23.3','host3');
insert into xx values('193.124.22.1','host4');
insert into xx values('193.124.22.2','host5');
insert into xx values('193.124.22.3','host6');
This diff is collapsed.
--
-- A quick test of the IP address code
--
-- $Id: test.sql,v 1.1 1998/02/14 17:58:09 scrappy Exp $
--
-- $Id: test.sql,v 1.2 1998/06/16 05:35:12 momjian Exp $
-- This is original test (it was written before my changes in this class). alex.
-- temporary table:
create table addresses (address ipaddr);
......
drop table stat_t;
create table stat_t(i1 ipaddr, i2 ipaddr, p int4, b int4);
create index stat_i1 on stat_t using btree (i1 ipaddr_ops);
create index stat_i2 on stat_t using btree (i2 ipaddr_ops);
copy stat_t from '/v/noc/src/ip_class/test.DATA' using delimiters ' ';
--
-- Please, check if your test data are not in /v/noc/src/ip_class/test.DATA file,
-- edit test1.sql file and repeatr it.
--
-- If everything is OK, you should run test2.sql now
--
vacuum verbose analyze stat_t (i1,i2);
--
--
select i2,sum(b) as b
into tmp
from stat_t
where i1 >= '144.206.0.0' and i1 <= '144.206.255.255'
group by i2;
insert into tmp
select '0.0.0.0' as i2,sum(b) as k
from tmp
where b < 10 * 1024;
delete from tmp
where b < 10 * 1024 and i2 <> '0.0.0.0';
select i2,b / 1024 as k from tmp
order by k desc;
select ipaddr_print(i2,'%A/%P'),b from tmp where i2 = '0.0.0.0';
drop table tmp;
explain select i2,sum(b) as b
into tmp
from stat_t
where i1 >= '144.206.0.0' and i1 <= '144.206.255.255'
group by i2;
-- ********************************************************
-- * Now remove test table by 'drop table stat_t' command *
-- ********************************************************
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment