From: Bruce Momjian Date: Fri, 21 Mar 2003 21:54:29 +0000 (+0000) Subject: Add hostmask() function: X-Git-Tag: REL7_4_BETA1~860 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e02f818311d845781da2d03d6c5090346cdd02bc;p=postgresql Add hostmask() function: + hostmask(inet) + inet + construct hostmask for network + hostmask('192.168.23.20/30') + 0.0.0.3 Greg Wickham --- diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 27966276d0..4e7631bd22 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,5 +1,5 @@ @@ -5899,6 +5899,13 @@ SELECT TIMESTAMP 'now'; netmask('192.168.1.5/24') 255.255.255.0 + + hostmask(inet) + inet + construct hostmask for network + hostmask('192.168.23.20/30') + 0.0.0.3 + network(inet) cidr diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c index 5757a3c1fa..92229d3818 100644 --- a/src/backend/utils/adt/network.c +++ b/src/backend/utils/adt/network.c @@ -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.38 2002/11/13 00:39:47 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.39 2003/03/21 21:54:29 momjian Exp $ * * Jon Postel RIP 16 Oct 1998 */ @@ -605,6 +605,46 @@ network_netmask(PG_FUNCTION_ARGS) PG_RETURN_INET_P(dst); } +Datum +network_hostmask(PG_FUNCTION_ARGS) +{ + inet *ip = PG_GETARG_INET_P(0); + 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: */ + unsigned long mask = 0xffffffff; + + /* + * Only shift if the mask len is < 32 bits .. + */ + + if (ip_bits(ip) < 32) + mask >>= ip_bits(ip); + else + mask = 0; + + 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)); + + ip_family(dst) = ip_family(ip); + ip_type(dst) = 0; + VARATT_SIZEP(dst) = VARHDRSZ + + ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst)) + + ip_addrsize(dst); + + PG_RETURN_INET_P(dst); +} /* * Convert a value of a network datatype to an approximate scalar value. diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 835d6f2b5b..ff9f65d962 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_proc.h,v 1.289 2003/03/20 18:58:02 momjian Exp $ + * $Id: pg_proc.h,v 1.290 2003/03/21 21:54:29 momjian Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -2358,6 +2358,8 @@ DATA(insert OID = 699 ( host PGNSP PGUID 12 f f t f i 1 25 "869" network_ho DESCR("show address octets only"); DATA(insert OID = 730 ( text PGNSP PGUID 12 f f t f i 1 25 "869" network_show - _null_ )); DESCR("show all parts of inet/cidr value"); +DATA(insert OID = 1362 ( hostmask PGNSP PGUID 12 f f t f i 1 869 "869" network_hostmask - _null_ )); +DESCR("hostmask of address"); DATA(insert OID = 1713 ( inet PGNSP PGUID 12 f f t f i 1 869 "25" text_inet - _null_ )); DESCR("text to inet"); DATA(insert OID = 1714 ( cidr PGNSP PGUID 12 f f t f i 1 650 "25" text_cidr - _null_ ));