Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions

network.c File Reference

#include "postgres.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "access/hash.h"
#include "catalog/pg_type.h"
#include "libpq/ip.h"
#include "libpq/libpq-be.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/inet.h"
Include dependency graph for network.c:

Go to the source code of this file.

Defines

#define ip_family(inetptr)   (((inet_struct *) VARDATA_ANY(inetptr))->family)
#define ip_bits(inetptr)   (((inet_struct *) VARDATA_ANY(inetptr))->bits)
#define ip_addr(inetptr)   (((inet_struct *) VARDATA_ANY(inetptr))->ipaddr)
#define ip_maxbits(inetptr)   (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
#define SET_INET_VARSIZE(dst)

Functions

static int32 network_cmp_internal (inet *a1, inet *a2)
static int bitncmp (void *l, void *r, int n)
static bool addressOK (unsigned char *a, int bits, int family)
static int ip_addrsize (inet *inetptr)
static inetinternal_inetpl (inet *ip, int64 addend)
static inetnetwork_in (char *src, bool is_cidr)
Datum inet_in (PG_FUNCTION_ARGS)
Datum cidr_in (PG_FUNCTION_ARGS)
static char * network_out (inet *src, bool is_cidr)
Datum inet_out (PG_FUNCTION_ARGS)
Datum cidr_out (PG_FUNCTION_ARGS)
static inetnetwork_recv (StringInfo buf, bool is_cidr)
Datum inet_recv (PG_FUNCTION_ARGS)
Datum cidr_recv (PG_FUNCTION_ARGS)
static byteanetwork_send (inet *addr, bool is_cidr)
Datum inet_send (PG_FUNCTION_ARGS)
Datum cidr_send (PG_FUNCTION_ARGS)
Datum inet_to_cidr (PG_FUNCTION_ARGS)
Datum inet_set_masklen (PG_FUNCTION_ARGS)
Datum cidr_set_masklen (PG_FUNCTION_ARGS)
Datum network_cmp (PG_FUNCTION_ARGS)
Datum network_lt (PG_FUNCTION_ARGS)
Datum network_le (PG_FUNCTION_ARGS)
Datum network_eq (PG_FUNCTION_ARGS)
Datum network_ge (PG_FUNCTION_ARGS)
Datum network_gt (PG_FUNCTION_ARGS)
Datum network_ne (PG_FUNCTION_ARGS)
Datum hashinet (PG_FUNCTION_ARGS)
Datum network_sub (PG_FUNCTION_ARGS)
Datum network_subeq (PG_FUNCTION_ARGS)
Datum network_sup (PG_FUNCTION_ARGS)
Datum network_supeq (PG_FUNCTION_ARGS)
Datum network_host (PG_FUNCTION_ARGS)
Datum network_show (PG_FUNCTION_ARGS)
Datum inet_abbrev (PG_FUNCTION_ARGS)
Datum cidr_abbrev (PG_FUNCTION_ARGS)
Datum network_masklen (PG_FUNCTION_ARGS)
Datum network_family (PG_FUNCTION_ARGS)
Datum network_broadcast (PG_FUNCTION_ARGS)
Datum network_network (PG_FUNCTION_ARGS)
Datum network_netmask (PG_FUNCTION_ARGS)
Datum network_hostmask (PG_FUNCTION_ARGS)
double convert_network_to_scalar (Datum value, Oid typid)
Datum network_scan_first (Datum in)
Datum network_scan_last (Datum in)
Datum inet_client_addr (PG_FUNCTION_ARGS)
Datum inet_client_port (PG_FUNCTION_ARGS)
Datum inet_server_addr (PG_FUNCTION_ARGS)
Datum inet_server_port (PG_FUNCTION_ARGS)
Datum inetnot (PG_FUNCTION_ARGS)
Datum inetand (PG_FUNCTION_ARGS)
Datum inetor (PG_FUNCTION_ARGS)
Datum inetpl (PG_FUNCTION_ARGS)
Datum inetmi_int8 (PG_FUNCTION_ARGS)
Datum inetmi (PG_FUNCTION_ARGS)
void clean_ipv6_addr (int addr_family, char *addr)

Define Documentation

#define ip_addr (   inetptr  )     (((inet_struct *) VARDATA_ANY(inetptr))->ipaddr)
#define ip_bits (   inetptr  )     (((inet_struct *) VARDATA_ANY(inetptr))->bits)
#define ip_family (   inetptr  )     (((inet_struct *) VARDATA_ANY(inetptr))->family)
#define ip_maxbits (   inetptr  )     (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
#define SET_INET_VARSIZE (   dst  ) 

Function Documentation

static bool addressOK ( unsigned char *  a,
int  bits,
int  family 
) [static]

Definition at line 995 of file network.c.

References Assert, and PGSQL_AF_INET.

Referenced by network_in(), and network_recv().

{
    int         byte;
    int         nbits;
    int         maxbits;
    int         maxbytes;
    unsigned char mask;

    if (family == PGSQL_AF_INET)
    {
        maxbits = 32;
        maxbytes = 4;
    }
    else
    {
        maxbits = 128;
        maxbytes = 16;
    }
    Assert(bits <= maxbits);

    if (bits == maxbits)
        return true;

    byte = bits / 8;

    nbits = bits % 8;
    mask = 0xff;
    if (bits != 0)
        mask >>= nbits;

    while (byte < maxbytes)
    {
        if ((a[byte] & mask) != 0)
            return false;
        mask = 0xff;
        byte++;
    }

    return true;
}

