From 8849655d24bf6d73102b92f900d6d78b6600dca2 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Thu, 8 Oct 1998 00:19:47 +0000 Subject: I agree. I think, though, that the best argument presented in the debate was from Paul Vixie, who wanted INET to be the name covering both IPV4 and IPV6. The following kit makes the needed changes: Tom Ivar Helbekkmo --- src/backend/utils/adt/Makefile | 4 +- src/backend/utils/adt/inet.c | 287 +++++++++++++++++++++++++++++++++++++++++ src/backend/utils/adt/ip.c | 285 ---------------------------------------- src/backend/utils/adt/mac.c | 4 +- 4 files changed, 291 insertions(+), 289 deletions(-) create mode 100644 src/backend/utils/adt/inet.c delete mode 100644 src/backend/utils/adt/ip.c (limited to 'src/backend/utils/adt') diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index 686a2d0e8c..7ac61fc5d6 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -4,7 +4,7 @@ # Makefile for utils/adt # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.18 1998/10/03 05:40:47 momjian Exp $ +# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.19 1998/10/08 00:19:33 momjian Exp $ # #------------------------------------------------------------------------- @@ -24,7 +24,7 @@ OBJS = acl.o arrayfuncs.o arrayutils.o bool.o cash.o char.o chunk.o \ oid.o oracle_compat.o \ regexp.o regproc.o ruleutils.o selfuncs.o sets.o \ tid.o timestamp.o varchar.o varlena.o version.o \ - ip.o mac.o inet_net_ntop.o inet_net_pton.o + inet.o mac.o inet_net_ntop.o inet_net_pton.o all: SUBSYS.o diff --git a/src/backend/utils/adt/inet.c b/src/backend/utils/adt/inet.c new file mode 100644 index 0000000000..25e0436214 --- /dev/null +++ b/src/backend/utils/adt/inet.c @@ -0,0 +1,287 @@ +/* + * PostgreSQL type definitions for the INET type. This + * is for IP V4 CIDR notation, but prepared for V6: just + * add the necessary bits where the comments indicate. + * + * $Id: inet.c,v 1.1 1998/10/08 00:19:35 momjian Exp $ + */ + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +static int v4bitncmp(unsigned int a1, unsigned int a2, int bits); + +/* + * Access macros. Add IPV6 support. + */ + +#define ip_addrsize(inetptr) \ + (((inet_struct *)VARDATA(inetptr))->family == AF_INET ? 4 : -1) + +#define ip_family(inetptr) \ + (((inet_struct *)VARDATA(inetptr))->family) + +#define ip_bits(inetptr) \ + (((inet_struct *)VARDATA(inetptr))->bits) + +#define ip_v4addr(inetptr) \ + (((inet_struct *)VARDATA(inetptr))->addr.ipv4_addr) + +/* + * IP address reader. + */ + +inet * +inet_in(char *src) +{ + int bits; + inet *dst; + + dst = palloc(VARHDRSZ + sizeof(inet_struct)); + if (dst == NULL) + { + elog(ERROR, "unable to allocate memory in inet_in()"); + return (NULL); + } + /* First, try for an IP V4 address: */ + ip_family(dst) = AF_INET; + bits = inet_net_pton(ip_family(dst), src, &ip_v4addr(dst), ip_addrsize(dst)); + if ((bits < 0) || (bits > 32)) + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "could not parse \"%s\"", src); + pfree(dst); + return (NULL); + } + VARSIZE(dst) = VARHDRSZ + + ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst)) + + ip_addrsize(dst); + ip_bits(dst) = bits; + return (dst); +} + +/* + * IP address output function. + */ + +char * +inet_out(inet *src) +{ + char *dst, + tmp[sizeof("255.255.255.255/32")]; + + if (ip_family(src) == AF_INET) + { + /* It's an IP V4 address: */ + if (inet_net_ntop(AF_INET, &ip_v4addr(src), ip_bits(src), + tmp, sizeof(tmp)) < 0) + { + elog(ERROR, "unable to print address (%s)", strerror(errno)); + return (NULL); + } + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "unknown address family (%d)", ip_family(src)); + return (NULL); + } + dst = palloc(strlen(tmp) + 1); + if (dst == NULL) + { + elog(ERROR, "unable to allocate memory in inet_out()"); + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +/* + * Boolean tests for magnitude. Add V4/V6 testing! + */ + +bool +inet_lt(inet *a1, inet *a2) +{ + if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) + { + int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)); + + return ((order < 0) || ((order == 0) && (ip_bits(a1) < ip_bits(a2)))); + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "cannot compare address families %d and %d", + ip_family(a1), ip_family(a2)); + return (FALSE); + } +} + +bool +inet_le(inet *a1, inet *a2) +{ + return (inet_lt(a1, a2) || inet_eq(a1, a2)); +} + +bool +inet_eq(inet *a1, inet *a2) +{ + if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) + { + return ((ip_bits(a1) == ip_bits(a2)) + && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "cannot compare address families %d and %d", + ip_family(a1), ip_family(a2)); + return (FALSE); + } +} + +bool +inet_ge(inet *a1, inet *a2) +{ + return (inet_gt(a1, a2) || inet_eq(a1, a2)); +} + +bool +inet_gt(inet *a1, inet *a2) +{ + if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) + { + int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)); + + return ((order > 0) || ((order == 0) && (ip_bits(a1) > ip_bits(a2)))); + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "cannot compare address families %d and %d", + ip_family(a1), ip_family(a2)); + return (FALSE); + } +} + +bool +inet_ne(inet *a1, inet *a2) +{ + return (!inet_eq(a1, a2)); +} + +bool +inet_sub(inet *a1, inet *a2) +{ + if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) + { + return ((ip_bits(a1) > ip_bits(a2)) + && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0)); + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "cannot compare address families %d and %d", + ip_family(a1), ip_family(a2)); + return (FALSE); + } +} + +bool +inet_subeq(inet *a1, inet *a2) +{ + if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) + { + return ((ip_bits(a1) >= ip_bits(a2)) + && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0)); + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "cannot compare address families %d and %d", + ip_family(a1), ip_family(a2)); + return (FALSE); + } +} + +bool +inet_sup(inet *a1, inet *a2) +{ + if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) + { + return ((ip_bits(a1) < ip_bits(a2)) + && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "cannot compare address families %d and %d", + ip_family(a1), ip_family(a2)); + return (FALSE); + } +} + +bool +inet_supeq(inet *a1, inet *a2) +{ + if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) + { + return ((ip_bits(a1) <= ip_bits(a2)) + && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "cannot compare address families %d and %d", + ip_family(a1), ip_family(a2)); + return (FALSE); + } +} + +/* + * Comparison function for sorting. Add V4/V6 testing! + */ + +int4 +inet_cmp(inet *a1, inet *a2) +{ + if (ntohl(ip_v4addr(a1)) < ntohl(ip_v4addr(a2))) + return (-1); + else if (ntohl(ip_v4addr(a1)) > ntohl(ip_v4addr(a2))) + return (1); + return 0; +} + +/* + * Bitwise comparison for V4 addresses. Add V6 implementation! + */ + +static int +v4bitncmp(unsigned int a1, unsigned int a2, int bits) +{ + unsigned long mask = 0; + int i; + + for (i = 0; i < bits; i++) + mask = (mask >> 1) | 0x80000000; + a1 = ntohl(a1); + a2 = ntohl(a2); + if ((a1 & mask) < (a2 & mask)) + return (-1); + else if ((a1 & mask) > (a2 & mask)) + return (1); + return (0); +} diff --git a/src/backend/utils/adt/ip.c b/src/backend/utils/adt/ip.c deleted file mode 100644 index 9b4ede1c64..0000000000 --- a/src/backend/utils/adt/ip.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * PostgreSQL type definitions for IP addresses. This - * is for IP V4 CIDR notation, but prepared for V6: just - * add the necessary bits where the comments indicate. - * - * $Id: ip.c,v 1.4 1998/10/04 16:24:30 momjian Exp $ - */ - -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -/* - * Access macros. Add IPV6 support. - */ - -#define ip_addrsize(ipaddrptr) \ - (((ipaddr_struct *)VARDATA(ipaddrptr))->family == AF_INET ? 4 : -1) - -#define ip_family(ipaddrptr) \ - (((ipaddr_struct *)VARDATA(ipaddrptr))->family) - -#define ip_bits(ipaddrptr) \ - (((ipaddr_struct *)VARDATA(ipaddrptr))->bits) - -#define ip_v4addr(ipaddrptr) \ - (((ipaddr_struct *)VARDATA(ipaddrptr))->addr.ipv4_addr) - -/* - * IP address reader. - */ - -ipaddr * -ipaddr_in(char *src) -{ - int bits; - ipaddr *dst; - - dst = palloc(VARHDRSZ + sizeof(ipaddr_struct)); - if (dst == NULL) - { - elog(ERROR, "unable to allocate memory in ipaddr_in()"); - return (NULL); - } - /* First, try for an IP V4 address: */ - ip_family(dst) = AF_INET; - bits = inet_net_pton(ip_family(dst), src, &ip_v4addr(dst), ip_addrsize(dst)); - if ((bits < 0) || (bits > 32)) - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "could not parse \"%s\"", src); - pfree(dst); - return (NULL); - } - VARSIZE(dst) = VARHDRSZ - + ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst)) - + ip_addrsize(dst); - ip_bits(dst) = bits; - return (dst); -} - -/* - * IP address output function. - */ - -char * -ipaddr_out(ipaddr *src) -{ - char *dst, - tmp[sizeof("255.255.255.255/32")]; - - if (ip_family(src) == AF_INET) - { - /* It's an IP V4 address: */ - if (inet_net_ntop(AF_INET, &ip_v4addr(src), ip_bits(src), - tmp, sizeof(tmp)) < 0) - { - elog(ERROR, "unable to print address (%s)", strerror(errno)); - return (NULL); - } - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "unknown address family (%d)", ip_family(src)); - return (NULL); - } - dst = palloc(strlen(tmp) + 1); - if (dst == NULL) - { - elog(ERROR, "unable to allocate memory in ipaddr_out()"); - return (NULL); - } - strcpy(dst, tmp); - return (dst); -} - -/* - * Boolean tests for magnitude. Add V4/V6 testing! - */ - -bool -ipaddr_lt(ipaddr *a1, ipaddr *a2) -{ - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)); - - return ((order < 0) || ((order == 0) && (ip_bits(a1) < ip_bits(a2)))); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return (FALSE); - } -} - -bool -ipaddr_le(ipaddr *a1, ipaddr *a2) -{ - return (ipaddr_lt(a1, a2) || ipaddr_eq(a1, a2)); -} - -bool -ipaddr_eq(ipaddr *a1, ipaddr *a2) -{ - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - return ((ip_bits(a1) == ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return (FALSE); - } -} - -bool -ipaddr_ge(ipaddr *a1, ipaddr *a2) -{ - return (ipaddr_gt(a1, a2) || ipaddr_eq(a1, a2)); -} - -bool -ipaddr_gt(ipaddr *a1, ipaddr *a2) -{ - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)); - - return ((order > 0) || ((order == 0) && (ip_bits(a1) > ip_bits(a2)))); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return (FALSE); - } -} - -bool -ipaddr_ne(ipaddr *a1, ipaddr *a2) -{ - return (!ipaddr_eq(a1, a2)); -} - -bool -ipaddr_sub(ipaddr *a1, ipaddr *a2) -{ - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - return ((ip_bits(a1) > ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0)); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return (FALSE); - } -} - -bool -ipaddr_subeq(ipaddr *a1, ipaddr *a2) -{ - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - return ((ip_bits(a1) >= ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0)); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return (FALSE); - } -} - -bool -ipaddr_sup(ipaddr *a1, ipaddr *a2) -{ - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - return ((ip_bits(a1) < ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return (FALSE); - } -} - -bool -ipaddr_supeq(ipaddr *a1, ipaddr *a2) -{ - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - return ((ip_bits(a1) <= ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return (FALSE); - } -} - -/* - * Comparison function for sorting. Add V4/V6 testing! - */ - -int4 -ipaddr_cmp(ipaddr *a1, ipaddr *a2) -{ - if (ntohl(ip_v4addr(a1)) < ntohl(ip_v4addr(a2))) - return (-1); - else if (ntohl(ip_v4addr(a1)) > ntohl(ip_v4addr(a2))) - return (1); - return 0; -} - -/* - * Bitwise comparison for V4 addresses. Add V6 implementation! - */ - -int -v4bitncmp(unsigned int a1, unsigned int a2, int bits) -{ - unsigned long mask = 0; - int i; - - for (i = 0; i < bits; i++) - mask = (mask >> 1) | 0x80000000; - a1 = ntohl(a1); - a2 = ntohl(a2); - if ((a1 & mask) < (a2 & mask)) - return (-1); - else if ((a1 & mask) > (a2 & mask)) - return (1); - return (0); -} diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c index 6d33f148dc..488f1dd11a 100644 --- a/src/backend/utils/adt/mac.c +++ b/src/backend/utils/adt/mac.c @@ -1,7 +1,7 @@ /* * PostgreSQL type definitions for MAC addresses. * - * $Id: mac.c,v 1.3 1998/10/04 16:24:32 momjian Exp $ + * $Id: mac.c,v 1.4 1998/10/08 00:19:36 momjian Exp $ */ #include @@ -10,7 +10,7 @@ #include #include #include -#include +#include manufacturer manufacturers[] = { {0x00, 0x00, 0x0C, "Cisco"}, -- cgit v1.2.1