contrib/xinetops for 8.1 "patch" - Mailing list pgsql-patches

From Stephen R. van den Berg
Subject contrib/xinetops for 8.1 "patch"
Date
Msg-id 20051113115228.GA22593@cuci.nl
Whole thread Raw
Responses Re: contrib/xinetops for 8.1 "patch"  (Bruce Momjian <pgman@candle.pha.pa.us>)
List pgsql-patches
I've been meaning to send it in for a while now, IMHO it could be
made part of the main distribution as well, but contrib is fine
if not everyone likes it.

I included the source in patch-format, since I didn't feel comfortable
attaching a tar.gz file on this list.
Below is an excerpt from the included README:
-------------------------------- cut here ---------------------------------
inet extended operations
~~~~~~~~~~~~~~~~~~~~~~~~

This directory contains definitions for extended operators on the
inet data type.

Operators available are:

   ~ & | + -

It supports the "natural" arithmetic with IP addresses and integers.
It is useful for applications which have to hand out and administer
ranges of IP-addresses (like a Radius or DHCP server).

Copyright (c) 2003-2006, Stephen R. van den Berg, The Netherlands.
             <srb@cuci.nl>

This module is distributed under the same BSD license as PostgreSQL.
-------------------------------- cut here ---------------------------------

diff -ur xinetops.old/Makefile xinetops/Makefile
--- xinetops.old/Makefile    2005-11-13 12:36:39.000000000 +0100
+++ xinetops/Makefile    2005-11-13 12:45:04.000000000 +0100
@@ -0,0 +1,11 @@
+# $Id: Makefile 523 2005-11-13 11:29:44Z srb $
+
+subdir = contrib/xinetops
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+
+MODULES = xinetops
+DATA_built = xinetops.sql
+DOCS = README.xinetops
+
+include $(top_srcdir)/contrib/contrib-global.mk
diff -ur xinetops.old/README.xinetops xinetops/README.xinetops
--- xinetops.old/README.xinetops    2005-11-13 12:36:39.000000000 +0100
+++ xinetops/README.xinetops    2005-11-13 12:45:04.000000000 +0100
@@ -0,0 +1,19 @@
+
+inet extended operations
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+This directory contains definitions for extended operators on the
+inet data type.
+
+Operators available are:
+
+   ~ & | + -
+
+It supports the "natural" arithmetic with IP addresses and integers.
+It is useful for applications which have to hand out and administer
+ranges of IP-addresses (like a Radius or DHCP server).
+
+Copyright (c) 2003-2006, Stephen R. van den Berg, The Netherlands.
+             <srb@cuci.nl>
+
+This module is distributed under the same BSD license as PostgreSQL.
diff -ur xinetops.old/xinetops.c xinetops/xinetops.c
--- xinetops.old/xinetops.c    2005-11-13 12:36:39.000000000 +0100
+++ xinetops/xinetops.c    2005-11-13 12:45:04.000000000 +0100
@@ -0,0 +1,254 @@
+/*
+ *    PostgreSQL type definitions for extended inet operations.
+ *    Copyright (c) 2003-2006, S.R. van den Berg, The Netherlands
+ *                 <srb@cuci.nl>
+ *
+ *      This module is distributed under the same BSD license as PostgreSQL.
+ *
+ *    $Id: xinetops.c 524 2005-11-13 11:44:43Z srb $
+ */
+
+#include "postgres.h"
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "catalog/pg_type.h"
+#include "utils/builtins.h"
+#include "utils/inet.h"
+
+#define ip_family(inetptr) \
+        (((inet_struct *)VARDATA(inetptr))->family)
+
+#define ip_bits(inetptr) \
+        (((inet_struct *)VARDATA(inetptr))->bits)
+
+#define ip_type(inetptr) \
+        (((inet_struct *)VARDATA(inetptr))->type)
+
+#define ip_addr(inetptr) \
+        (((inet_struct *)VARDATA(inetptr))->ipaddr)
+
+static int
+ip_addrsize(inet *inetptr)
+{
+        switch (ip_family(inetptr))
+        {
+                case PGSQL_AF_INET:
+                        return 4;
+                case PGSQL_AF_INET6:
+                        return 16;
+                default:
+                        return -1;
+        }
+}
+
+
+PG_FUNCTION_INFO_V1(inet_not);
+
+Datum
+inet_not(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));
+
+        {
+           int nb = ip_addrsize(ip);
+           unsigned char*pip = ip_addr(ip);
+           unsigned char*pdst = ip_addr(dst);
+
+           while (nb-->0)
+           {
+            pdst[nb] = pip[nb];
+           }
+        }
+    ip_bits(dst) = ip_bits(ip);
+
+    ip_family(dst) = ip_family(ip);
+    ip_type(dst) = 0;
+    VARATT_SIZEP(dst) = VARHDRSZ
+        + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+        + ip_addrsize(dst);
+
+    PG_RETURN_INET_P(dst);
+}
+
+PG_FUNCTION_INFO_V1(inet_or);
+
+Datum
+inet_or(PG_FUNCTION_ARGS)
+{
+    inet       *ip = PG_GETARG_INET_P(0);
+    inet       *ip2 = PG_GETARG_INET_P(1);
+    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) != ip_family(ip2))
+        elog(ERROR, "mismatch in address family (%d)!=(%d)",
+                ip_family(ip), ip_family(ip2));
+    else
+        {
+           int nb = ip_addrsize(ip);
+           unsigned char*pip = ip_addr(ip);
+           unsigned char*pip2 = ip_addr(ip2);
+           unsigned char*pdst = ip_addr(dst);
+
+           while (nb-->0)
+           {
+            pdst[nb] = pip[nb]|pip2[nb];
+           }
+        }
+    ip_bits(dst) = ip_bits(ip);
+    if (ip_bits(dst)<ip_bits(ip2))
+        ip_bits(dst) = ip_bits(ip2);
+
+    ip_family(dst) = ip_family(ip);
+    ip_type(dst) = 0;
+    VARATT_SIZEP(dst) = VARHDRSZ
+        + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+        + ip_addrsize(dst);
+
+    PG_RETURN_INET_P(dst);
+}
+
+PG_FUNCTION_INFO_V1(inet_and);
+
+Datum
+inet_and(PG_FUNCTION_ARGS)
+{
+    inet       *ip = PG_GETARG_INET_P(0);
+    inet       *ip2 = PG_GETARG_INET_P(1);
+    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) != ip_family(ip2))
+        elog(ERROR, "mismatch in address family (%d)!=(%d)",
+                ip_family(ip), ip_family(ip2));
+    else
+        {
+           int nb = ip_addrsize(ip);
+           unsigned char*pip = ip_addr(ip);
+           unsigned char*pip2 = ip_addr(ip2);
+           unsigned char*pdst = ip_addr(dst);
+
+           while (nb-->0)
+           {
+            pdst[nb] = pip[nb]&pip2[nb];
+           }
+        }
+    ip_bits(dst) = ip_bits(ip);
+    if (ip_bits(dst)<ip_bits(ip2))
+        ip_bits(dst) = ip_bits(ip2);
+
+    ip_family(dst) = ip_family(ip);
+    ip_type(dst) = 0;
+    VARATT_SIZEP(dst) = VARHDRSZ
+        + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+        + ip_addrsize(dst);
+
+    PG_RETURN_INET_P(dst);
+}
+
+PG_FUNCTION_INFO_V1(inet_min);
+
+Datum
+inet_min(PG_FUNCTION_ARGS)
+{
+    inet       *ip = PG_GETARG_INET_P(0);
+    inet       *ip2 = PG_GETARG_INET_P(1);
+    int       res = 0;
+
+    if (ip_family(ip) != ip_family(ip2))
+        elog(ERROR, "mismatch in address family (%d)!=(%d)",
+                ip_family(ip), ip_family(ip2));
+    else
+        {
+           int nb = ip_addrsize(ip);
+           unsigned char*pip = ip_addr(ip);
+           unsigned char*pip2 = ip_addr(ip2);
+           unsigned sh = 1;
+
+           while (nb-->0)
+           {
+            res += sh*(pip[nb]-pip2[nb]);
+            sh <<= 8;
+           }
+        }
+
+    PG_RETURN_INT32(res);
+}
+
+static Datum
+i_inet_plusi(inet *ip, int iarg)
+{
+    inet       *dst;
+
+    dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
+    /* make sure any unused bits are zeroed */
+    MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
+
+        {
+           int nb = ip_addrsize(ip);
+           unsigned char*pip = ip_addr(ip);
+           unsigned char*pdst = ip_addr(dst);
+           int carry = 0;
+
+           while (nb-->0)
+           {
+            pdst[nb] = carry = pip[nb]+iarg+carry;
+            iarg >>=8;
+            carry >>=8;
+           }
+        }
+        ip_bits(dst) = ip_bits(ip);
+
+    ip_family(dst) = ip_family(ip);
+    ip_type(dst) = 0;
+    VARATT_SIZEP(dst) = VARHDRSZ
+        + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+        + ip_addrsize(dst);
+
+    PG_RETURN_INET_P(dst);
+}
+
+PG_FUNCTION_INFO_V1(inet_plusi);
+
+Datum
+inet_plusi(PG_FUNCTION_ARGS)
+{
+    inet       *ip = PG_GETARG_INET_P(0);
+    int       iarg = PG_GETARG_INT32(1);
+    return i_inet_plusi(ip,iarg);
+}
+
+PG_FUNCTION_INFO_V1(inet_iplus);
+
+Datum
+inet_iplus(PG_FUNCTION_ARGS)
+{
+    int       iarg = PG_GETARG_INT32(0);
+    inet       *ip = PG_GETARG_INET_P(1);
+    return i_inet_plusi(ip,iarg);
+}
+
+PG_FUNCTION_INFO_V1(inet_mini);
+
+Datum
+inet_mini(PG_FUNCTION_ARGS)
+{
+    inet       *ip = PG_GETARG_INET_P(0);
+    int       iarg = PG_GETARG_INT32(1);
+    return i_inet_plusi(ip,-iarg);
+}
diff -ur xinetops.old/xinetops.sql.in xinetops/xinetops.sql.in
--- xinetops.old/xinetops.sql.in    2005-11-13 12:36:39.000000000 +0100
+++ xinetops/xinetops.sql.in    2005-11-13 12:45:04.000000000 +0100
@@ -0,0 +1,104 @@
+--
+--    PostgreSQL type definitions for extended inet operations.
+--      Copyright (c) 2003-2006, S.R. van den Berg, The Netherlands
+--                               <srb@cuci.nl>
+--
+--      This module is distributed under the same BSD license as PostgreSQL.
+--
+--    $Id: xinetops.sql.in 524 2005-11-13 11:44:43Z srb $
+--
+
+-- Adjust this setting to control where the objects get created.
+SET search_path = public;
+
+SET autocommit TO 'on';
+
+--
+--    The various functions doing the work
+--
+
+CREATE FUNCTION inet_not(inet)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_or(inet, inet)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_and(inet, inet)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_plusi(inet, int)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_iplus(int, inet)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_mini(inet, int)
+RETURNS inet
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+CREATE FUNCTION inet_min(inet, inet)
+RETURNS int
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
+--
+--    Now the operators.
+--
+
+CREATE OPERATOR ~ (
+    RIGHTARG = inet,
+    PROCEDURE = inet_not
+);
+
+CREATE OPERATOR | (
+    LEFTARG = inet,
+    RIGHTARG = inet,
+    COMMUTATOR = |,
+    PROCEDURE = inet_or
+);
+
+CREATE OPERATOR & (
+    LEFTARG = inet,
+    RIGHTARG = inet,
+    COMMUTATOR = &,
+    PROCEDURE = inet_and
+);
+
+CREATE OPERATOR + (
+    LEFTARG = inet,
+    RIGHTARG = int,
+    COMMUTATOR = +,
+    PROCEDURE = inet_plusi
+);
+
+CREATE OPERATOR + (
+    LEFTARG = int,
+    RIGHTARG = inet,
+    COMMUTATOR = +,
+    PROCEDURE = inet_iplus
+);
+
+CREATE OPERATOR - (
+    LEFTARG = inet,
+    RIGHTARG = int,
+    COMMUTATOR = -,
+    PROCEDURE = inet_mini
+);
+
+CREATE OPERATOR - (
+    LEFTARG = inet,
+    RIGHTARG = inet,
+    COMMUTATOR = -,
+    PROCEDURE = inet_min
+);
--
Sincerely,                                                          srb@cuci.nl
           Stephen R. van den Berg (AKA BuGless).

Skiing beyond this point may result in death and/or loss of skiing privileges.

pgsql-patches by date:

Previous
From: Qingqing Zhou
Date:
Subject: Re: Add missing const qualifier in ECPG
Next
From: Andrew Dunstan
Date:
Subject: drop if exists