* 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.27 2000/11/25 21:30:54 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.28 2000/12/22 18:00:20 tgl Exp $
*
* Jon Postel RIP 16 Oct 1998
*/
inet *src = PG_GETARG_INET_P(0);
char tmp[sizeof("255.255.255.255/32")];
char *dst;
+ int len;
if (ip_family(src) == AF_INET)
{
/* It's an IP V4 address: */
- if (ip_type(src))
- dst = inet_cidr_ntop(AF_INET, &ip_v4addr(src), ip_bits(src),
- tmp, sizeof(tmp));
- else
- dst = inet_net_ntop(AF_INET, &ip_v4addr(src), ip_bits(src),
- tmp, sizeof(tmp));
-
+ /* Use inet style for both inet and cidr, since we don't want
+ * abbreviated CIDR style here.
+ */
+ dst = inet_net_ntop(AF_INET, &ip_v4addr(src), ip_bits(src),
+ tmp, sizeof(tmp));
if (dst == NULL)
elog(ERROR, "unable to print address (%s)", strerror(errno));
+ /* For CIDR, add /n if not present */
+ if (ip_type(src) && strchr(tmp, '/') == NULL)
+ {
+ len = strlen(tmp);
+ snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src));
+ }
}
else
/* Go for an IPV6 address here, before faulting out: */
/* 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));
+ /* Add /n if not present (which it won't be) */
+ if (strchr(tmp, '/') == NULL)
+ {
+ len = strlen(tmp);
+ snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
+ }
}
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)
+ /* 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_abbrev(PG_FUNCTION_ARGS)
+{
+ inet *ip = PG_GETARG_INET_P(0);
+ text *ret;
+ char *dst;
+ int len;
+ char tmp[sizeof("255.255.255.255/32")];
+
+ if (ip_family(ip) == AF_INET)
{
- len = strlen(tmp);
- snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
+ /* It's an IP V4 address: */
+ if (ip_type(ip))
+ dst = inet_cidr_ntop(AF_INET, &ip_v4addr(ip), ip_bits(ip),
+ tmp, sizeof(tmp));
+ else
+ dst = inet_net_ntop(AF_INET, &ip_v4addr(ip), ip_bits(ip),
+ tmp, sizeof(tmp));
+
+ if (dst == NULL)
+ elog(ERROR, "unable to print address (%s)", strerror(errno));
}
+ 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);
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': has bits set to right of mask
SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
- ten | cidr | inet
------+--------------+------------------
- | 192.168.1/24 | 192.168.1.226/24
- | 192.168.1/24 | 192.168.1.226
- | 10/8 | 10.1.2.3/8
- | 10.0.0.0/32 | 10.1.2.3/8
- | 10.1.2.3/32 | 10.1.2.3
- | 10.1.2/24 | 10.1.2.3/24
- | 10.1/16 | 10.1.2.3/16
- | 10/8 | 10.1.2.3/8
- | 10/8 | 11.1.2.3/8
- | 10/8 | 9.1.2.3/8
+ ten | cidr | inet
+-----+----------------+------------------
+ | 192.168.1.0/24 | 192.168.1.226/24
+ | 192.168.1.0/24 | 192.168.1.226
+ | 10.0.0.0/8 | 10.1.2.3/8
+ | 10.0.0.0/32 | 10.1.2.3/8
+ | 10.1.2.3/32 | 10.1.2.3
+ | 10.1.2.0/24 | 10.1.2.3/24
+ | 10.1.0.0/16 | 10.1.2.3/16
+ | 10.0.0.0/8 | 10.1.2.3/8
+ | 10.0.0.0/8 | 11.1.2.3/8
+ | 10.0.0.0/8 | 9.1.2.3/8
(10 rows)
-- now test some support functions
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/24 | 192.168.1.226/24 | 192.168.1.255/24
- | 192.168.1/24 | 192.168.1.255/24 | 192.168.1.226 | 192.168.1.226
- | 10/8 | 10.255.255.255/8 | 10.1.2.3/8 | 10.255.255.255/8
- | 10.0.0.0/32 | 10.0.0.0 | 10.1.2.3/8 | 10.255.255.255/8
- | 10.1.2.3/32 | 10.1.2.3 | 10.1.2.3 | 10.1.2.3
- | 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
+ ten | cidr | broadcast | inet | broadcast
+-----+----------------+------------------+------------------+------------------
+ | 192.168.1.0/24 | 192.168.1.255/24 | 192.168.1.226/24 | 192.168.1.255/24
+ | 192.168.1.0/24 | 192.168.1.255/24 | 192.168.1.226 | 192.168.1.226
+ | 10.0.0.0/8 | 10.255.255.255/8 | 10.1.2.3/8 | 10.255.255.255/8
+ | 10.0.0.0/32 | 10.0.0.0 | 10.1.2.3/8 | 10.255.255.255/8
+ | 10.1.2.3/32 | 10.1.2.3 | 10.1.2.3 | 10.1.2.3
+ | 10.1.2.0/24 | 10.1.2.255/24 | 10.1.2.3/24 | 10.1.2.255/24
+ | 10.1.0.0/16 | 10.1.255.255/16 | 10.1.2.3/16 | 10.1.255.255/16
+ | 10.0.0.0/8 | 10.255.255.255/8 | 10.1.2.3/8 | 10.255.255.255/8
+ | 10.0.0.0/8 | 10.255.255.255/8 | 11.1.2.3/8 | 11.255.255.255/8
+ | 10.0.0.0/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)",
i AS inet, network(i) AS "network(inet)" FROM INET_TBL;
- ten | cidr | network(cidr) | inet | network(inet)
------+--------------+---------------+------------------+------------------
- | 192.168.1/24 | 192.168.1/24 | 192.168.1.226/24 | 192.168.1/24
- | 192.168.1/24 | 192.168.1/24 | 192.168.1.226 | 192.168.1.226/32
- | 10/8 | 10/8 | 10.1.2.3/8 | 10/8
- | 10.0.0.0/32 | 10.0.0.0/32 | 10.1.2.3/8 | 10/8
- | 10.1.2.3/32 | 10.1.2.3/32 | 10.1.2.3 | 10.1.2.3/32
- | 10.1.2/24 | 10.1.2/24 | 10.1.2.3/24 | 10.1.2/24
- | 10.1/16 | 10.1/16 | 10.1.2.3/16 | 10.1/16
- | 10/8 | 10/8 | 10.1.2.3/8 | 10/8
- | 10/8 | 10/8 | 11.1.2.3/8 | 11/8
- | 10/8 | 10/8 | 9.1.2.3/8 | 9/8
+ ten | cidr | network(cidr) | inet | network(inet)
+-----+----------------+----------------+------------------+------------------
+ | 192.168.1.0/24 | 192.168.1.0/24 | 192.168.1.226/24 | 192.168.1.0/24
+ | 192.168.1.0/24 | 192.168.1.0/24 | 192.168.1.226 | 192.168.1.226/32
+ | 10.0.0.0/8 | 10.0.0.0/8 | 10.1.2.3/8 | 10.0.0.0/8
+ | 10.0.0.0/32 | 10.0.0.0/32 | 10.1.2.3/8 | 10.0.0.0/8
+ | 10.1.2.3/32 | 10.1.2.3/32 | 10.1.2.3 | 10.1.2.3/32
+ | 10.1.2.0/24 | 10.1.2.0/24 | 10.1.2.3/24 | 10.1.2.0/24
+ | 10.1.0.0/16 | 10.1.0.0/16 | 10.1.2.3/16 | 10.1.0.0/16
+ | 10.0.0.0/8 | 10.0.0.0/8 | 10.1.2.3/8 | 10.0.0.0/8
+ | 10.0.0.0/8 | 10.0.0.0/8 | 11.1.2.3/8 | 11.0.0.0/8
+ | 10.0.0.0/8 | 10.0.0.0/8 | 9.1.2.3/8 | 9.0.0.0/8
(10 rows)
SELECT '' AS ten, c AS cidr, masklen(c) AS "masklen(cidr)",
i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL;
- ten | cidr | masklen(cidr) | inet | masklen(inet)
------+--------------+---------------+------------------+---------------
- | 192.168.1/24 | 24 | 192.168.1.226/24 | 24
- | 192.168.1/24 | 24 | 192.168.1.226 | 32
- | 10/8 | 8 | 10.1.2.3/8 | 8
- | 10.0.0.0/32 | 32 | 10.1.2.3/8 | 8
- | 10.1.2.3/32 | 32 | 10.1.2.3 | 32
- | 10.1.2/24 | 24 | 10.1.2.3/24 | 24
- | 10.1/16 | 16 | 10.1.2.3/16 | 16
- | 10/8 | 8 | 10.1.2.3/8 | 8
- | 10/8 | 8 | 11.1.2.3/8 | 8
- | 10/8 | 8 | 9.1.2.3/8 | 8
+ ten | cidr | masklen(cidr) | inet | masklen(inet)
+-----+----------------+---------------+------------------+---------------
+ | 192.168.1.0/24 | 24 | 192.168.1.226/24 | 24
+ | 192.168.1.0/24 | 24 | 192.168.1.226 | 32
+ | 10.0.0.0/8 | 8 | 10.1.2.3/8 | 8
+ | 10.0.0.0/32 | 32 | 10.1.2.3/8 | 8
+ | 10.1.2.3/32 | 32 | 10.1.2.3 | 32
+ | 10.1.2.0/24 | 24 | 10.1.2.3/24 | 24
+ | 10.1.0.0/16 | 16 | 10.1.2.3/16 | 16
+ | 10.0.0.0/8 | 8 | 10.1.2.3/8 | 8
+ | 10.0.0.0/8 | 8 | 11.1.2.3/8 | 8
+ | 10.0.0.0/8 | 8 | 9.1.2.3/8 | 8
(10 rows)
SELECT '' AS four, c AS cidr, masklen(c) AS "masklen(cidr)",
i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL
WHERE masklen(c) <= 8;
- four | cidr | masklen(cidr) | inet | masklen(inet)
-------+------+---------------+------------+---------------
- | 10/8 | 8 | 10.1.2.3/8 | 8
- | 10/8 | 8 | 10.1.2.3/8 | 8
- | 10/8 | 8 | 11.1.2.3/8 | 8
- | 10/8 | 8 | 9.1.2.3/8 | 8
+ four | cidr | masklen(cidr) | inet | masklen(inet)
+------+------------+---------------+------------+---------------
+ | 10.0.0.0/8 | 8 | 10.1.2.3/8 | 8
+ | 10.0.0.0/8 | 8 | 10.1.2.3/8 | 8
+ | 10.0.0.0/8 | 8 | 11.1.2.3/8 | 8
+ | 10.0.0.0/8 | 8 | 9.1.2.3/8 | 8
(4 rows)
SELECT '' AS six, c AS cidr, i AS inet FROM INET_TBL
i << c AS sb, i <<= c AS sbe,
i >> c AS sup, i >>= c AS spe
FROM INET_TBL;
- ten | i | c | lt | le | eq | ge | gt | ne | sb | sbe | sup | spe
------+------------------+--------------+----+----+----+----+----+----+----+-----+-----+-----
- | 192.168.1.226/24 | 192.168.1/24 | f | f | f | t | t | t | f | t | f | t
- | 192.168.1.226 | 192.168.1/24 | f | f | f | t | t | t | t | t | f | f
- | 10.1.2.3/8 | 10/8 | f | f | f | t | t | t | f | t | f | t
- | 10.1.2.3/8 | 10.0.0.0/32 | t | t | f | f | f | t | f | f | t | t
- | 10.1.2.3 | 10.1.2.3/32 | f | t | t | t | f | f | f | t | f | t
- | 10.1.2.3/24 | 10.1.2/24 | f | f | f | t | t | t | f | t | f | t
- | 10.1.2.3/16 | 10.1/16 | f | f | f | t | t | t | f | t | f | t
- | 10.1.2.3/8 | 10/8 | f | f | f | t | t | t | f | t | f | t
- | 11.1.2.3/8 | 10/8 | f | f | f | t | t | t | f | f | f | f
- | 9.1.2.3/8 | 10/8 | t | t | f | f | f | t | f | f | f | f
+ ten | i | c | lt | le | eq | ge | gt | ne | sb | sbe | sup | spe
+-----+------------------+----------------+----+----+----+----+----+----+----+-----+-----+-----
+ | 192.168.1.226/24 | 192.168.1.0/24 | f | f | f | t | t | t | f | t | f | t
+ | 192.168.1.226 | 192.168.1.0/24 | f | f | f | t | t | t | t | t | f | f
+ | 10.1.2.3/8 | 10.0.0.0/8 | f | f | f | t | t | t | f | t | f | t
+ | 10.1.2.3/8 | 10.0.0.0/32 | t | t | f | f | f | t | f | f | t | t
+ | 10.1.2.3 | 10.1.2.3/32 | f | t | t | t | f | f | f | t | f | t
+ | 10.1.2.3/24 | 10.1.2.0/24 | f | f | f | t | t | t | f | t | f | t
+ | 10.1.2.3/16 | 10.1.0.0/16 | f | f | f | t | t | t | f | t | f | t
+ | 10.1.2.3/8 | 10.0.0.0/8 | f | f | f | t | t | t | f | t | f | t
+ | 11.1.2.3/8 | 10.0.0.0/8 | f | f | f | t | t | t | f | f | f | f
+ | 9.1.2.3/8 | 10.0.0.0/8 | t | t | f | f | f | t | f | f | f | f
(10 rows)