static int bitncmp ( void *  l,
void *  r,
int  n 
) [static]

Definition at line 966 of file network.c.

References IS_HIGHBIT_SET, and memcmp().

Referenced by network_cmp_internal(), network_sub(), network_subeq(), network_sup(), and network_supeq().

{
    u_int       lb,
                rb;
    int         x,
                b;

    b = n / 8;
    x = memcmp(l, r, b);
    if (x || (n % 8) == 0)
        return x;

    lb = ((const u_char *) l)[b];
    rb = ((const u_char *) r)[b];
    for (b = n % 8; b > 0; b--)
    {
        if (IS_HIGHBIT_SET(lb) != IS_HIGHBIT_SET(rb))
        {
            if (IS_HIGHBIT_SET(lb))
                return 1;
            return -1;
        }
        lb <<= 1;
        rb <<= 1;
    }
    return 0;
}

Datum cidr_abbrev ( PG_FUNCTION_ARGS   ) 

Definition at line 670 of file network.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, inet_cidr_ntop(), ip_addr, ip_bits, ip_family, NULL, PG_GETARG_INET_PP, and PG_RETURN_TEXT_P.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    char       *dst;
    char        tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];

    dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),
                         ip_bits(ip), tmp, sizeof(tmp));

    if (dst == NULL)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("could not format cidr value: %m")));

    PG_RETURN_TEXT_P(cstring_to_text(tmp));
}

Datum cidr_in ( PG_FUNCTION_ARGS   ) 

Definition at line 137 of file network.c.

References network_in(), PG_GETARG_CSTRING, and PG_RETURN_INET_P.

{
    char       *src = PG_GETARG_CSTRING(0);

    PG_RETURN_INET_P(network_in(src, true));
}

Datum cidr_out ( PG_FUNCTION_ARGS   ) 

Definition at line 181 of file network.c.

References network_out(), PG_GETARG_INET_PP, and PG_RETURN_CSTRING.

Datum cidr_recv ( PG_FUNCTION_ARGS   ) 
Datum cidr_send ( PG_FUNCTION_ARGS   ) 

Definition at line 308 of file network.c.

References network_send(), PG_GETARG_INET_PP, and PG_RETURN_BYTEA_P.

{
    inet       *addr = PG_GETARG_INET_PP(0);

    PG_RETURN_BYTEA_P(network_send(addr, true));
}

Datum cidr_set_masklen ( PG_FUNCTION_ARGS   ) 

Definition at line 382 of file network.c.

References ereport, errcode(), errmsg(), ERROR, ip_addr, ip_addrsize(), ip_bits, ip_maxbits, palloc(), PG_GETARG_INET_PP, PG_GETARG_INT32, PG_RETURN_INET_P, and VARSIZE_ANY.

{
    inet       *src = PG_GETARG_INET_PP(0);
    int         bits = PG_GETARG_INT32(1);
    inet       *dst;
    int         byte;
    int         nbits;
    int         maxbytes;

    if (bits == -1)
        bits = ip_maxbits(src);

    if ((bits < 0) || (bits > ip_maxbits(src)))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("invalid mask length: %d", bits)));

    /* clone the original data */
    dst = (inet *) palloc(VARSIZE_ANY(src));
    memcpy(dst, src, VARSIZE_ANY(src));

    ip_bits(dst) = bits;

    /* zero out any bits to the right of the new netmask */
    byte = bits / 8;

    nbits = bits % 8;
    /* clear the first byte, this might be a partial byte */
    if (nbits != 0)
    {
        ip_addr(dst)[byte] &= ~(0xFF >> nbits);
        byte++;
    }
    /* clear remaining bytes */
    maxbytes = ip_addrsize(dst);
    while (byte < maxbytes)
    {
        ip_addr(dst)[byte] = 0;
        byte++;
    }

    PG_RETURN_INET_P(dst);
}

void clean_ipv6_addr ( int  addr_family,
char *  addr 
)

Definition at line 1457 of file network.c.

Referenced by inet_client_addr(), inet_server_addr(), pg_stat_get_activity(), and pg_stat_get_backend_client_addr().

{
#ifdef HAVE_IPV6
    if (addr_family == AF_INET6)
    {
        char       *pct = strchr(addr, '%');

        if (pct)
            *pct = '\0';
    }
#endif
}

double convert_network_to_scalar ( Datum  value,
Oid  typid 
)

Definition at line 903 of file network.c.

References macaddr::a, macaddr::b, macaddr::c, CIDROID, macaddr::d, DatumGetInetPP, DatumGetMacaddrP, macaddr::e, elog, ERROR, macaddr::f, i, INETOID, ip_addr, ip_family, MACADDROID, and PGSQL_AF_INET.

Referenced by convert_to_scalar(), gbt_inet_compress(), and gbt_inet_consistent().

