inet increment w/ int8 - Mailing list pgsql-hackers

From Ilya A. Kovalenko
Subject inet increment w/ int8
Date
Msg-id 17534258300.20050418042534@oganer.net
Whole thread Raw
Responses Re: inet increment w/ int8
Re: inet increment w/ int8
List pgsql-hackers
Greetings,
 I suggest function for "inet" increment w/ int8 (signed).

FUNCTION inet_inc(int, int8) RETURNS inet

Function, useful for making address pools (using also
existing "inet" compare functions to trap boundaries).

Notes: This version lets address wrap around 0-*ff boundary. Uses couple of non-POSIX functions - betoh64() and
htobe64()Tested on i386 with OpenBSD 3.7 PostgreSQL 8.0.2
 

-----------------------------------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "postgres.h"                   /* general Postgres declarations */

#include "fmgr.h"                       /* for argument/result macros */
#include "utils/inet.h"

Datum           inet_inc(PG_FUNCTION_ARGS);

//------ stolen from backend/utils/adt/network.c --------

#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)
#define ip_maxbits(inetptr) \       (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)

static int
ip_addrsize(inet *inetptr)
{       switch (ip_family(inetptr))       {               case PGSQL_AF_INET:                       return 4;
   case PGSQL_AF_INET6:                       return 16;               default:                       return 0;
}
}
//-------------------------------------------------------

PG_FUNCTION_INFO_V1(inet_inc);

Datum
inet_inc(PG_FUNCTION_ARGS)
{  inet    *src = PG_GETARG_INET_P(0);  int64    arg = PG_GETARG_INT64(1);  inet    *dst;  uint64   wsp;

// allocate destination structure  dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));

// copy to destination  *((inet_struct *)VARDATA(dst)) = *((inet_struct *)VARDATA(src));
  if (ip_family(dst) == PGSQL_AF_INET)  {
// Increment v4 address w/ item truncated to 32 bits     *((uint32*)(ip_addr(dst))) =
htonl(ntohl(*((int32*)(ip_addr(dst))))+ (int32)arg);  }  else  {
 
// Increment v6 address low qword (store to workspace)     wsp = htobe64(betoh64(*((int64*)(ip_addr(dst) + 8))) + arg);
   *((uint64*)(ip_addr(dst) + 8)) = wsp;
 

// Carry/borrow high qword     if ( arg > 0 && wsp < *((uint64*)(ip_addr(src) + 8)) )     {  *((int64*)(ip_addr(dst)))
=           htobe64(betoh64(*((int64*)(ip_addr(dst)))) + 1);     }     else        if ( arg < 0 && wsp >
*((uint64*)(ip_addr(src)+ 8)) )        {  *((int64*)(ip_addr(dst))) =
htobe64(betoh64(*((int64*)(ip_addr(dst))))- 1);        }  }
 

// Return result  VARATT_SIZEP(dst) = VARHDRSZ         + ((char *) ip_addr(dst) - (char *) VARDATA(dst))         +
ip_addrsize(dst);
  PG_RETURN_INET_P(dst);

}
-----------------------------------------------------

Thank you

Ilya A. Kovalenko         (mailto:shadow@oganer.net)
SpecialEQ SW section
JSC Oganer-Service

P.S. Treat as Public Domain



pgsql-hackers by date:

Previous
From: elein@varlena.com (elein)
Date:
Subject: Re: argtype_inherit() is dead code
Next
From: "Jim C. Nasby"
Date:
Subject: Re: argtype_inherit() is dead code