Adjust INET/CIDR display conventions and reimplement some INET/CIDR
functions, per recent discussions on pghackers. For now, I have called the verbose-display formatting function text(), but will reconsider if enough people object. initdb forced.
This commit is contained in:
parent
d7f8ffa781
commit
a210023008
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.38 2000/10/04 15:47:45 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.39 2000/11/10 20:13:25 tgl Exp $
|
||||
-->
|
||||
|
||||
<chapter id="datatype">
|
||||
@ -65,7 +65,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.38 2000/10/04 15:47:45 pe
|
||||
<row>
|
||||
<entry>cidr</entry>
|
||||
<entry></entry>
|
||||
<entry>IP version 4 network or host address</entry>
|
||||
<entry>IP network address</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>circle</entry>
|
||||
@ -95,7 +95,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.38 2000/10/04 15:47:45 pe
|
||||
<row>
|
||||
<entry>inet</entry>
|
||||
<entry></entry>
|
||||
<entry>IP version 4 network or host address</entry>
|
||||
<entry>IP network or host address</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>int2</entry>
|
||||
@ -1736,7 +1736,7 @@ January 8 04:05:06 1999 PST
|
||||
|
||||
<para>
|
||||
<productname>Postgres</> offers data types to store IP and MAC
|
||||
addresses. It is preferrable to use these types over plain text
|
||||
addresses. It is preferable to use these types over plain text
|
||||
types, because these types offer input error checking and several
|
||||
specialized operators and functions.
|
||||
|
||||
@ -1755,16 +1755,16 @@ January 8 04:05:06 1999 PST
|
||||
|
||||
<row>
|
||||
<entry>cidr</entry>
|
||||
<entry>11 bytes</entry>
|
||||
<entry>12 bytes</entry>
|
||||
<entry>IP networks</entry>
|
||||
<entry>valid IPv4 networks</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>inet</entry>
|
||||
<entry>11 bytes</entry>
|
||||
<entry>12 bytes</entry>
|
||||
<entry>IP hosts and networks</entry>
|
||||
<entry>valid IPv4 hosts</entry>
|
||||
<entry>valid IPv4 hosts or networks</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
@ -1784,19 +1784,48 @@ January 8 04:05:06 1999 PST
|
||||
</para>
|
||||
|
||||
|
||||
<sect2 id="inet-type">
|
||||
<title><type>inet</type></title>
|
||||
|
||||
<para>
|
||||
The <type>inet</type> type holds an IP host address, and
|
||||
optionally the identity of the subnet it is in, all in one field.
|
||||
The subnet identity is represented by the number of bits in the
|
||||
network part of the address (the "netmask"). If the netmask is 32,
|
||||
then the value does not indicate a subnet, only a single host.
|
||||
Note that if you want to accept networks only, you should use the
|
||||
<type>cidr</type> type rather than <type>inet</type>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The input format for this type is <replaceable
|
||||
class="parameter">x.x.x.x/y</replaceable> where <replaceable
|
||||
class="parameter">x.x.x.x</replaceable> is an IP address and
|
||||
<replaceable class="parameter">y</replaceable> is the number of
|
||||
bits in the netmask. If the <replaceable
|
||||
class="parameter">y</replaceable> part is left off, then the
|
||||
netmask is 32, and the value represents just a single host.
|
||||
On display, the <replaceable class="parameter">/y</replaceable>
|
||||
portion is suppressed if the netmask is 32.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="cidr-type">
|
||||
<title><type>cidr</></title>
|
||||
|
||||
<para>
|
||||
The <type>cidr</type> type holds an IP network. The format for
|
||||
The <type>cidr</type> type holds an IP network specification.
|
||||
Input and output formats follow Classless Internet Domain Routing
|
||||
conventions.
|
||||
The format for
|
||||
specifying classless networks is <replaceable
|
||||
class="parameter">x.x.x.x/y</> where <replaceable
|
||||
class="parameter">x.x.x.x</> is the network and <replaceable
|
||||
class="parameter">y</> is the number of bits in the netmask. If
|
||||
<replaceable class="parameter">y</> omitted, it is calculated
|
||||
using assumptions from the older classfull naming system except
|
||||
that it is extended to include at least all of the octets in the
|
||||
input.
|
||||
using assumptions from the older classful numbering system, except
|
||||
that it will be at least large enough to include all of the octets
|
||||
written in the input.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -1816,6 +1845,10 @@ January 8 04:05:06 1999 PST
|
||||
<entry>192.168.100.128/25</entry>
|
||||
<entry>192.168.100.128/25</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>192.168/24</entry>
|
||||
<entry>192.168.0/24</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>192.168/25</entry>
|
||||
<entry>192.168.0.0/25</entry>
|
||||
@ -1856,30 +1889,19 @@ January 8 04:05:06 1999 PST
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="inet-type">
|
||||
<title><type>inet</type></title>
|
||||
|
||||
<para>
|
||||
The <type>inet</type> type holds an IP host address, and
|
||||
optionally the identity of the subnet it is in, all in one field.
|
||||
Note that if you want to store networks only, you should use the
|
||||
<type>cidr</type> type. The <type>inet</type> type is similar to
|
||||
the <type>cidr</type> type except that the bits in the host part
|
||||
can be non-zero. Functions exist to extract the various elements
|
||||
of the field.
|
||||
</para>
|
||||
The essential difference between <type>inet</type> and <type>cidr</type>
|
||||
data types is that <type>inet</type> accepts values with nonzero bits to
|
||||
the right of the netmask, whereas <type>cidr</type> does not.
|
||||
|
||||
<para>
|
||||
The input format for this type is <replaceable
|
||||
class="parameter">x.x.x.x/y</replaceable> where <replaceable
|
||||
class="parameter">x.x.x.x</replaceable> is an internet host and
|
||||
<replaceable class="parameter">y</replaceable> is the number of
|
||||
bits in the netmask. If the <replaceable
|
||||
class="parameter">y</replaceable> part is left off, then the
|
||||
netmask is 32 and you are effectively only storing the address of
|
||||
a single host.
|
||||
<tip>
|
||||
<para>
|
||||
If you do not like the output format for <type>inet</type> or
|
||||
<type>cidr</type> values, try the <function>host</>() and
|
||||
<function>text</>() functions.
|
||||
</para>
|
||||
</tip>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
|
@ -1480,62 +1480,98 @@ Not defined by this name. Implements the intersection operator '#'
|
||||
<para>
|
||||
<table tocentry="1" id="cidr-inet-functions">
|
||||
<title><type>cidr</> and <type>inet</> Functions</title>
|
||||
<tgroup cols="4">
|
||||
<tgroup cols="5">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Function</entry>
|
||||
<entry>Returns</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Example</entry>
|
||||
<entry>Result</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>broadcast(cidr)</entry>
|
||||
<entry>text</entry>
|
||||
<entry>construct broadcast address as text</entry>
|
||||
<entry>broadcast('192.168.1.5/24')</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>broadcast(inet)</entry>
|
||||
<entry>text</entry>
|
||||
<entry>construct broadcast address as text</entry>
|
||||
<entry>inet</entry>
|
||||
<entry>broadcast address for network</entry>
|
||||
<entry>broadcast('192.168.1.5/24')</entry>
|
||||
<entry>192.168.1.255/24</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>host(inet)</entry>
|
||||
<entry>text</entry>
|
||||
<entry>extract host address as text</entry>
|
||||
<entry>extract IP address as text</entry>
|
||||
<entry>host('192.168.1.5/24')</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>masklen(cidr)</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>calculate netmask length</entry>
|
||||
<entry>masklen('192.168.1.5/24')</entry>
|
||||
<entry>192.168.1.5</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>masklen(inet)</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>calculate netmask length</entry>
|
||||
<entry>extract netmask length</entry>
|
||||
<entry>masklen('192.168.1.5/24')</entry>
|
||||
<entry>24</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>netmask(inet)</entry>
|
||||
<entry>text</entry>
|
||||
<entry>construct netmask as text</entry>
|
||||
<entry>inet</entry>
|
||||
<entry>construct netmask for network</entry>
|
||||
<entry>netmask('192.168.1.5/24')</entry>
|
||||
<entry>255.255.255.0</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>network(inet)</entry>
|
||||
<entry>cidr</entry>
|
||||
<entry>extract network part of address</entry>
|
||||
<entry>network('192.168.1.5/24')</entry>
|
||||
<entry>192.168.1/24</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>text(inet)</entry>
|
||||
<entry>text</entry>
|
||||
<entry>extract IP address and masklen as text</entry>
|
||||
<entry>text(inet '192.168.1.5')</entry>
|
||||
<entry>192.168.1.5/32</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All of the functions for <type>inet</type> can be applied to
|
||||
<type>cidr</type> values as well. The <function>host</>() and
|
||||
<function>text</>() functions are primarily intended to offer
|
||||
alternative display formats.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<table tocentry="1" id="macaddr-functions">
|
||||
<title><type>macaddr</> Functions</title>
|
||||
<tgroup cols="5">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Function</entry>
|
||||
<entry>Returns</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Example</entry>
|
||||
<entry>Result</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>trunc(macaddr)</entry>
|
||||
<entry>macaddr</entry>
|
||||
<entry>set last 3 bytes to zero</entry>
|
||||
<entry>trunc(macaddr '12:34:56:78:90:ab')</entry>
|
||||
<entry>12:34:56:00:00:00</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The function <function>trunc</>(<type>macaddr</>) returns a MAC
|
||||
address with the last 3 bytes set to 0. This can be used to
|
||||
associate the remaining prefix with a manufacturer. The directory
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/oper.sgml,v 1.21 2000/10/24 20:13:31 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/oper.sgml,v 1.22 2000/11/10 20:13:25 tgl Exp $
|
||||
-->
|
||||
|
||||
<Chapter Id="operators">
|
||||
@ -756,80 +756,11 @@ logical union
|
||||
<sect1 id="net-operators">
|
||||
<title>Network Address Type Operators</title>
|
||||
|
||||
<sect2 id="cidr-operators">
|
||||
<title><type>cidr</> Operators</title>
|
||||
<sect2 id="cidr-inet-operators">
|
||||
<title><type>cidr</> and <type>inet</> Operators</title>
|
||||
|
||||
<table tocentry="1" id="cidr-operators-table">
|
||||
<title><type>cidr</> Operators</title>
|
||||
<TGROUP COLS="3">
|
||||
<THEAD>
|
||||
<ROW>
|
||||
<ENTRY>Operator</ENTRY>
|
||||
<ENTRY>Description</ENTRY>
|
||||
<ENTRY>Usage</ENTRY>
|
||||
</ROW>
|
||||
</THEAD>
|
||||
<TBODY>
|
||||
<ROW>
|
||||
<ENTRY> < </ENTRY>
|
||||
<ENTRY>Less than</ENTRY>
|
||||
<ENTRY>'192.168.1.5'::cidr < '192.168.1.6'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> <= </ENTRY>
|
||||
<ENTRY>Less than or equal</ENTRY>
|
||||
<ENTRY>'192.168.1.5'::cidr <= '192.168.1.5'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> = </ENTRY>
|
||||
<ENTRY>Equals</ENTRY>
|
||||
<ENTRY>'192.168.1.5'::cidr = '192.168.1.5'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> >= </ENTRY>
|
||||
<ENTRY>Greater or equal</ENTRY>
|
||||
<ENTRY>'192.168.1.5'::cidr >= '192.168.1.5'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> > </ENTRY>
|
||||
<ENTRY>Greater</ENTRY>
|
||||
<ENTRY>'192.168.1.5'::cidr > '192.168.1.4'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> <> </ENTRY>
|
||||
<ENTRY>Not equal</ENTRY>
|
||||
<ENTRY>'192.168.1.5'::cidr <> '192.168.1.4'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> << </ENTRY>
|
||||
<ENTRY>is contained within</ENTRY>
|
||||
<ENTRY>'192.168.1.5'::cidr << '192.168.1/24'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> <<= </ENTRY>
|
||||
<ENTRY>is contained within or equals</ENTRY>
|
||||
<ENTRY>'192.168.1/24'::cidr <<= '192.168.1/24'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> >> </ENTRY>
|
||||
<ENTRY>contains</ENTRY>
|
||||
<ENTRY>'192.168.1/24'::cidr >> '192.168.1.5'::cidr</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY> >>= </ENTRY>
|
||||
<ENTRY>contains or equals</ENTRY>
|
||||
<ENTRY>'192.168.1/24'::cidr >>= '192.168.1/24'::cidr</ENTRY>
|
||||
</ROW>
|
||||
</TBODY>
|
||||
</TGROUP>
|
||||
</TABLE>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="inet-operators">
|
||||
<title><type>inet</> Operators</title>
|
||||
|
||||
<table tocentry="1" id="inet-operators-table">
|
||||
<title><type>inet</> Operators</title>
|
||||
<table tocentry="1" id="cidr-inet-operators-table">
|
||||
<title><type>cidr</> and <type>inet</> Operators</title>
|
||||
<TGROUP COLS="3">
|
||||
<THEAD>
|
||||
<ROW>
|
||||
@ -892,6 +823,16 @@ logical union
|
||||
</TBODY>
|
||||
</TGROUP>
|
||||
</TABLE>
|
||||
|
||||
<para>
|
||||
All of the operators for <type>inet</type> can be applied to
|
||||
<type>cidr</type> values as well. The operators
|
||||
<literal><<</> <literal><<=</>
|
||||
<literal>>></> <literal>>>=</>
|
||||
test for subnet inclusion: they consider only the network parts
|
||||
of the two addresses, ignoring any host part, and determine whether
|
||||
one network part is identical to or a subnet of the other.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="macaddr-operators">
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.8 1999/07/17 20:17:56 momjian Exp $";
|
||||
static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.9 2000/11/10 20:13:25 tgl Exp $";
|
||||
|
||||
#endif
|
||||
|
||||
@ -56,7 +56,7 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
|
||||
{
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
case AF_INET:
|
||||
return (inet_cidr_ntop_ipv4(src, bits, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
@ -102,15 +102,12 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
|
||||
/* Format whole octets. */
|
||||
for (b = bits / 8; b > 0; b--)
|
||||
{
|
||||
if (size < sizeof "255.")
|
||||
if (size < sizeof ".255")
|
||||
goto emsgsize;
|
||||
t = dst;
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
if (b > 1)
|
||||
{
|
||||
if (dst != odst)
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
size -= (size_t) (dst - t);
|
||||
}
|
||||
|
||||
@ -132,6 +129,7 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
|
||||
if (size < sizeof "/32")
|
||||
goto emsgsize;
|
||||
dst += SPRINTF((dst, "/%u", bits));
|
||||
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
@ -159,7 +157,7 @@ inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
|
||||
{
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
case AF_INET:
|
||||
return (inet_net_ntop_ipv4(src, bits, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
@ -185,48 +183,34 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
|
||||
{
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
size_t len = 4;
|
||||
int b,
|
||||
tb;
|
||||
int len = 4;
|
||||
int b;
|
||||
|
||||
if (bits < 0 || bits > 32)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
if (bits == 0)
|
||||
{
|
||||
if (size < sizeof "0")
|
||||
goto emsgsize;
|
||||
*dst++ = '0';
|
||||
size--;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/* Format whole octets plus nonzero trailing octets. */
|
||||
tb = (bits == 32) ? 31 : bits;
|
||||
for (b = 0; bits != 0 && (b <= (tb / 8) || (b < len && *src != 0)); b++)
|
||||
/* Always format all four octets, regardless of mask length. */
|
||||
for (b = len; b > 0; b--)
|
||||
{
|
||||
if (size < sizeof "255.")
|
||||
if (size < sizeof ".255")
|
||||
goto emsgsize;
|
||||
t = dst;
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
if (b + 1 <= (tb / 8) || (b + 1 < len && *src != 0))
|
||||
{
|
||||
if (dst != odst)
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
size -= (size_t) (dst - t);
|
||||
}
|
||||
|
||||
/* don't print masklen if 32 bits */
|
||||
if (bits == 32)
|
||||
return odst;
|
||||
|
||||
/* Format CIDR /width. */
|
||||
if (size < sizeof "/32")
|
||||
goto emsgsize;
|
||||
dst += SPRINTF((dst, "/%u", bits));
|
||||
if (bits != 32)
|
||||
{
|
||||
if (size < sizeof "/32")
|
||||
goto emsgsize;
|
||||
dst += SPRINTF((dst, "/%u", bits));
|
||||
}
|
||||
|
||||
return (odst);
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
* is for IP V4 CIDR notation, but prepared for V6: just
|
||||
* add the necessary bits where the comments indicate.
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.25 2000/10/27 01:52:15 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.26 2000/11/10 20:13:25 tgl Exp $
|
||||
*
|
||||
* Jon Postel RIP 16 Oct 1998
|
||||
*/
|
||||
@ -67,12 +67,12 @@ network_in(char *src, int type)
|
||||
|
||||
/*
|
||||
* Error check: CIDR values must not have any bits set beyond the masklen.
|
||||
* XXX this code not IPV6 ready.
|
||||
* XXX this code is not IPV6 ready.
|
||||
*/
|
||||
if (type)
|
||||
{
|
||||
if (! v4addressOK(ip_v4addr(dst), bits))
|
||||
elog(ERROR, "invalid CIDR value '%s': width too small", src);
|
||||
elog(ERROR, "invalid CIDR value '%s': has bits set to right of mask", src);
|
||||
}
|
||||
|
||||
VARATT_SIZEP(dst) = VARHDRSZ
|
||||
@ -338,12 +338,10 @@ network_host(PG_FUNCTION_ARGS)
|
||||
char *ptr,
|
||||
tmp[sizeof("255.255.255.255/32")];
|
||||
|
||||
if (ip_type(ip))
|
||||
elog(ERROR, "CIDR type has no host part");
|
||||
|
||||
if (ip_family(ip) == AF_INET)
|
||||
{
|
||||
/* It's an IP V4 address: */
|
||||
/* force display of 32 bits, regardless of masklen... */
|
||||
if (inet_net_ntop(AF_INET, &ip_v4addr(ip), 32, tmp, sizeof(tmp)) == NULL)
|
||||
elog(ERROR, "unable to print host (%s)", strerror(errno));
|
||||
}
|
||||
@ -351,7 +349,7 @@ network_host(PG_FUNCTION_ARGS)
|
||||
/* Go for an IPV6 address here, before faulting out: */
|
||||
elog(ERROR, "unknown address family (%d)", ip_family(ip));
|
||||
|
||||
/* Suppress /n if present */
|
||||
/* Suppress /n if present (shouldn't happen now) */
|
||||
if ((ptr = strchr(tmp, '/')) != NULL)
|
||||
*ptr = '\0';
|
||||
|
||||
@ -363,6 +361,40 @@ network_host(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(ret);
|
||||
}
|
||||
|
||||
Datum
|
||||
network_show(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
text *ret;
|
||||
int len;
|
||||
char tmp[sizeof("255.255.255.255/32")];
|
||||
|
||||
if (ip_family(ip) == AF_INET)
|
||||
{
|
||||
/* It's an IP V4 address: */
|
||||
/* force display of 32 bits, regardless of masklen... */
|
||||
if (inet_net_ntop(AF_INET, &ip_v4addr(ip), 32, tmp, sizeof(tmp)) == NULL)
|
||||
elog(ERROR, "unable to print host (%s)", strerror(errno));
|
||||
}
|
||||
else
|
||||
/* Go for an IPV6 address here, before faulting out: */
|
||||
elog(ERROR, "unknown address family (%d)", ip_family(ip));
|
||||
|
||||
/* Add /n if not present */
|
||||
if (strchr(tmp, '/') == NULL)
|
||||
{
|
||||
len = strlen(tmp);
|
||||
snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
|
||||
}
|
||||
|
||||
/* Return string as a text datum */
|
||||
len = strlen(tmp);
|
||||
ret = (text *) palloc(len + VARHDRSZ);
|
||||
VARATT_SIZEP(ret) = len + VARHDRSZ;
|
||||
memcpy(VARDATA(ret), tmp, len);
|
||||
PG_RETURN_TEXT_P(ret);
|
||||
}
|
||||
|
||||
Datum
|
||||
network_masklen(PG_FUNCTION_ARGS)
|
||||
{
|
||||
@ -375,100 +407,100 @@ Datum
|
||||
network_broadcast(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
text *ret;
|
||||
int len;
|
||||
char *ptr,
|
||||
tmp[sizeof("255.255.255.255/32")];
|
||||
inet *dst;
|
||||
|
||||
dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
|
||||
/* make sure any unused bits are zeroed */
|
||||
MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
|
||||
|
||||
if (ip_family(ip) == AF_INET)
|
||||
{
|
||||
/* It's an IP V4 address: */
|
||||
int addr;
|
||||
unsigned long mask = 0xffffffff;
|
||||
|
||||
if (ip_bits(ip) < 32)
|
||||
mask >>= ip_bits(ip);
|
||||
addr = htonl(ntohl(ip_v4addr(ip)) | mask);
|
||||
mask >>= ip_bits(ip);
|
||||
|
||||
if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL)
|
||||
elog(ERROR, "unable to print address (%s)", strerror(errno));
|
||||
ip_v4addr(dst) = htonl(ntohl(ip_v4addr(ip)) | mask);
|
||||
}
|
||||
else
|
||||
/* Go for an IPV6 address here, before faulting out: */
|
||||
elog(ERROR, "unknown address family (%d)", ip_family(ip));
|
||||
|
||||
/* Suppress /n if present */
|
||||
if ((ptr = strchr(tmp, '/')) != NULL)
|
||||
*ptr = '\0';
|
||||
ip_family(dst) = ip_family(ip);
|
||||
ip_bits(dst) = ip_bits(ip);
|
||||
ip_type(dst) = 0;
|
||||
VARATT_SIZEP(dst) = VARHDRSZ
|
||||
+ ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
|
||||
+ ip_addrsize(dst);
|
||||
|
||||
/* Return string as a text datum */
|
||||
len = strlen(tmp);
|
||||
ret = (text *) palloc(len + VARHDRSZ);
|
||||
VARATT_SIZEP(ret) = len + VARHDRSZ;
|
||||
memcpy(VARDATA(ret), tmp, len);
|
||||
PG_RETURN_TEXT_P(ret);
|
||||
PG_RETURN_INET_P(dst);
|
||||
}
|
||||
|
||||
Datum
|
||||
network_network(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
text *ret;
|
||||
int len;
|
||||
char tmp[sizeof("255.255.255.255/32")];
|
||||
inet *dst;
|
||||
|
||||
dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
|
||||
/* make sure any unused bits are zeroed */
|
||||
MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
|
||||
|
||||
if (ip_family(ip) == AF_INET)
|
||||
{
|
||||
/* It's an IP V4 address: */
|
||||
int addr = htonl(ntohl(ip_v4addr(ip)) & (0xffffffff << (32 - ip_bits(ip))));
|
||||
unsigned long mask = 0xffffffff;
|
||||
|
||||
if (inet_cidr_ntop(AF_INET, &addr, ip_bits(ip), tmp, sizeof(tmp)) == NULL)
|
||||
elog(ERROR, "unable to print network (%s)", strerror(errno));
|
||||
mask <<= (32 - ip_bits(ip));
|
||||
|
||||
ip_v4addr(dst) = htonl(ntohl(ip_v4addr(ip)) & mask);
|
||||
}
|
||||
else
|
||||
/* Go for an IPV6 address here, before faulting out: */
|
||||
elog(ERROR, "unknown address family (%d)", ip_family(ip));
|
||||
|
||||
/* Return string as a text datum */
|
||||
len = strlen(tmp);
|
||||
ret = (text *) palloc(len + VARHDRSZ);
|
||||
VARATT_SIZEP(ret) = len + VARHDRSZ;
|
||||
memcpy(VARDATA(ret), tmp, len);
|
||||
PG_RETURN_TEXT_P(ret);
|
||||
ip_family(dst) = ip_family(ip);
|
||||
ip_bits(dst) = ip_bits(ip);
|
||||
ip_type(dst) = 1;
|
||||
VARATT_SIZEP(dst) = VARHDRSZ
|
||||
+ ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
|
||||
+ ip_addrsize(dst);
|
||||
|
||||
PG_RETURN_INET_P(dst);
|
||||
}
|
||||
|
||||
Datum
|
||||
network_netmask(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
text *ret;
|
||||
int len;
|
||||
char *ptr,
|
||||
tmp[sizeof("255.255.255.255/32")];
|
||||
inet *dst;
|
||||
|
||||
dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
|
||||
/* make sure any unused bits are zeroed */
|
||||
MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
|
||||
|
||||
if (ip_family(ip) == AF_INET)
|
||||
{
|
||||
/* It's an IP V4 address: */
|
||||
int addr = htonl(ip_bits(ip) ?
|
||||
(-1 << (32 - ip_bits(ip))) & 0xffffffff : 0x00000000);
|
||||
unsigned long mask = 0xffffffff;
|
||||
|
||||
if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL)
|
||||
elog(ERROR, "unable to print netmask (%s)", strerror(errno));
|
||||
mask <<= (32 - ip_bits(ip));
|
||||
|
||||
ip_v4addr(dst) = htonl(mask);
|
||||
|
||||
ip_bits(dst) = 32;
|
||||
}
|
||||
else
|
||||
/* Go for an IPV6 address here, before faulting out: */
|
||||
elog(ERROR, "unknown address family (%d)", ip_family(ip));
|
||||
|
||||
/* Suppress /n if present */
|
||||
if ((ptr = strchr(tmp, '/')) != NULL)
|
||||
*ptr = '\0';
|
||||
ip_family(dst) = ip_family(ip);
|
||||
ip_type(dst) = 0;
|
||||
VARATT_SIZEP(dst) = VARHDRSZ
|
||||
+ ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
|
||||
+ ip_addrsize(dst);
|
||||
|
||||
/* Return string as a text datum */
|
||||
len = strlen(tmp);
|
||||
ret = (text *) palloc(len + VARHDRSZ);
|
||||
VARATT_SIZEP(ret) = len + VARHDRSZ;
|
||||
memcpy(VARDATA(ret), tmp, len);
|
||||
PG_RETURN_TEXT_P(ret);
|
||||
PG_RETURN_INET_P(dst);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: catversion.h,v 1.56 2000/11/08 16:59:50 petere Exp $
|
||||
* $Id: catversion.h,v 1.57 2000/11/10 20:13:26 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 200011080
|
||||
#define CATALOG_VERSION_NO 200011101
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_proc.h,v 1.172 2000/11/06 15:58:46 thomas Exp $
|
||||
* $Id: pg_proc.h,v 1.173 2000/11/10 20:13:26 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The script catalog/genbki.sh reads this file and generates .bki
|
||||
@ -2270,17 +2270,19 @@ DESCR("is-supernet");
|
||||
DATA(insert OID = 930 ( network_supeq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_supeq - ));
|
||||
DESCR("is-supernet-or-equal");
|
||||
|
||||
/* inet/cidr versions */
|
||||
DATA(insert OID = 696 ( netmask PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_netmask - ));
|
||||
/* inet/cidr functions */
|
||||
DATA(insert OID = 683 ( network PGUID 12 f t t t 1 f 650 "869" 100 0 0 100 network_network - ));
|
||||
DESCR("network part of address");
|
||||
DATA(insert OID = 696 ( netmask PGUID 12 f t t t 1 f 869 "869" 100 0 0 100 network_netmask - ));
|
||||
DESCR("netmask of address");
|
||||
DATA(insert OID = 697 ( masklen PGUID 12 f t t t 1 f 23 "869" 100 0 0 100 network_masklen - ));
|
||||
DESCR("netmask length");
|
||||
DATA(insert OID = 698 ( broadcast PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_broadcast - ));
|
||||
DESCR("broadcast address");
|
||||
DATA(insert OID = 698 ( broadcast PGUID 12 f t t t 1 f 869 "869" 100 0 0 100 network_broadcast - ));
|
||||
DESCR("broadcast address of network");
|
||||
DATA(insert OID = 699 ( host PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_host - ));
|
||||
DESCR("host address");
|
||||
DATA(insert OID = 683 ( network PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_network - ));
|
||||
DESCR("network address");
|
||||
DESCR("show address octets only");
|
||||
DATA(insert OID = 730 ( text PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_show - ));
|
||||
DESCR("show all parts of inet/cidr value");
|
||||
|
||||
DATA(insert OID = 1691 ( boolle PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolle - ));
|
||||
DESCR("less-than-or-equal");
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: builtins.h,v 1.140 2000/10/24 20:16:47 petere Exp $
|
||||
* $Id: builtins.h,v 1.141 2000/11/10 20:13:26 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -504,6 +504,7 @@ extern Datum network_netmask(PG_FUNCTION_ARGS);
|
||||
extern Datum network_masklen(PG_FUNCTION_ARGS);
|
||||
extern Datum network_broadcast(PG_FUNCTION_ARGS);
|
||||
extern Datum network_host(PG_FUNCTION_ARGS);
|
||||
extern Datum network_show(PG_FUNCTION_ARGS);
|
||||
|
||||
/* mac.c */
|
||||
extern Datum macaddr_in(PG_FUNCTION_ARGS);
|
||||
|
@ -17,7 +17,7 @@ INSERT INTO INET_TBL (c, i) VALUES ('10', '11.1.2.3/8');
|
||||
INSERT INTO INET_TBL (c, i) VALUES ('10', '9.1.2.3/8');
|
||||
-- check that CIDR rejects invalid input:
|
||||
INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/24', '192.168.1.226');
|
||||
ERROR: invalid CIDR value '192.168.1.2/24': width too small
|
||||
ERROR: invalid CIDR value '192.168.1.2/24': has bits set to right of mask
|
||||
SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
|
||||
ten | cidr | inet
|
||||
-----+--------------+------------------
|
||||
@ -34,35 +34,35 @@ SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
|
||||
(10 rows)
|
||||
|
||||
-- now test some support functions
|
||||
SELECT '' AS ten, i AS inet, host(i) FROM INET_TBL;
|
||||
ten | inet | host
|
||||
-----+------------------+---------------
|
||||
| 192.168.1.226/24 | 192.168.1.226
|
||||
| 192.168.1.226 | 192.168.1.226
|
||||
| 10.1.2.3/8 | 10.1.2.3
|
||||
| 10.1.2.3/8 | 10.1.2.3
|
||||
| 10.1.2.3 | 10.1.2.3
|
||||
| 10.1.2.3/24 | 10.1.2.3
|
||||
| 10.1.2.3/16 | 10.1.2.3
|
||||
| 10.1.2.3/8 | 10.1.2.3
|
||||
| 11.1.2.3/8 | 11.1.2.3
|
||||
| 9.1.2.3/8 | 9.1.2.3
|
||||
SELECT '' AS ten, i AS inet, host(i), text(i) FROM INET_TBL;
|
||||
ten | inet | host | text
|
||||
-----+------------------+---------------+------------------
|
||||
| 192.168.1.226/24 | 192.168.1.226 | 192.168.1.226/24
|
||||
| 192.168.1.226 | 192.168.1.226 | 192.168.1.226/32
|
||||
| 10.1.2.3/8 | 10.1.2.3 | 10.1.2.3/8
|
||||
| 10.1.2.3/8 | 10.1.2.3 | 10.1.2.3/8
|
||||
| 10.1.2.3 | 10.1.2.3 | 10.1.2.3/32
|
||||
| 10.1.2.3/24 | 10.1.2.3 | 10.1.2.3/24
|
||||
| 10.1.2.3/16 | 10.1.2.3 | 10.1.2.3/16
|
||||
| 10.1.2.3/8 | 10.1.2.3 | 10.1.2.3/8
|
||||
| 11.1.2.3/8 | 11.1.2.3 | 11.1.2.3/8
|
||||
| 9.1.2.3/8 | 9.1.2.3 | 9.1.2.3/8
|
||||
(10 rows)
|
||||
|
||||
SELECT '' AS ten, c AS cidr, broadcast(c),
|
||||
i AS inet, broadcast(i) FROM INET_TBL;
|
||||
ten | cidr | broadcast | inet | broadcast
|
||||
-----+--------------+-----------------+------------------+-----------------
|
||||
| 192.168.1/24 | 192.168.1.255 | 192.168.1.226/24 | 192.168.1.255
|
||||
| 192.168.1/24 | 192.168.1.255 | 192.168.1.226 | 255.255.255.255
|
||||
| 10/8 | 10.255.255.255 | 10.1.2.3/8 | 10.255.255.255
|
||||
| 10.0.0.0/32 | 255.255.255.255 | 10.1.2.3/8 | 10.255.255.255
|
||||
| 10.1.2.3/32 | 255.255.255.255 | 10.1.2.3 | 255.255.255.255
|
||||
| 10.1.2/24 | 10.1.2.255 | 10.1.2.3/24 | 10.1.2.255
|
||||
| 10.1/16 | 10.1.255.255 | 10.1.2.3/16 | 10.1.255.255
|
||||
| 10/8 | 10.255.255.255 | 10.1.2.3/8 | 10.255.255.255
|
||||
| 10/8 | 10.255.255.255 | 11.1.2.3/8 | 11.255.255.255
|
||||
| 10/8 | 10.255.255.255 | 9.1.2.3/8 | 9.255.255.255
|
||||
ten | cidr | broadcast | inet | broadcast
|
||||
-----+--------------+------------------+------------------+------------------
|
||||
| 192.168.1/24 | 192.168.1.255/24 | 192.168.1.226/24 | 192.168.1.255/24
|
||||
| 192.168.1/24 | 192.168.1.255/24 | 192.168.1.226 | 255.255.255.255
|
||||
| 10/8 | 10.255.255.255/8 | 10.1.2.3/8 | 10.255.255.255/8
|
||||
| 10.0.0.0/32 | 255.255.255.255 | 10.1.2.3/8 | 10.255.255.255/8
|
||||
| 10.1.2.3/32 | 255.255.255.255 | 10.1.2.3 | 255.255.255.255
|
||||
| 10.1.2/24 | 10.1.2.255/24 | 10.1.2.3/24 | 10.1.2.255/24
|
||||
| 10.1/16 | 10.1.255.255/16 | 10.1.2.3/16 | 10.1.255.255/16
|
||||
| 10/8 | 10.255.255.255/8 | 10.1.2.3/8 | 10.255.255.255/8
|
||||
| 10/8 | 10.255.255.255/8 | 11.1.2.3/8 | 11.255.255.255/8
|
||||
| 10/8 | 10.255.255.255/8 | 9.1.2.3/8 | 9.255.255.255/8
|
||||
(10 rows)
|
||||
|
||||
SELECT '' AS ten, c AS cidr, network(c) AS "network(cidr)",
|
||||
|
@ -23,7 +23,7 @@ SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
|
||||
|
||||
-- now test some support functions
|
||||
|
||||
SELECT '' AS ten, i AS inet, host(i) FROM INET_TBL;
|
||||
SELECT '' AS ten, i AS inet, host(i), text(i) FROM INET_TBL;
|
||||
SELECT '' AS ten, c AS cidr, broadcast(c),
|
||||
i AS inet, broadcast(i) FROM INET_TBL;
|
||||
SELECT '' AS ten, c AS cidr, network(c) AS "network(cidr)",
|
||||
|
Loading…
x
Reference in New Issue
Block a user