{
    switch (typid)
    {
        case INETOID:
        case CIDROID:
            {
                inet       *ip = DatumGetInetPP(value);
                int         len;
                double      res;
                int         i;

                /*
                 * Note that we don't use the full address for IPv6.
                 */
                if (ip_family(ip) == PGSQL_AF_INET)
                    len = 4;
                else
                    len = 5;

                res = ip_family(ip);
                for (i = 0; i < len; i++)
                {
                    res *= 256;
                    res += ip_addr(ip)[i];
                }
                return res;

                break;
            }
        case MACADDROID:
            {
                macaddr    *mac = DatumGetMacaddrP(value);
                double      res;

                res = (mac->a << 16) | (mac->b << 8) | (mac->c);
                res *= 256 * 256 * 256;
                res += (mac->d << 16) | (mac->e << 8) | (mac->f);
                return res;
            }
    }

    /*
     * Can't get here unless someone tries to use scalarltsel/scalargtsel on
     * an operator with one network and one non-network operand.
     */
    elog(ERROR, "unsupported type: %u", typid);
    return 0;
}

Datum hashinet ( PG_FUNCTION_ARGS   ) 

Definition at line 527 of file network.c.

References hash_any(), ip_addrsize(), PG_GETARG_INET_PP, and VARDATA_ANY.

{
    inet       *addr = PG_GETARG_INET_PP(0);
    int         addrsize = ip_addrsize(addr);

    /* XXX this assumes there are no pad bytes in the data structure */
    return hash_any((unsigned char *) VARDATA_ANY(addr), addrsize + 2);
}

Datum inet_abbrev ( PG_FUNCTION_ARGS   ) 

Definition at line 652 of file network.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, inet_net_ntop(), ip_addr, ip_bits, ip_family, NULL, PG_GETARG_INET_PP, and PG_RETURN_TEXT_P.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    char       *dst;
    char        tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];

    dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
                        ip_bits(ip), tmp, sizeof(tmp));

    if (dst == NULL)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("could not format inet value: %m")));

    PG_RETURN_TEXT_P(cstring_to_text(tmp));
}

Datum inet_client_addr ( PG_FUNCTION_ARGS   ) 

Definition at line 1070 of file network.c.

References SockAddr::addr, clean_ipv6_addr(), MyProcPort, network_in(), NI_NUMERICHOST, NI_NUMERICSERV, NULL, pg_getnameinfo_all(), PG_RETURN_INET_P, PG_RETURN_NULL, port, Port::raddr, and SockAddr::salen.

{
    Port       *port = MyProcPort;
    char        remote_host[NI_MAXHOST];
    int         ret;

    if (port == NULL)
        PG_RETURN_NULL();

    switch (port->raddr.addr.ss_family)
    {
        case AF_INET:
#ifdef HAVE_IPV6
        case AF_INET6:
#endif
            break;
        default:
            PG_RETURN_NULL();
    }

    remote_host[0] = '\0';

    ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
                             remote_host, sizeof(remote_host),
                             NULL, 0,
                             NI_NUMERICHOST | NI_NUMERICSERV);
    if (ret != 0)
        PG_RETURN_NULL();

    clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);

    PG_RETURN_INET_P(network_in(remote_host, false));
}

Datum inet_client_port ( PG_FUNCTION_ARGS   ) 

Definition at line 1109 of file network.c.

References SockAddr::addr, CStringGetDatum, DirectFunctionCall1, int4in(), MyProcPort, NI_NUMERICHOST, NI_NUMERICSERV, NULL, pg_getnameinfo_all(), PG_RETURN_DATUM, PG_RETURN_NULL, port, Port::raddr, and SockAddr::salen.

{
    Port       *port = MyProcPort;
    char        remote_port[NI_MAXSERV];
    int         ret;

    if (port == NULL)
        PG_RETURN_NULL();

    switch (port->raddr.addr.ss_family)
    {
        case AF_INET:
#ifdef HAVE_IPV6
        case AF_INET6:
#endif
            break;
        default:
            PG_RETURN_NULL();
    }

    remote_port[0] = '\0';

    ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
                             NULL, 0,
                             remote_port, sizeof(remote_port),
                             NI_NUMERICHOST | NI_NUMERICSERV);
    if (ret != 0)
        PG_RETURN_NULL();

    PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(remote_port)));
}

Datum inet_in ( PG_FUNCTION_ARGS   ) 
Datum inet_out ( PG_FUNCTION_ARGS   ) 

Definition at line 173 of file network.c.

References network_out(), PG_GETARG_INET_PP, and PG_RETURN_CSTRING.

{
    inet       *src = PG_GETARG_INET_PP(0);

    PG_RETURN_CSTRING(network_out(src, false));
}

Datum inet_recv ( PG_FUNCTION_ARGS   ) 
Datum inet_send ( PG_FUNCTION_ARGS   ) 

Definition at line 300 of file network.c.

References network_send(), PG_GETARG_INET_PP, and PG_RETURN_BYTEA_P.

{
    inet       *addr = PG_GETARG_INET_PP(0);

    PG_RETURN_BYTEA_P(network_send(addr, false));
}

Datum inet_server_addr ( PG_FUNCTION_ARGS   ) 

Definition at line 1146 of file network.c.

References SockAddr::addr, clean_ipv6_addr(), Port::laddr, MyProcPort, network_in(), NI_NUMERICHOST, NI_NUMERICSERV, NULL, pg_getnameinfo_all(), PG_RETURN_INET_P, PG_RETURN_NULL, port, and SockAddr::salen.

{
    Port       *port = MyProcPort;
    char        local_host[NI_MAXHOST];
    int         ret;

    if (port == NULL)
        PG_RETURN_NULL();

    switch (port->laddr.addr.ss_family)
    {
        case AF_INET:
#ifdef HAVE_IPV6
        case AF_INET6:
#endif
            break;
        default:
            PG_RETURN_NULL();
    }

    local_host[0] = '\0';

    ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
                             local_host, sizeof(local_host),
                             NULL, 0,
                             NI_NUMERICHOST | NI_NUMERICSERV);
    if (ret != 0)
        PG_RETURN_NULL();

    clean_ipv6_addr(port->laddr.addr.ss_family, local_host);

    PG_RETURN_INET_P(network_in(local_host, false));
}

