mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-13 03:42:35 -06:00
wasm: net.cidr_contains, net.cidr_intersects, and net.cidr_overlap builtins.
Signed-off-by: Teemu Koponen <koponen@styra.com>
This commit is contained in:
committed by
Torin Sandall
parent
52ddaca92b
commit
78d9bf1aed
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -58,71 +58,74 @@ const (
|
||||
)
|
||||
|
||||
var builtinsFunctions = map[string]string{
|
||||
ast.Plus.Name: "opa_arith_plus",
|
||||
ast.Minus.Name: "opa_arith_minus",
|
||||
ast.Multiply.Name: "opa_arith_multiply",
|
||||
ast.Divide.Name: "opa_arith_divide",
|
||||
ast.Abs.Name: "opa_arith_abs",
|
||||
ast.Round.Name: "opa_arith_round",
|
||||
ast.Rem.Name: "opa_arith_rem",
|
||||
ast.ArrayConcat.Name: "opa_array_concat",
|
||||
ast.ArraySlice.Name: "opa_array_slice",
|
||||
ast.SetDiff.Name: "opa_set_diff",
|
||||
ast.And.Name: "opa_set_intersection",
|
||||
ast.Or.Name: "opa_set_union",
|
||||
ast.Intersection.Name: "opa_sets_intersection",
|
||||
ast.Union.Name: "opa_sets_union",
|
||||
ast.IsNumber.Name: "opa_types_is_number",
|
||||
ast.IsString.Name: "opa_types_is_string",
|
||||
ast.IsBoolean.Name: "opa_types_is_boolean",
|
||||
ast.IsArray.Name: "opa_types_is_array",
|
||||
ast.IsSet.Name: "opa_types_is_set",
|
||||
ast.IsObject.Name: "opa_types_is_object",
|
||||
ast.IsNull.Name: "opa_types_is_null",
|
||||
ast.TypeNameBuiltin.Name: "opa_types_name",
|
||||
ast.BitsOr.Name: "opa_bits_or",
|
||||
ast.BitsAnd.Name: "opa_bits_and",
|
||||
ast.BitsNegate.Name: "opa_bits_negate",
|
||||
ast.BitsXOr.Name: "opa_bits_xor",
|
||||
ast.BitsShiftLeft.Name: "opa_bits_shiftleft",
|
||||
ast.BitsShiftRight.Name: "opa_bits_shiftright",
|
||||
ast.Count.Name: "opa_agg_count",
|
||||
ast.Sum.Name: "opa_agg_sum",
|
||||
ast.Product.Name: "opa_agg_product",
|
||||
ast.Max.Name: "opa_agg_max",
|
||||
ast.Min.Name: "opa_agg_min",
|
||||
ast.Sort.Name: "opa_agg_sort",
|
||||
ast.All.Name: "opa_agg_all",
|
||||
ast.Any.Name: "opa_agg_any",
|
||||
ast.Base64IsValid.Name: "opa_base64_is_valid",
|
||||
ast.Base64Decode.Name: "opa_base64_decode",
|
||||
ast.Base64Encode.Name: "opa_base64_encode",
|
||||
ast.Base64UrlEncode.Name: "opa_base64_url_encode",
|
||||
ast.Base64UrlDecode.Name: "opa_base64_url_decode",
|
||||
ast.JSONMarshal.Name: "opa_json_marshal",
|
||||
ast.JSONUnmarshal.Name: "opa_json_unmarshal",
|
||||
ast.ObjectFilter.Name: "opa_object_filter",
|
||||
ast.Concat.Name: "opa_strings_concat",
|
||||
ast.FormatInt.Name: "opa_strings_format_int",
|
||||
ast.IndexOf.Name: "opa_strings_indexof",
|
||||
ast.Substring.Name: "opa_strings_substring",
|
||||
ast.Lower.Name: "opa_strings_lower",
|
||||
ast.Upper.Name: "opa_strings_upper",
|
||||
ast.Contains.Name: "opa_strings_contains",
|
||||
ast.StartsWith.Name: "opa_strings_startswith",
|
||||
ast.EndsWith.Name: "opa_strings_endswith",
|
||||
ast.Split.Name: "opa_strings_split",
|
||||
ast.Replace.Name: "opa_strings_replace",
|
||||
ast.ReplaceN.Name: "opa_strings_replace_n",
|
||||
ast.Trim.Name: "opa_strings_trim",
|
||||
ast.TrimLeft.Name: "opa_strings_trim_left",
|
||||
ast.TrimPrefix.Name: "opa_strings_trim_prefix",
|
||||
ast.TrimRight.Name: "opa_strings_trim_right",
|
||||
ast.TrimSuffix.Name: "opa_strings_trim_suffix",
|
||||
ast.TrimSpace.Name: "opa_strings_trim_space",
|
||||
ast.NumbersRange.Name: "opa_numbers_range",
|
||||
ast.ToNumber.Name: "opa_to_number",
|
||||
ast.WalkBuiltin.Name: "opa_value_transitive_closure",
|
||||
ast.Plus.Name: "opa_arith_plus",
|
||||
ast.Minus.Name: "opa_arith_minus",
|
||||
ast.Multiply.Name: "opa_arith_multiply",
|
||||
ast.Divide.Name: "opa_arith_divide",
|
||||
ast.Abs.Name: "opa_arith_abs",
|
||||
ast.Round.Name: "opa_arith_round",
|
||||
ast.Rem.Name: "opa_arith_rem",
|
||||
ast.ArrayConcat.Name: "opa_array_concat",
|
||||
ast.ArraySlice.Name: "opa_array_slice",
|
||||
ast.SetDiff.Name: "opa_set_diff",
|
||||
ast.And.Name: "opa_set_intersection",
|
||||
ast.Or.Name: "opa_set_union",
|
||||
ast.Intersection.Name: "opa_sets_intersection",
|
||||
ast.Union.Name: "opa_sets_union",
|
||||
ast.IsNumber.Name: "opa_types_is_number",
|
||||
ast.IsString.Name: "opa_types_is_string",
|
||||
ast.IsBoolean.Name: "opa_types_is_boolean",
|
||||
ast.IsArray.Name: "opa_types_is_array",
|
||||
ast.IsSet.Name: "opa_types_is_set",
|
||||
ast.IsObject.Name: "opa_types_is_object",
|
||||
ast.IsNull.Name: "opa_types_is_null",
|
||||
ast.TypeNameBuiltin.Name: "opa_types_name",
|
||||
ast.BitsOr.Name: "opa_bits_or",
|
||||
ast.BitsAnd.Name: "opa_bits_and",
|
||||
ast.BitsNegate.Name: "opa_bits_negate",
|
||||
ast.BitsXOr.Name: "opa_bits_xor",
|
||||
ast.BitsShiftLeft.Name: "opa_bits_shiftleft",
|
||||
ast.BitsShiftRight.Name: "opa_bits_shiftright",
|
||||
ast.Count.Name: "opa_agg_count",
|
||||
ast.Sum.Name: "opa_agg_sum",
|
||||
ast.Product.Name: "opa_agg_product",
|
||||
ast.Max.Name: "opa_agg_max",
|
||||
ast.Min.Name: "opa_agg_min",
|
||||
ast.Sort.Name: "opa_agg_sort",
|
||||
ast.All.Name: "opa_agg_all",
|
||||
ast.Any.Name: "opa_agg_any",
|
||||
ast.Base64IsValid.Name: "opa_base64_is_valid",
|
||||
ast.Base64Decode.Name: "opa_base64_decode",
|
||||
ast.Base64Encode.Name: "opa_base64_encode",
|
||||
ast.Base64UrlEncode.Name: "opa_base64_url_encode",
|
||||
ast.Base64UrlDecode.Name: "opa_base64_url_decode",
|
||||
ast.NetCIDRContains.Name: "opa_cidr_contains",
|
||||
ast.NetCIDROverlap.Name: "opa_cidr_contains",
|
||||
ast.NetCIDRIntersects.Name: "opa_cidr_intersects",
|
||||
ast.JSONMarshal.Name: "opa_json_marshal",
|
||||
ast.JSONUnmarshal.Name: "opa_json_unmarshal",
|
||||
ast.ObjectFilter.Name: "opa_object_filter",
|
||||
ast.Concat.Name: "opa_strings_concat",
|
||||
ast.FormatInt.Name: "opa_strings_format_int",
|
||||
ast.IndexOf.Name: "opa_strings_indexof",
|
||||
ast.Substring.Name: "opa_strings_substring",
|
||||
ast.Lower.Name: "opa_strings_lower",
|
||||
ast.Upper.Name: "opa_strings_upper",
|
||||
ast.Contains.Name: "opa_strings_contains",
|
||||
ast.StartsWith.Name: "opa_strings_startswith",
|
||||
ast.EndsWith.Name: "opa_strings_endswith",
|
||||
ast.Split.Name: "opa_strings_split",
|
||||
ast.Replace.Name: "opa_strings_replace",
|
||||
ast.ReplaceN.Name: "opa_strings_replace_n",
|
||||
ast.Trim.Name: "opa_strings_trim",
|
||||
ast.TrimLeft.Name: "opa_strings_trim_left",
|
||||
ast.TrimPrefix.Name: "opa_strings_trim_prefix",
|
||||
ast.TrimRight.Name: "opa_strings_trim_right",
|
||||
ast.TrimSuffix.Name: "opa_strings_trim_suffix",
|
||||
ast.TrimSpace.Name: "opa_strings_trim_space",
|
||||
ast.NumbersRange.Name: "opa_numbers_range",
|
||||
ast.ToNumber.Name: "opa_to_number",
|
||||
ast.WalkBuiltin.Name: "opa_value_transitive_closure",
|
||||
}
|
||||
|
||||
var builtinDispatchers = [...]string{
|
||||
|
||||
@@ -128,6 +128,15 @@ cases:
|
||||
- note: base64url.encode built-in
|
||||
query: base64url.encode("Hello",x)
|
||||
want_result: [{'x': "SGVsbG8="}]
|
||||
- note: net.cidr_contains
|
||||
query: net.cidr_contains("172.17.0.0/24", "172.17.0.0/16", x)
|
||||
want_result: [{'x': false}]
|
||||
- note: net.cidr_contains
|
||||
query: net.cidr_overlap("172.17.0.0/16", "172.17.0.1", x)
|
||||
want_result: [{'x': true}]
|
||||
- note: net.cidr_intersects
|
||||
query: net.cidr_intersects("192.168.1.0/25", "192.168.1.64/25", x)
|
||||
want_result: [{'x': true}]
|
||||
- note: json.marshal built-in
|
||||
query: json.marshal("string",x)
|
||||
want_result: [{'x': '"string"'}]
|
||||
|
||||
+337
@@ -0,0 +1,337 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "str.h"
|
||||
#include "value.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t len;
|
||||
unsigned char ip[16];
|
||||
unsigned char mask[16];
|
||||
} ip_net;
|
||||
|
||||
typedef unsigned char u_char;
|
||||
typedef unsigned int u_int;
|
||||
|
||||
static int inet_pton4(const char *src, const char *end, u_char *dst);
|
||||
static int inet_pton6(const char *src, const char *end, u_char *dst);
|
||||
|
||||
static bool parse_ip(const char *src, int n, ip_net *dst)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (src[i] == '.')
|
||||
{
|
||||
dst->len = 4;
|
||||
memset(dst->mask, 0xff, 4);
|
||||
return inet_pton4(src, src + n, dst->ip);
|
||||
}
|
||||
else if (src[i] == ':')
|
||||
{
|
||||
dst->len = 16;
|
||||
memset(dst->mask, 0xff, 16);
|
||||
return inet_pton6(src, src + n, dst->ip);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool parse_cidr(const char *src, size_t n, ip_net *dst)
|
||||
{
|
||||
const char *slash = NULL;
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
if (src[i] == '/')
|
||||
{
|
||||
slash = &src[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (slash == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const char *addr = src;
|
||||
const size_t len = slash - src;
|
||||
if (!parse_ip(addr, len, dst))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const char *mask = slash + 1;
|
||||
long long bits;
|
||||
if (opa_atoi64(mask, n - len - 1, &bits) == -1 || bits < 0 || bits > dst->len*8)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dst->len; i++)
|
||||
{
|
||||
if (bits >= 8) {
|
||||
dst->mask[i] = 0xff;
|
||||
bits -= 8;
|
||||
continue;
|
||||
}
|
||||
|
||||
dst->mask[i] = ~((unsigned char)(0xff >> bits));
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dst->len; i++)
|
||||
{
|
||||
dst->ip[i] &= dst->mask[i];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// returns true if a contains b.
|
||||
static bool contains(ip_net *a, ip_net *b)
|
||||
{
|
||||
if (a->len != b->len)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < a->len; i++)
|
||||
{
|
||||
if (a->mask[i] & ~b->mask[i])
|
||||
{
|
||||
// If b mask is shorter, a can never contain b. For
|
||||
// example, 192.168/16 (a) doesn't contain 192.168/15 (b).
|
||||
// The above logical operation checks if the b mask is
|
||||
// shorter. For example, consider the masks a and b:
|
||||
//
|
||||
// | mask
|
||||
// -------+----------
|
||||
// a | 11111000
|
||||
// b | 11110000
|
||||
// ~b | 00001111
|
||||
// a & ~b | 00001000
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Since b mask may be longer than a, use the a mask to ignore
|
||||
// the b bits not relevant for comparison. Note, ips are
|
||||
// already masked at the construction time with their own
|
||||
// masks (see L84 above) so they don't have bits beyond their
|
||||
// mask length.
|
||||
if (a->ip[i] != (b->ip[i] & a->mask[i]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
opa_value *opa_cidr_contains(opa_value *a, opa_value *b)
|
||||
{
|
||||
if (opa_value_type(a) != OPA_STRING || opa_value_type(b) != OPA_STRING)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ip_net ip_a, ip_b;
|
||||
|
||||
opa_string_t *s = opa_cast_string(a);
|
||||
if (!parse_cidr(s->v, s->len, &ip_a)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = opa_cast_string(b);
|
||||
if (!parse_ip(s->v, s->len, &ip_b) && !parse_cidr(s->v, s->len, &ip_b)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return opa_boolean(contains(&ip_a, &ip_b) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
opa_value *opa_cidr_intersects(opa_value *a, opa_value *b)
|
||||
{
|
||||
if (opa_value_type(a) != OPA_STRING || opa_value_type(b) != OPA_STRING)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
opa_string_t *as = opa_cast_string(a);
|
||||
opa_string_t *bs = opa_cast_string(b);
|
||||
ip_net ip_a, ip_b;
|
||||
if (!parse_cidr(as->v, as->len, &ip_a) || !parse_cidr(bs->v, bs->len, &ip_b)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return opa_boolean(contains(&ip_a, &ip_b) || contains(&ip_b, &ip_a) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(const char *src, const char *stop, u_char *dst)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
#define NS_INADDRSZ 4
|
||||
u_char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while (src != stop && (ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
u_int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (saw_digit && *tp == 0)
|
||||
return (0);
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (!saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(const char *src, const char *stop, u_char *dst)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
#define NS_IN6ADDRSZ 16
|
||||
#define NS_INT16SZ 2
|
||||
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok, *end;
|
||||
int ch, seen_xdigits;
|
||||
u_int val;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
seen_xdigits = 0;
|
||||
val = 0;
|
||||
while (src != stop && (ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (++seen_xdigits > 4)
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!seen_xdigits) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
} else if (*src == '\0') {
|
||||
return (0);
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
seen_xdigits = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, stop, tp) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
seen_xdigits = 0;
|
||||
break; /*%< '\\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (seen_xdigits) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
return (0);
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef OPA_CIDR_H
|
||||
#define OPA_CIDR_H
|
||||
|
||||
#include "value.h"
|
||||
|
||||
opa_value *opa_cidr_contains(opa_value *net, opa_value *ip_or_net);
|
||||
opa_value *opa_cidr_intersects(opa_value *a, opa_value *b);
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,23 @@
|
||||
|
||||
#include "../malloc.h"
|
||||
|
||||
void *memchr(const void *src, int c, size_t n)
|
||||
{
|
||||
const unsigned char *s = src;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if (*s == (unsigned char)c)
|
||||
{
|
||||
return (void *)s;
|
||||
}
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
unsigned char *d = dest;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "arithmetic.h"
|
||||
#include "array.h"
|
||||
#include "bits-builtins.h"
|
||||
#include "cidr.h"
|
||||
#include "conversions.h"
|
||||
#include "encoding.h"
|
||||
#include "json.h"
|
||||
@@ -1936,6 +1937,29 @@ void test_to_number(void)
|
||||
test("to_number/bad value", opa_to_number(opa_array()) == NULL);
|
||||
}
|
||||
|
||||
void test_cidr_contains(void)
|
||||
{
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("10.0.0.0/8"), opa_string_terminated("10.1.0.0/24")), opa_boolean(TRUE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("172.17.0.0/24"), opa_string_terminated("172.17.0.0/16")), opa_boolean(FALSE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("10.0.0.0/8"), opa_string_terminated("192.168.1.0/24")), opa_boolean(FALSE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("10.0.0.0/8"), opa_string_terminated("10.1.1.1/32")), opa_boolean(TRUE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("2001:4860:4860::8888/32"), opa_string_terminated("2001:4860:4860:1234::8888/40")), opa_boolean(TRUE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("2001:4860:4860::8888/32"), opa_string_terminated("2001:4860:4860:1234:5678:1234:5678:8888/128")), opa_boolean(TRUE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("2001:4860::/96"), opa_string_terminated("2001:4860::/32")), opa_boolean(FALSE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("2001:4860::/32"), opa_string_terminated("fd1e:5bfe:8af3:9ddc::/64")), opa_boolean(FALSE)) == 0);
|
||||
test("cidr/contains", opa_cidr_contains(opa_string_terminated("not-a-cidr"), opa_string_terminated("192.168.1.67")) == NULL);
|
||||
test("cidr/contains", opa_cidr_contains(opa_string_terminated("192.168.1.0/28"), opa_string_terminated("not-a-cidr")) == NULL);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("10.0.0.0/8"), opa_string_terminated("10.1.2.3")), opa_boolean(TRUE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_contains(opa_string_terminated("10.0.0.0/8"), opa_string_terminated("192.168.1.1")), opa_boolean(FALSE)) == 0);
|
||||
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_intersects(opa_string_terminated("192.168.1.0/25"), opa_string_terminated("192.168.1.64/25")), opa_boolean(TRUE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_intersects(opa_string_terminated("192.168.1.0/24"), opa_string_terminated("192.168.2.0/24")), opa_boolean(FALSE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_intersects(opa_string_terminated("fd1e:5bfe:8af3:9ddc::/64"), opa_string_terminated("fd1e:5bfe:8af3:9ddc:1111::/72")), opa_boolean(TRUE)) == 0);
|
||||
test("cidr/contains", opa_value_compare(opa_cidr_intersects(opa_string_terminated("fd1e:5bfe:8af3:9ddc::/64"), opa_string_terminated("2001:4860:4860::8888/32")), opa_boolean(FALSE)) == 0);
|
||||
test("cidr/contains", opa_cidr_intersects(opa_string_terminated("not-a-cidr"), opa_string_terminated("192.168.1.0/24")) == NULL);
|
||||
test("cidr/contains", opa_cidr_intersects(opa_string_terminated("192.168.1.0/28"), opa_string_terminated("not-a-cidr")) == NULL);
|
||||
}
|
||||
|
||||
opa_value *__new_value_path(int sz, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
Reference in New Issue
Block a user