Пример #1
0
static inline
IP_P
ipaddr_transform_2(Datum d1, Datum d2, PGFunction ip4func, PGFunction ip6func)
{
    IP_P ipp1 = DatumGetIP_P(d1);
    IP_P ipp2 = DatumGetIP_P(d2);
	IP ip1;
	IP ip2;
	IP out;
	int af1 = ip_unpack(ipp1, &ip1);
	int af2 = ip_unpack(ipp2, &ip2);

	if (af1 != af2)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid mixing of IP address families")));
				
	switch (af1)
	{
		case PGSQL_AF_INET:
			out.ip4 = DatumGetIP4(DirectFunctionCall2(ip4func, IP4GetDatum(ip1.ip4), IP4GetDatum(ip2.ip4)));
			break;

		case PGSQL_AF_INET6:
			out.ip6 = *(DatumGetIP6P(DirectFunctionCall2(ip6func, IP6PGetDatum(&ip1.ip6), IP6PGetDatum(&ip2.ip6))));
			break;

		default:
			ipaddr_internal_error();
	}

    return ip_pack(af1, &out);
}
Пример #2
0
Datum
ipaddr_send(PG_FUNCTION_ARGS)
{
    IP_P arg1 = PG_GETARG_IP_P(0);
    StringInfoData buf;
	IP ip;
	int af = ip_unpack(arg1, &ip);

    pq_begintypsend(&buf);
	pq_sendbyte(&buf, af);
	pq_sendbyte(&buf, ip_maxbits(af));
	pq_sendbyte(&buf, 1);
	pq_sendbyte(&buf, ip_sizeof(af));

	switch (af)
	{
		case PGSQL_AF_INET:
			pq_sendint(&buf, ip.ip4, sizeof(IP4));
			break;

		case PGSQL_AF_INET6:
			pq_sendint64(&buf, ip.ip6.bits[0]);
			pq_sendint64(&buf, ip.ip6.bits[1]);
			break;
	}

    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
Пример #3
0
static inline
bool
ipaddr_comparison_bool(Datum d1, Datum d2,
					   bool mismatch_af1, bool mismatch_af2,
					   PGFunction ip4func, PGFunction ip6func)
{
    IP_P ipp1 = DatumGetIP_P(d1);
    IP_P ipp2 = DatumGetIP_P(d2);
	IP ip1;
	IP ip2;
	int af1 = ip_unpack(ipp1, &ip1);
	int af2 = ip_unpack(ipp2, &ip2);
	bool retval;

	if (af1 != af2)
	{
		retval = (af1 > af2) ? mismatch_af1 : mismatch_af2;
	}
	else
	{
		switch (af1)
		{
			case PGSQL_AF_INET:
				retval = DatumGetBool(DirectFunctionCall2(ip4func, IP4GetDatum(ip1.ip4), IP4GetDatum(ip2.ip4)));
				break;

			case PGSQL_AF_INET6:
				retval = DatumGetBool(DirectFunctionCall2(ip6func, IP6PGetDatum(&ip1.ip6), IP6PGetDatum(&ip2.ip6)));
				break;

			default:
				ipaddr_internal_error();
		}
	}

	if ((Pointer)ipp1 != DatumGetPointer(d1))
		pfree(ipp1);
	if ((Pointer)ipp2 != DatumGetPointer(d2))
		pfree(ipp2);

    return retval;
}
Пример #4
0
/* return 0 on success, -1 on failure. */
static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data_size, _Bool disable_family_check)
{
    if (data_size < (SIZE_IP + SIZE_PORT))
        return -1;

    if (ip_unpack(&target->ip, data, data_size, disable_family_check) == -1)
        return -1;

    memcpy(&target->port, data + SIZE_IP, SIZE_PORT);
    return 0;
}
Пример #5
0
Datum
ipaddr_family(PG_FUNCTION_ARGS)
{
	IP_P ipp = PG_GETARG_IP_P(0);
	IP ip;

	if (ip_unpack(ipp, &ip) == PGSQL_AF_INET6)
		PG_RETURN_INT32(6);
	else
		PG_RETURN_INT32(4);
}
Пример #6
0
Datum
ipaddr_cmp(PG_FUNCTION_ARGS)
{
    IP_P ipp1 = PG_GETARG_IP_P(0);
	IP_P ipp2 = PG_GETARG_IP_P(1);
	IP ip1;
	IP ip2;
	int af1 = ip_unpack(ipp1, &ip1);
	int af2 = ip_unpack(ipp2, &ip2);
	int32 retval;

	if (af1 != af2)
	{
		retval = (af1 > af2) ? 1 : -1;
	}
	else
	{
		switch (af1)
		{
			case PGSQL_AF_INET:
				retval = DatumGetInt32(DirectFunctionCall2(ip4_cmp, IP4GetDatum(ip1.ip4), IP4GetDatum(ip2.ip4)));
				break;

			case PGSQL_AF_INET6:
				retval = DatumGetInt32(DirectFunctionCall2(ip6_cmp, IP6PGetDatum(&ip1.ip6), IP6PGetDatum(&ip2.ip6)));
				break;

			default:
				ipaddr_internal_error();
		}
	}

	PG_FREE_IF_COPY(ipp1,0);
	PG_FREE_IF_COPY(ipp2,1);

    PG_RETURN_INT32(retval);
}
Пример #7
0
Datum
ipaddr_minus_ipaddr(PG_FUNCTION_ARGS)
{
    Datum minuend = PG_GETARG_DATUM(0);
    Datum subtrahend = PG_GETARG_DATUM(1);
    Datum res;
	IP ip1;
	IP ip2;
	int af1 = ip_unpack(DatumGetIP_P(minuend), &ip1);
	int af2 = ip_unpack(DatumGetIP_P(subtrahend), &ip2);

	if (af1 != af2)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid mixing of IP address families")));
				
	switch (af1)
	{
		case PGSQL_AF_INET:
			res = DirectFunctionCall2(numeric_sub,
									  DirectFunctionCall1(ip4_cast_to_numeric,IP4GetDatum(ip1.ip4)),
									  DirectFunctionCall1(ip4_cast_to_numeric,IP4GetDatum(ip2.ip4)));
			break;

		case PGSQL_AF_INET6:
			res = DirectFunctionCall2(numeric_sub,
									  DirectFunctionCall1(ip6_cast_to_numeric,IP6PGetDatum(&ip1.ip6)),
									  DirectFunctionCall1(ip6_cast_to_numeric,IP6PGetDatum(&ip2.ip6)));
			break;

		default:
			ipaddr_internal_error();
	}

    PG_RETURN_DATUM(res);
}
Пример #8
0
Datum
ipaddr_cast_to_ip4(PG_FUNCTION_ARGS)
{
	IP_P ipp = PG_GETARG_IP_P(0);
	IP ip;

	if (ip_unpack(ipp, &ip) == PGSQL_AF_INET)
	{
		PG_RETURN_IP4(ip.ip4);
	}

    ereport(ERROR,
            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
             errmsg("invalid IP value in cast to IP4")));
    PG_RETURN_NULL();
}
Пример #9
0
Datum
ipaddr_cast_to_ip6(PG_FUNCTION_ARGS)
{
	IP_P ipp = PG_GETARG_IP_P(0);
	IP ip;

	if (ip_unpack(ipp, &ip) == PGSQL_AF_INET6)
	{
		IP6 *out = palloc(sizeof(IP6));
		*out = ip.ip6;
		PG_RETURN_IP6_P(out);
	}

    ereport(ERROR,
            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
             errmsg("invalid IP value in cast to IP4")));
    PG_RETURN_NULL();
}
Пример #10
0
static inline
Datum
ipaddr_transform_1d(Datum d, PGFunction ip4func, PGFunction ip6func)
{
    IP_P ipp = DatumGetIP_P(d);
	IP ip;
	int af = ip_unpack(ipp, &ip);

	switch (af)
	{
		case PGSQL_AF_INET:
			return DirectFunctionCall1(ip4func, IP4GetDatum(ip.ip4));

		case PGSQL_AF_INET6:
			return DirectFunctionCall1(ip6func, IP6PGetDatum(&ip.ip6));
	}
	
	ipaddr_internal_error();
}
Пример #11
0
Datum
ipaddr_out(PG_FUNCTION_ARGS)
{
    IP_P ipp = PG_GETARG_IP_P(0);
    char *out = palloc(IP6_STRING_MAX);
	IP ip;

	switch (ip_unpack(ipp, &ip))
	{
		case PGSQL_AF_INET:
			ip4_raw_output(ip.ip4, out, IP6_STRING_MAX);
			break;
		case PGSQL_AF_INET6:
			ip6_raw_output(ip.ip6.bits, out, IP6_STRING_MAX);
			break;
	}

    PG_RETURN_CSTRING(out);
}
Пример #12
0
Datum
ipaddr_cast_to_text(PG_FUNCTION_ARGS)
{
    IP_P ipp = PG_GETARG_IP_P(0);
	IP ip;
	int af = ip_unpack(ipp, &ip);
    text *out = NULL;

	switch (af)
	{
		case PGSQL_AF_INET:
			out = make_text(NULL, IP4_STRING_MAX);
			set_text_len(out, ip4_raw_output(ip.ip4, VARDATA(out), IP4_STRING_MAX));
			break;
		case PGSQL_AF_INET6:
			out = make_text(NULL, IP6_STRING_MAX);
			set_text_len(out, ip6_raw_output(ip.ip6.bits, VARDATA(out), IP6_STRING_MAX));
			break;
	}

    PG_RETURN_TEXT_P(out);
}
Пример #13
0
static inline
IP_P
ipaddr_transform_2d(Datum d1, Datum d2, PGFunction ip4func, PGFunction ip6func)
{
    IP_P ipp = DatumGetIP_P(d1);
	IP ip;
	int af = ip_unpack(ipp, &ip);

	switch (af)
	{
		case PGSQL_AF_INET:
			ip.ip4 = DatumGetIP4(DirectFunctionCall2(ip4func, IP4GetDatum(ip.ip4), d2));
			break;

		case PGSQL_AF_INET6:
			ip.ip6 = *(DatumGetIP6P(DirectFunctionCall2(ip6func, IP6PGetDatum(&ip.ip6), d2)));
			break;

		default:
			ipaddr_internal_error();
	}

    return ip_pack(af, &ip);
}