Datum inet_server_port ( PG_FUNCTION_ARGS   ) 

Definition at line 1185 of file network.c.

References SockAddr::addr, CStringGetDatum, DirectFunctionCall1, int4in(), Port::laddr, MyProcPort, NI_NUMERICHOST, NI_NUMERICSERV, NULL, pg_getnameinfo_all(), PG_RETURN_DATUM, PG_RETURN_NULL, port, and SockAddr::salen.

{
    Port       *port = MyProcPort;
    char        local_port[NI_MAXSERV];
    int         ret;

    if (port == NULL)
        PG_RETURN_NULL();

    switch (port->laddr.addr.ss_family)
    {
        case AF_INET:
#ifdef HAVE_IPV6
        case AF_INET6:
#endif
            break;
        default:
            PG_RETURN_NULL();
    }

    local_port[0] = '\0';

    ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
                             NULL, 0,
                             local_port, sizeof(local_port),
                             NI_NUMERICHOST | NI_NUMERICSERV);
    if (ret != 0)
        PG_RETURN_NULL();

    PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(local_port)));
}

Datum inet_set_masklen ( PG_FUNCTION_ARGS   ) 

Definition at line 358 of file network.c.

References ereport, errcode(), errmsg(), ERROR, ip_bits, ip_maxbits, palloc(), PG_GETARG_INET_PP, PG_GETARG_INT32, PG_RETURN_INET_P, and VARSIZE_ANY.

Referenced by network_scan_last().

{
    inet       *src = PG_GETARG_INET_PP(0);
    int         bits = PG_GETARG_INT32(1);
    inet       *dst;

    if (bits == -1)
        bits = ip_maxbits(src);

    if ((bits < 0) || (bits > ip_maxbits(src)))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("invalid mask length: %d", bits)));

    /* clone the original data */
    dst = (inet *) palloc(VARSIZE_ANY(src));
    memcpy(dst, src, VARSIZE_ANY(src));

    ip_bits(dst) = bits;

    PG_RETURN_INET_P(dst);
}

Datum inet_to_cidr ( PG_FUNCTION_ARGS   ) 

Definition at line 317 of file network.c.

References elog, ERROR, ip_addr, ip_addrsize(), ip_bits, ip_maxbits, palloc(), PG_GETARG_INET_PP, PG_RETURN_INET_P, and VARSIZE_ANY.

{
    inet       *src = PG_GETARG_INET_PP(0);
    inet       *dst;
    int         bits;
    int         byte;
    int         nbits;
    int         maxbytes;

    bits = ip_bits(src);

    /* safety check */
    if ((bits < 0) || (bits > ip_maxbits(src)))
        elog(ERROR, "invalid inet bit length: %d", bits);

    /* clone the original data */
    dst = (inet *) palloc(VARSIZE_ANY(src));
    memcpy(dst, src, VARSIZE_ANY(src));

    /* zero out any bits to the right of the netmask */
    byte = bits / 8;

    nbits = bits % 8;
    /* clear the first byte, this might be a partial byte */
    if (nbits != 0)
    {
        ip_addr(dst)[byte] &= ~(0xFF >> nbits);
        byte++;
    }
    /* clear remaining bytes */
    maxbytes = ip_addrsize(dst);
    while (byte < maxbytes)
    {
        ip_addr(dst)[byte] = 0;
        byte++;
    }

    PG_RETURN_INET_P(dst);
}

Datum inetand ( PG_FUNCTION_ARGS   ) 

Definition at line 1244 of file network.c.

References ereport, errcode(), errmsg(), ERROR, ip_addr, ip_addrsize(), ip_bits, ip_family, Max, palloc0(), PG_GETARG_INET_PP, PG_RETURN_INET_P, and SET_INET_VARSIZE.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    inet       *ip2 = PG_GETARG_INET_PP(1);
    inet       *dst;

    dst = (inet *) palloc0(sizeof(inet));

    if (ip_family(ip) != ip_family(ip2))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("cannot AND inet values of different sizes")));
    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) = Max(ip_bits(ip), ip_bits(ip2));

    ip_family(dst) = ip_family(ip);
    SET_INET_VARSIZE(dst);

    PG_RETURN_INET_P(dst);
}

Datum inetmi ( PG_FUNCTION_ARGS   ) 

Definition at line 1380 of file network.c.

References byte, ereport, errcode(), errmsg(), ERROR, ip_addr, ip_addrsize(), ip_family, PG_GETARG_INET_PP, and PG_RETURN_INT64.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    inet       *ip2 = PG_GETARG_INET_PP(1);
    int64       res = 0;

    if (ip_family(ip) != ip_family(ip2))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("cannot subtract inet values of different sizes")));
    else
    {
        /*
         * We form the difference using the traditional complement, increment,
         * and add rule, with the increment part being handled by starting the
         * carry off at 1.  If you don't think integer arithmetic is done in
         * two's complement, too bad.
         */
        int         nb = ip_addrsize(ip);
        int         byte = 0;
        unsigned char *pip = ip_addr(ip);
        unsigned char *pip2 = ip_addr(ip2);
        int         carry = 1;

        while (nb-- > 0)
        {
            int         lobyte;

            carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;
            lobyte = carry & 0xFF;
            if (byte < sizeof(int64))
            {
                res |= ((int64) lobyte) << (byte * 8);
            }
            else
            {
                /*
                 * Input wider than int64: check for overflow.  All bytes to
                 * the left of what will fit should be 0 or 0xFF, depending on
                 * sign of the now-complete result.
                 */
                if ((res < 0) ? (lobyte != 0xFF) : (lobyte != 0))
                    ereport(ERROR,
                            (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                             errmsg("result is out of range")));
            }
            carry >>= 8;
            byte++;
        }

        /*
         * If input is narrower than int64, overflow is not possible, but we
         * have to do proper sign extension.
         */
        if (carry == 0 && byte < sizeof(int64))
            res |= ((int64) -1) << (byte * 8);
    }

    PG_RETURN_INT64(res);
}

Datum inetmi_int8 ( PG_FUNCTION_ARGS   ) 

Definition at line 1370 of file network.c.

References internal_inetpl(), PG_GETARG_INET_PP, PG_GETARG_INT64, and PG_RETURN_INET_P.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    int64       addend = PG_GETARG_INT64(1);

    PG_RETURN_INET_P(internal_inetpl(ip, -addend));
}

Datum inetnot ( PG_FUNCTION_ARGS   ) 

Definition at line 1219 of file network.c.

References ip_addr, ip_addrsize(), ip_bits, ip_family, palloc0(), PG_GETARG_INET_PP, PG_RETURN_INET_P, and SET_INET_VARSIZE.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    inet       *dst;

    dst = (inet *) palloc0(sizeof(inet));

    {
        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);
    SET_INET_VARSIZE(dst);

    PG_RETURN_INET_P(dst);
}

Datum inetor ( PG_FUNCTION_ARGS   ) 

Definition at line 1276 of file network.c.

References ereport, errcode(), errmsg(), ERROR, ip_addr, ip_addrsize(), ip_bits, ip_family, Max, palloc0(), PG_GETARG_INET_PP, PG_RETURN_INET_P, and SET_INET_VARSIZE.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    inet       *ip2 = PG_GETARG_INET_PP(1);
    inet       *dst;

    dst = (inet *) palloc0(sizeof(inet));

    if (ip_family(ip) != ip_family(ip2))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("cannot OR inet values of different sizes")));
    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) = Max(ip_bits(ip), ip_bits(ip2));

    ip_family(dst) = ip_family(ip);
    SET_INET_VARSIZE(dst);

    PG_RETURN_INET_P(dst);
}

Datum inetpl ( PG_FUNCTION_ARGS   ) 

Definition at line 1360 of file network.c.

References internal_inetpl(), PG_GETARG_INET_PP, PG_GETARG_INT64, and PG_RETURN_INET_P.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    int64       addend = PG_GETARG_INT64(1);

    PG_RETURN_INET_P(internal_inetpl(ip, addend));
}

static inet * internal_inetpl ( inet ip,
int64  addend 
) [static]

Definition at line 1308 of file network.c.

References ereport, errcode(), errmsg(), ERROR, ip_addr, ip_addrsize(), ip_bits, ip_family, palloc0(), and SET_INET_VARSIZE.

Referenced by inetmi_int8(), and inetpl().

{
    inet       *dst;

    dst = (inet *) palloc0(sizeof(inet));

    {
        int         nb = ip_addrsize(ip);
        unsigned char *pip = ip_addr(ip);
        unsigned char *pdst = ip_addr(dst);
        int         carry = 0;

        while (nb-- > 0)
        {
            carry = pip[nb] + (int) (addend & 0xFF) + carry;
            pdst[nb] = (unsigned char) (carry & 0xFF);
            carry >>= 8;

            /*
             * We have to be careful about right-shifting addend because
             * right-shift isn't portable for negative values, while simply
             * dividing by 256 doesn't work (the standard rounding is in the
             * wrong direction, besides which there may be machines out there
             * that round the wrong way).  So, explicitly clear the low-order
             * byte to remove any doubt about the correct result of the
             * division, and then divide rather than shift.
             */
            addend &= ~((int64) 0xFF);
            addend /= 0x100;
        }

        /*
         * At this point we should have addend and carry both zero if original
         * addend was >= 0, or addend -1 and carry 1 if original addend was <
         * 0.  Anything else means overflow.
         */
        if (!((addend == 0 && carry == 0) ||
              (addend == -1 && carry == 1)))
            ereport(ERROR,
                    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                     errmsg("result is out of range")));
    }

    ip_bits(dst) = ip_bits(ip);
    ip_family(dst) = ip_family(ip);
    SET_INET_VARSIZE(dst);

    return dst;
}

static int ip_addrsize ( inet inetptr  )  [static]

Definition at line 66 of file network.c.

References ip_family, PGSQL_AF_INET, and PGSQL_AF_INET6.

Referenced by cidr_set_masklen(), hashinet(), inet_to_cidr(), inetand(), inetmi(), inetnot(), inetor(), internal_inetpl(), network_in(), network_recv(), and network_send().

{
    switch (ip_family(inetptr))
    {
        case PGSQL_AF_INET:
            return 4;
        case PGSQL_AF_INET6:
            return 16;
        default:
            return 0;
    }
}

Datum network_broadcast ( PG_FUNCTION_ARGS   ) 

Definition at line 715 of file network.c.

References ip_addr, ip_bits, ip_family, palloc0(), PG_GETARG_INET_PP, PG_RETURN_INET_P, and SET_INET_VARSIZE.

Referenced by network_scan_last().

{
    inet       *ip = PG_GETARG_INET_PP(0);
    inet       *dst;
    int         byte;
    int         bits;
    int         maxbytes;
    unsigned char mask;
    unsigned char *a,
               *b;

    /* make sure any unused bits are zeroed */
    dst = (inet *) palloc0(sizeof(inet));

    if (ip_family(ip) == PGSQL_AF_INET)
        maxbytes = 4;
    else
        maxbytes = 16;

    bits = ip_bits(ip);
    a = ip_addr(ip);
    b = ip_addr(dst);

    for (byte = 0; byte < maxbytes; byte++)
    {
        if (bits >= 8)
        {
            mask = 0x00;
            bits -= 8;
        }
        else if (bits == 0)
            mask = 0xff;
        else
        {
            mask = 0xff >> bits;
            bits = 0;
        }

        b[byte] = a[byte] | mask;
    }

    ip_family(dst) = ip_family(ip);
    ip_bits(dst) = ip_bits(ip);
    SET_INET_VARSIZE(dst);

    PG_RETURN_INET_P(dst);
}

Datum network_cmp ( PG_FUNCTION_ARGS   ) 
static int32 network_cmp_internal ( inet a1,
inet a2 
) [static]

Definition at line 438 of file network.c.

References bitncmp(), ip_addr, ip_bits, ip_family, ip_maxbits, and Min.

Referenced by network_cmp(), network_eq(), network_ge(), network_gt(), network_le(), network_lt(), and network_ne().

{
    if (ip_family(a1) == ip_family(a2))
    {
        int         order;

        order = bitncmp(ip_addr(a1), ip_addr(a2),
                        Min(ip_bits(a1), ip_bits(a2)));
        if (order != 0)
            return order;
        order = ((int) ip_bits(a1)) - ((int) ip_bits(a2));
        if (order != 0)
            return order;
        return bitncmp(ip_addr(a1), ip_addr(a2), ip_maxbits(a1));
    }

    return ip_family(a1) - ip_family(a2);
}

Datum network_eq ( PG_FUNCTION_ARGS   ) 
Datum network_family ( PG_FUNCTION_ARGS   ) 

Definition at line 696 of file network.c.

References ip_family, PG_GETARG_INET_PP, PG_RETURN_INT32, PGSQL_AF_INET, and PGSQL_AF_INET6.

{
    inet       *ip = PG_GETARG_INET_PP(0);

    switch (ip_family(ip))
    {
        case PGSQL_AF_INET:
            PG_RETURN_INT32(4);
            break;
        case PGSQL_AF_INET6:
            PG_RETURN_INT32(6);
            break;
        default:
            PG_RETURN_INT32(0);
            break;
    }
}

Datum network_ge ( PG_FUNCTION_ARGS   ) 
Datum network_gt ( PG_FUNCTION_ARGS   ) 
Datum network_host ( PG_FUNCTION_ARGS   ) 

Definition at line 603 of file network.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, inet_net_ntop(), ip_addr, ip_family, ip_maxbits, PG_GETARG_INET_PP, and PG_RETURN_TEXT_P.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    char       *ptr;
    char        tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];

    /* force display of max bits, regardless of masklen... */
    if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
                      tmp, sizeof(tmp)) == NULL)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("could not format inet value: %m")));

    /* Suppress /n if present (shouldn't happen now) */
    if ((ptr = strchr(tmp, '/')) != NULL)
        *ptr = '\0';

    PG_RETURN_TEXT_P(cstring_to_text(tmp));
}

Datum network_hostmask ( PG_FUNCTION_ARGS   ) 

Definition at line 850 of file network.c.

References ip_addr, ip_bits, ip_family, ip_maxbits, palloc0(), PG_GETARG_INET_PP, PG_RETURN_INET_P, and SET_INET_VARSIZE.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    inet       *dst;
    int         byte;
    int         bits;
    int         maxbytes;
    unsigned char mask;
    unsigned char *b;

    /* make sure any unused bits are zeroed */
    dst = (inet *) palloc0(sizeof(inet));

    if (ip_family(ip) == PGSQL_AF_INET)
        maxbytes = 4;
    else
        maxbytes = 16;

    bits = ip_maxbits(ip) - ip_bits(ip);
    b = ip_addr(dst);

    byte = maxbytes - 1;

    while (bits)
    {
        if (bits >= 8)
        {
            mask = 0xff;
            bits -= 8;
        }
        else
        {
            mask = 0xff >> (8 - bits);
            bits = 0;
        }

        b[byte] = mask;
        byte--;
    }

    ip_family(dst) = ip_family(ip);
    ip_bits(dst) = ip_maxbits(ip);
    SET_INET_VARSIZE(dst);

    PG_RETURN_INET_P(dst);
}

static inet* network_in ( char *  src,
bool  is_cidr 
) [static]

Definition at line 83 of file network.c.

References addressOK(), ereport, errcode(), errdetail(), errmsg(), ERROR, inet_net_pton(), ip_addr, ip_addrsize(), ip_bits, ip_family, ip_maxbits, palloc0(), and SET_INET_VARSIZE.

Referenced by cidr_in(), inet_client_addr(), inet_in(), and inet_server_addr().

{
    int         bits;
    inet       *dst;

    dst = (inet *) palloc0(sizeof(inet));

    /*
     * First, check to see if this is an IPv6 or IPv4 address.  IPv6 addresses
     * will have a : somewhere in them (several, in fact) so if there is one
     * present, assume it's V6, otherwise assume it's V4.
     */

    if (strchr(src, ':') != NULL)
        ip_family(dst) = PGSQL_AF_INET6;
    else
        ip_family(dst) = PGSQL_AF_INET;

    bits = inet_net_pton(ip_family(dst), src, ip_addr(dst),
                         is_cidr ? ip_addrsize(dst) : -1);
    if ((bits < 0) || (bits > ip_maxbits(dst)))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
        /* translator: first %s is inet or cidr */
                 errmsg("invalid input syntax for type %s: \"%s\"",
                        is_cidr ? "cidr" : "inet", src)));

    /*
     * Error check: CIDR values must not have any bits set beyond the masklen.
     */
    if (is_cidr)
    {
        if (!addressOK(ip_addr(dst), bits, ip_family(dst)))
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                     errmsg("invalid cidr value: \"%s\"", src),
                     errdetail("Value has bits set to right of mask.")));
    }

    ip_bits(dst) = bits;
    SET_INET_VARSIZE(dst);

    return dst;
}

Datum network_le ( PG_FUNCTION_ARGS   ) 
Datum network_lt ( PG_FUNCTION_ARGS   ) 
Datum network_masklen ( PG_FUNCTION_ARGS   ) 

Definition at line 688 of file network.c.

References ip_bits, PG_GETARG_INET_PP, and PG_RETURN_INT32.

Datum network_ne ( PG_FUNCTION_ARGS   ) 
Datum network_netmask ( PG_FUNCTION_ARGS   ) 

Definition at line 808 of file network.c.

References ip_addr, ip_bits, ip_family, ip_maxbits, palloc0(), PG_GETARG_INET_PP, PG_RETURN_INET_P, and SET_INET_VARSIZE.

{
    inet       *ip = PG_GETARG_INET_PP(0);
    inet       *dst;
    int         byte;
    int         bits;
    unsigned char mask;
    unsigned char *b;

    /* make sure any unused bits are zeroed */
    dst = (inet *) palloc0(sizeof(inet));

    bits = ip_bits(ip);
    b = ip_addr(dst);

    byte = 0;

    while (bits)
    {
        if (bits >= 8)
        {
            mask = 0xff;
            bits -= 8;
        }
        else
        {
            mask = 0xff << (8 - bits);
            bits = 0;
        }

        b[byte] = mask;
        byte++;
    }

    ip_family(dst) = ip_family(ip);
    ip_bits(dst) = ip_maxbits(ip);
    SET_INET_VARSIZE(dst);

    PG_RETURN_INET_P(dst);
}

Datum network_network ( PG_FUNCTION_ARGS   ) 

Definition at line 764 of file network.c.

References ip_addr, ip_bits, ip_family, palloc0(), PG_GETARG_INET_PP, PG_RETURN_INET_P, and SET_INET_VARSIZE.

Referenced by network_scan_first().

{
    inet       *ip = PG_GETARG_INET_PP(0);
    inet       *dst;
    int         byte;
    int         bits;
    unsigned char mask;
    unsigned char *a,
               *b;

    /* make sure any unused bits are zeroed */
    dst = (inet *) palloc0(sizeof(inet));

    bits = ip_bits(ip);
    a = ip_addr(ip);
    b = ip_addr(dst);

    byte = 0;

    while (bits)
    {
        if (bits >= 8)
        {
            mask = 0xff;
            bits -= 8;
        }
        else
        {
            mask = 0xff << (8 - bits);
            bits = 0;
        }

        b[byte] = a[byte] & mask;
        byte++;
    }

    ip_family(dst) = ip_family(ip);
    ip_bits(dst) = ip_bits(ip);
    SET_INET_VARSIZE(dst);

    PG_RETURN_INET_P(dst);
}

static char* network_out ( inet src,
bool  is_cidr 
) [static]

Definition at line 149 of file network.c.

References ereport, errcode(), errmsg(), ERROR, inet_net_ntop(), ip_addr, ip_bits, ip_family, NULL, pstrdup(), and snprintf().

Referenced by cidr_out(), and inet_out().

{
    char        tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
    char       *dst;
    int         len;

    dst = inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src),
                        tmp, sizeof(tmp));
    if (dst == NULL)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("could not format inet value: %m")));

    /* For CIDR, add /n if not present */
    if (is_cidr && strchr(tmp, '/') == NULL)
    {
        len = strlen(tmp);
        snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src));
    }

    return pstrdup(tmp);
}

static inet* network_recv ( StringInfo  buf,
bool  is_cidr 
) [static]

Definition at line 200 of file network.c.

References addressOK(), ereport, errcode(), errdetail(), errmsg(), ERROR, i, ip_addr, ip_addrsize(), ip_bits, ip_family, ip_maxbits, palloc0(), PGSQL_AF_INET, PGSQL_AF_INET6, pq_getmsgbyte(), and SET_INET_VARSIZE.

Referenced by cidr_recv(), and inet_recv().

{
    inet       *addr;
    char       *addrptr;
    int         bits;
    int         nb,
                i;

    /* make sure any unused bits in a CIDR value are zeroed */
    addr = (inet *) palloc0(sizeof(inet));

    ip_family(addr) = pq_getmsgbyte(buf);
    if (ip_family(addr) != PGSQL_AF_INET &&
        ip_family(addr) != PGSQL_AF_INET6)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
        /* translator: %s is inet or cidr */
                 errmsg("invalid address family in external \"%s\" value",
                        is_cidr ? "cidr" : "inet")));
    bits = pq_getmsgbyte(buf);
    if (bits < 0 || bits > ip_maxbits(addr))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
        /* translator: %s is inet or cidr */
                 errmsg("invalid bits in external \"%s\" value",
                        is_cidr ? "cidr" : "inet")));
    ip_bits(addr) = bits;
    i = pq_getmsgbyte(buf);     /* ignore is_cidr */
    nb = pq_getmsgbyte(buf);
    if (nb != ip_addrsize(addr))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
        /* translator: %s is inet or cidr */
                 errmsg("invalid length in external \"%s\" value",
                        is_cidr ? "cidr" : "inet")));

    addrptr = (char *) ip_addr(addr);
    for (i = 0; i < nb; i++)
        addrptr[i] = pq_getmsgbyte(buf);

    /*
     * Error check: CIDR values must not have any bits set beyond the masklen.
     */
    if (is_cidr)
    {
        if (!addressOK(ip_addr(addr), bits, ip_family(addr)))
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                     errmsg("invalid external \"cidr\" value"),
                     errdetail("Value has bits set to right of mask.")));
    }

    SET_INET_VARSIZE(addr);

    return addr;
}

Datum network_scan_first ( Datum  in  ) 

Definition at line 1044 of file network.c.

References DirectFunctionCall1, and network_network().

Referenced by network_prefix_quals().

Datum network_scan_last ( Datum  in  ) 
static bytea* network_send ( inet addr,
bool  is_cidr 
) [static]

Definition at line 278 of file network.c.

References buf, i, ip_addr, ip_addrsize(), ip_bits, ip_family, pq_begintypsend(), pq_endtypsend(), and pq_sendbyte().

Referenced by cidr_send(), and inet_send().

{
    StringInfoData buf;
    char       *addrptr;
    int         nb,
                i;

    pq_begintypsend(&buf);
    pq_sendbyte(&buf, ip_family(addr));
    pq_sendbyte(&buf, ip_bits(addr));
    pq_sendbyte(&buf, is_cidr);
    nb = ip_addrsize(addr);
    if (nb < 0)
        nb = 0;
    pq_sendbyte(&buf, nb);
    addrptr = (char *) ip_addr(addr);
    for (i = 0; i < nb; i++)
        pq_sendbyte(&buf, addrptr[i]);
    return pq_endtypsend(&buf);
}

Datum network_show ( PG_FUNCTION_ARGS   ) 

Definition at line 629 of file network.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, inet_net_ntop(), ip_addr, ip_bits, ip_family, ip_maxbits, PG_GETARG_INET_PP, PG_RETURN_TEXT_P, and snprintf().

{
    inet       *ip = PG_GETARG_INET_PP(0);
    int         len;
    char        tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];

    if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
                      tmp, sizeof(tmp)) == NULL)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("could not format inet value: %m")));

    /* 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));
    }

    PG_RETURN_TEXT_P(cstring_to_text(tmp));
}

Datum network_sub ( PG_FUNCTION_ARGS   ) 

Definition at line 540 of file network.c.

References a1, a2, bitncmp(), ip_addr, ip_bits, ip_family, PG_GETARG_INET_PP, and PG_RETURN_BOOL.

{
    inet       *a1 = PG_GETARG_INET_PP(0);
    inet       *a2 = PG_GETARG_INET_PP(1);

    if (ip_family(a1) == ip_family(a2))
    {
        PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2)
                     && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
    }

    PG_RETURN_BOOL(false);
}

Datum network_subeq ( PG_FUNCTION_ARGS   ) 

Definition at line 555 of file network.c.

References a1, a2, bitncmp(), ip_addr, ip_bits, ip_family, PG_GETARG_INET_PP, and PG_RETURN_BOOL.

{
    inet       *a1 = PG_GETARG_INET_PP(0);
    inet       *a2 = PG_GETARG_INET_PP(1);

    if (ip_family(a1) == ip_family(a2))
    {
        PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2)
                     && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
    }

    PG_RETURN_BOOL(false);
}

Datum network_sup ( PG_FUNCTION_ARGS   ) 

Definition at line 570 of file network.c.

References a1, a2, bitncmp(), ip_addr, ip_bits, ip_family, PG_GETARG_INET_PP, and PG_RETURN_BOOL.

{
    inet       *a1 = PG_GETARG_INET_PP(0);
    inet       *a2 = PG_GETARG_INET_PP(1);

    if (ip_family(a1) == ip_family(a2))
    {
        PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2)
                     && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
    }

    PG_RETURN_BOOL(false);
}

Datum network_supeq ( PG_FUNCTION_ARGS   ) 

Definition at line 585 of file network.c.

References a1, a2, bitncmp(), ip_addr, ip_bits, ip_family, PG_GETARG_INET_PP, and PG_RETURN_BOOL.

{
    inet       *a1 = PG_GETARG_INET_PP(0);
    inet       *a2 = PG_GETARG_INET_PP(1);

    if (ip_family(a1) == ip_family(a2))
    {
        PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2)
                     && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
    }

    PG_RETURN_BOOL(false);
}