45RCSID(
"$Id: 59aaf0595cae0a1d224215f43dfaf9dc49b20c32 $")
48#include <freeradius-devel/util/value.h>
51#include <freeradius-devel/util/base16.h>
52#include <freeradius-devel/util/size.h>
62 "in_addr.s_addr has unexpected length");
64 "in6_addr.s6_addr has unexpected length");
66 "vb_ifid has unexpected length");
68 "vb_ether has unexpected length");
71 "datum.boolean has unexpected length");
73 "vb_uint8 has unexpected length");
75 "vb_uint16 has unexpected length");
77 "vb_uint32 has unexpected length");
79 "vb_uint64 has unexpected length");
82 "vb_int8 has unexpected length");
84 "vb_int16 has unexpected length");
86 "vb_int32 has unexpected length");
88 "vb_int64 has unexpected length");
91 "vb_float32 has unexpected length");
93 "vb_float64 has unexpected length");
96#if defined(WITH_VERIFY_PTR) || !defined(NDEBUG)
97#define VERIFY_IS_SET(_vb) UNCONST(fr_value_box_t *, _vb)->verified
98#define VERIFY_SET(_vb) UNCONST(fr_value_box_t *, _vb)->verified = true
99#define VERIFY_CLEAR(_vb) UNCONST(fr_value_box_t *, _vb)->verified = false
101#define VERIFY_IS_SET(_vb) (0)
102#define VERIFY_SET(_vb) do { } while (0)
103#define VERIFY_CLEAR(_vb) do { } while (0)
116#define network_min_size(_x) (fr_value_box_network_sizes[_x][0])
117#define network_max_size(_x) (fr_value_box_network_sizes[_x][1])
470 .name =
"unprintables",
564 L(
""),
L(
"\n"),
L(
"\r"),
L(
"\""))
570 L(
""),
L(
"\n"),
L(
"\r"),
L(
"'"))
576 L(
""),
L(
"\n"),
L(
"\r"),
L(
"/"))
582 L(
""),
L(
"\n"),
L(
"\r"),
L(
"`"))
591 L(
""),
L(
"\n"),
L(
"\r"),
L(
"\"\"\""))
597 L(
""),
L(
"\n"),
L(
"\r"),
L(
"'''"))
603 L(
""),
L(
"\n"),
L(
"\r"),
L(
"///"))
609 L(
""),
L(
"\n"),
L(
"\r"),
L(
"```"))
656 dst->vb_length = src->vb_length;
665 fr_value_box_list_init(&dst->vb_group);
693#if defined(WITH_VERIFY_PTR) || !defined(NDEBUG)
694 dst->file = src->file;
695 dst->line = src->line;
698 dst->enumv = src->enumv;
699 dst->type = src->type;
700 dst->tainted = src->tainted;
701 dst->vb_safefor = src->vb_safefor;
702 dst->vb_secret = src->vb_secret;
703 fr_value_box_list_entry_init(dst);
708 dst->talloced =
false;
724 if (a == b)
return CMP_EQ;
735 if ((fpclassify(a) == FP_ZERO) || (fpclassify(b) == FP_ZERO)) {
737 if (diff < DBL_EPSILON)
return CMP_EQ;
745 sum = fabs(a) + fabs(b);
750 if (sum < DBL_MIN)
goto check;
755 if ((diff / fmin(sum, DBL_MAX)) < DBL_EPSILON)
return CMP_EQ;
772 if (a->type != b->type) {
793#define RETURN(_type) return CMP(a->datum._type, b->datum._type)
794#define COMPARE(_type) return CMP(memcmp(&a->datum._type, &b->datum._type, sizeof(a->datum._type)), 0)
833 return float_cmp((
double) a->vb_float32, (
double) b->vb_float32);
836 return float_cmp(a->vb_float64, b->vb_float64);
868 return CMP(a->vb_void, b->vb_void);
904 if (a_net == b_net) {
907 compare = memcmp(a, b, bytes);
913 if ((compare == 0) &&
975 if (common == 0)
return true;
980 if (common < 8)
break;
982 if (a[i] != b[i])
return false;
990 mask <<= (8 - common);
994 if ((a[i] &
mask) == ((b[i] &
mask))) {
1030 if (b->vb_ip.af != AF_INET)
goto fail_cmp_v4;
1037 if (b->vb_ip.af != AF_INET)
goto fail_cmp_v4;
1042 b->vb_ip.prefix, (
uint8_t const *) &b->vb_ipv4addr);
1054 if (b->vb_ip.af != AF_INET)
goto fail_cmp_v4;
1059 (
uint8_t const *) &a->vb_ipv4addr,
1060 32, (
uint8_t const *) &b->vb_ip.addr.v4);
1063 if (b->vb_ip.af != AF_INET)
goto fail_cmp_v4;
1068 (
uint8_t const *) &a->vb_ipv4addr,
1069 b->vb_ip.prefix, (
uint8_t const *) &b->vb_ipv4addr);
1079 if (b->vb_ip.af != AF_INET6)
goto fail_cmp_v6;
1086 if (b->vb_ip.af != AF_INET6)
goto fail_cmp_v6;
1091 b->vb_ip.prefix, (
uint8_t const *) &b->vb_ip.addr.v6);
1103 if (b->vb_ip.af != AF_INET6)
goto fail_cmp_v6;
1108 (
uint8_t const *) &a->vb_ip.addr.v6,
1109 128, (
uint8_t const *) &b->vb_ip.addr.v6);
1112 if (b->vb_ip.af != AF_INET6)
goto fail_cmp_v6;
1117 (
uint8_t const *) &a->vb_ip.addr.v6,
1118 b->vb_ip.prefix, (
uint8_t const *) &b->vb_ip.addr.v6);
1126 if (a->vb_ip.af != b->vb_ip.af)
goto fail_cmp_v4;
1131 if (a->vb_ip.af != b->vb_ip.af)
goto fail_cmp_v4;
1133 if (a->vb_ip.af == AF_INET)
goto cmp_prefix_v4;
1164 return (compare == 0);
1167 return (compare != 0);
1170 return (compare < 0);
1173 return (compare > 0);
1176 return (compare <= 0);
1179 return (compare >= 0);
1332 switch (src->type) {
1384 switch (src->type) {
1386 dst->vb_uint16 = htons(src->vb_uint16);
1391 dst->vb_uint32 = htonl(src->vb_uint32);
1396 dst->vb_uint64 = htonll(src->vb_uint64);
1400 dst->vb_int16 = htons(src->vb_int16);
1404 dst->vb_int32 = htonl(src->vb_int32);
1408 dst->vb_int64 = htonll(src->vb_int64);
1433 switch (
value->type) {
1439 if (
value->enumv->flags.length) {
1440 return value->enumv->flags.length;
1450 if (
value->vb_length > UINT16_MAX)
return UINT16_MAX;
1453 return value->vb_length;
1460 if (
value->enumv)
return value->enumv->flags.length;
1553 switch (
value->type) {
1563 if (
value->enumv->flags.length) {
1567 if (max < value->enumv->flags.length) {
1572 }
else if (
max >
value->enumv->flags.length) {
1588 if (
max > UINT16_MAX)
max = UINT16_MAX;
1627 switch (
value->type) {
1632 sizeof(
value->vb_ipv4addr));
1642 sizeof(
value->vb_ipv4addr));
1647 if (
value->vb_ip.scope_id > 0) {
1655 if (
value->vb_ip.scope_id > 0) {
1667 switch (
value->vb_ip.af) {
1682 switch (
value->vb_ip.af) {
1734 if (
value->vb_attr->depth != 1) {
1736 value->vb_attr->depth,
value->vb_attr->name);
1740 switch (
value->vb_attr->flags.length) {
1745 value->vb_attr->name,
value->vb_attr->attr,
value->vb_attr->flags.length);
1749 base.vb_uint8 =
value->vb_attr->attr;
1753 if (
value->vb_attr->attr > UINT16_MAX)
goto too_large;
1755 base.vb_uint16 =
value->vb_attr->attr;
1760 base.vb_uint32 =
value->vb_attr->attr;
1765 value->vb_attr->flags.length,
value->vb_attr->name);
1786 if (!
value->enumv) {
1793 if (!
value->enumv) {
1796 }
else switch (
value->enumv->flags.length) {
1798 if (date > UINT16_MAX) date = UINT16_MAX;
1804 if (date > UINT32_MAX) date = UINT32_MAX;
1827 if (!
value->enumv) {
1830 }
else if (!
value->enumv->flags.is_unsigned) {
1831 switch (
value->enumv->flags.length) {
1833 if (date < INT16_MIN) {
1835 }
else if (date > INT16_MAX) {
1843 if (date < INT32_MIN) {
1845 }
else if (date > INT32_MAX) {
1859 switch (
value->enumv->flags.length) {
1863 }
else if (date > UINT16_MAX) {
1872 }
else if (date > UINT32_MAX) {
1957 "Expected length >= %zu bytes, got %zu bytes",
1967 if (enumv && !enumv->flags.array) {
1969 "Expected length <= %zu bytes, got %zu bytes",
1982 size_t newlen =
len;
1989 if (enumv->flags.length) {
1990 newlen = enumv->flags.length;
2013 if (newlen >
len)
return -(newlen + offset);
2071 dst->vb_ip.scope_id = scope_id;
2087 dst->vb_ip.scope_id = scope_id;
2117 dst->datum.boolean = (val != 0);
2168 fr_strerror_const(
"No enumv (i.e. root) passed to fr_value_box_from_network for type 'attribute'");
2182 switch (enumv->flags.length) {
2204 if (!dst->vb_attr) {
2206 if (!dst->vb_attr)
return -1;
2226 length = enumv->flags.length;
2234 if (
len > length)
return -(length);
2256 length = enumv->flags.length;
2264 if (
len > length)
return -(length);
2268 if (!enumv || !enumv->flags.is_unsigned) {
2280 if (tmp > INT64_MAX) tmp = INT64_MAX;
2313 AF_INET, 32, 32, 0, 4,
2317 AF_INET, 0, 32, 0, 4,
2321 AF_INET6, 128, 128, 16, 16,
2325 AF_INET6, 0, 128, 0, 16,
2347 int prefix_len,
uint8_t const *
data,
size_t data_len,
2348 bool fixed,
bool tainted)
2386 fr_strerror_printf(
"Invalid prefix length '%d' - it requires %u bytes of data, and there are only %zu bytes of data",
2404 if (enumv && enumv->flags.array) {
2434 .prefix = prefix_len,
2438 if (!data_len)
return 0;
2440 fr_assert(data_len <=
sizeof(dst->vb_ip.addr));
2442 memcpy((
uint8_t *) &dst->vb_ip.addr,
data, data_len);
2469 void const *src,
size_t len)
2482 memcpy(&dst->datum, src,
len);
2486 if (
len !=
sizeof(
struct in_addr)) {
2493 memcpy(&dst->vb_ipv4addr, src,
len);
2497 if (
len !=
sizeof(
struct in6_addr)) {
2504 memcpy(&dst->vb_ipv6addr, src,
len);
2539 switch (
value->type) {
2541 if (*outlen < 8)
return -1;
2556 if (slen < 0)
return -1;
2565 *outlen =
value->vb_ip.prefix;
2571 *outlen =
value->vb_length * 8;
2576 *outlen =
sizeof(
value->vb_ether) * 8;
2607 "destination type size %zu",
2620 if (!src->vb_length)
return 0;
2622 ptr = (
uint8_t *) &dst->datum;
2635 switch (dst->type) {
2637 memcpy(ptr, src->vb_octets, src->vb_length);
2642 dst->vb_bool = (src->vb_octets[0] != 0);
2654 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
2675 switch (src->type) {
2690 (
char const *)src->vb_octets, src->vb_length, src->tainted) < 0)
return -1;
2696 dst,
UNCONST(fr_value_box_list_t *, &src->vb_group),
2736 switch (src->type) {
2750 (
uint8_t const *)src->vb_strvalue, src->vb_length, src->tainted) < 0)
return -1;
2756 dst,
UNCONST(fr_value_box_list_t *, &src->vb_group),
2765 (
uint8_t const *)&src->vb_ipv4addr,
2766 sizeof(src->vb_ipv4addr), src->tainted);
2776 sizeof(src->vb_ipv4addr) + 1, src->tainted) < 0)
return -1;
2778 bin[0] = src->vb_ip.prefix;
2779 memcpy(&bin[1], (
uint8_t const *)&src->vb_ipv4addr,
sizeof(src->vb_ipv4addr));
2788 (
uint8_t const *)src->vb_ipv6addr,
2789 sizeof(src->vb_ipv6addr), src->tainted);
2799 fr_strerror_printf(
"IPv6 scope_id %u is too large to encode in one byte", src->vb_ip.scope_id);
2804 sizeof(src->vb_ipv6addr) + 2, src->tainted) < 0)
return -1;
2805 bin[0] = (
uint8_t) src->vb_ip.scope_id;
2806 bin[1] = src->vb_ip.prefix;
2807 memcpy(&bin[2], src->vb_ipv6addr,
sizeof(src->vb_ipv6addr));
2849#define CAST_IP_FIX_COMBO \
2850 case FR_TYPE_COMBO_IP_ADDR: \
2851 if (src->vb_ip.af == AF_INET) { \
2852 src_type = FR_TYPE_IPV4_ADDR; \
2853 } else if (src->vb_ip.af == AF_INET6) { \
2854 src_type = FR_TYPE_IPV6_ADDR; \
2857 case FR_TYPE_COMBO_IP_PREFIX: \
2858 if (src->vb_ip.af == AF_INET) { \
2859 src_type = FR_TYPE_IPV4_PREFIX; \
2860 } else if (src->vb_ip.af == AF_INET6) { \
2861 src_type = FR_TYPE_IPV6_PREFIX; \
2902 src->vb_strvalue, src->vb_length,
2915 dst->vb_ip.af = AF_INET;
2916 dst->vb_ip.prefix = 32;
2917 dst->vb_ip.scope_id = 0;
2929 memcpy(&dst->vb_ip.addr.v4, &src->vb_ipv6addr[
sizeof(
v4_v6_map)],
2930 sizeof(dst->vb_ip.addr.v4));
2935 if (src->vb_ip.prefix != 32) {
2937 "cast to IP address types",
2946 memcpy(&dst->vb_ip.addr.v4, &src->vb_ip.addr.v4,
sizeof(dst->vb_ip.addr.v4));
2950 if (src->vb_ip.prefix != 128) {
2951 fr_strerror_printf(
"Invalid cast from %s to %s. Only /128 (not /%i) prefixes may be "
2952 "cast to IP address types",
2958 if (memcmp(&src->vb_ipv6addr,
v4_v6_map,
sizeof(
v4_v6_map)) != 0)
goto bad_v6_prefix_map;
2959 memcpy(&dst->vb_ip.addr.v4, &src->vb_ipv6addr[
sizeof(
v4_v6_map)],
2960 sizeof(dst->vb_ip.addr.v4));
2964 if (src->vb_length !=
sizeof(dst->vb_ipv4addr)) {
2965 fr_strerror_printf(
"Invalid cast from %s to %s. Needed octet string of length %zu, got %zu",
2968 sizeof(dst->vb_ipv4addr), src->vb_length);
2971 memcpy(&dst->vb_ip.addr.v4, src->vb_octets,
sizeof(dst->vb_ipv4addr));
2978 net = ntohl(src->vb_uint32);
2979 memcpy(&dst->vb_ip.addr.v4, (
uint8_t *)&net,
sizeof(dst->vb_ipv4addr));
3016 src->vb_strvalue, src->vb_length,
3029 dst->vb_ip.af = AF_INET;
3030 dst->vb_ip.scope_id = 0;
3034 dst->vb_ip.prefix = src->vb_ip.prefix;
3038 memcpy(&dst->vb_ip, &src->vb_ip,
sizeof(dst->vb_ip));
3052 memcpy(&dst->vb_ipv4addr, &src->vb_ipv6addr[
sizeof(
v4_v6_map)],
3053 sizeof(dst->vb_ipv4addr));
3054 dst->vb_ip.prefix = 32;
3058 if (memcmp(src->vb_ipv6addr,
v4_v6_map,
sizeof(
v4_v6_map)) != 0)
goto bad_v6_prefix_map;
3060 if (src->vb_ip.prefix < (
sizeof(
v4_v6_map) << 3)) {
3061 fr_strerror_printf(
"Invalid cast from %s to %s. Expected prefix >= %u bits got %u bits",
3064 (
unsigned int)(
sizeof(
v4_v6_map) << 3), src->vb_ip.prefix);
3067 memcpy(&dst->vb_ipv4addr, &src->vb_ipv6addr[
sizeof(
v4_v6_map)],
3068 sizeof(dst->vb_ipv4addr));
3073 dst->vb_ip.prefix = src->vb_ip.prefix - (
sizeof(
v4_v6_map) << 3);
3077 if (src->vb_length !=
sizeof(dst->vb_ipv4addr) + 1) {
3078 fr_strerror_printf(
"Invalid cast from %s to %s. Needed octet string of length %zu, got %zu",
3081 sizeof(dst->vb_ipv4addr) + 1, src->vb_length);
3084 dst->vb_ip.prefix = src->vb_octets[0];
3085 memcpy(&dst->vb_ip.addr.v4, &src->vb_octets[1],
sizeof(dst->vb_ipv4addr));
3092 net = ntohl(src->vb_uint32);
3093 memcpy(&dst->vb_ip.addr.v4, (
uint8_t *)&net,
sizeof(dst->vb_ipv4addr));
3094 dst->vb_ip.prefix = 32;
3125 static_assert((
sizeof(
v4_v6_map) +
sizeof(src->vb_ip.addr.v4)) <=
3126 sizeof(src->vb_ip.addr.v6),
"IPv6 storage too small");
3134 src->vb_strvalue, src->vb_length,
3147 dst->vb_ip.af = AF_INET6;
3148 dst->vb_ip.prefix = 128;
3153 uint8_t *p = dst->vb_ipv6addr;
3158 memcpy(p, (
uint8_t const *)&src->vb_ipv4addr,
sizeof(src->vb_ipv4addr));
3159 dst->vb_ip.scope_id = 0;
3165 uint8_t *p = dst->vb_ipv6addr;
3167 if (src->vb_ip.prefix != 32) {
3169 "cast to IP address types",
3179 memcpy(p, (
uint8_t const *)&src->vb_ipv4addr,
sizeof(src->vb_ipv4addr));
3180 dst->vb_ip.scope_id = 0;
3185 if (src->vb_ip.prefix != 128) {
3186 fr_strerror_printf(
"Invalid cast from %s to %s. Only /128 (not /%i) prefixes may be "
3187 "cast to IP address types",
3196 memcpy(dst->vb_ipv6addr, src->vb_ipv6addr,
3197 sizeof(dst->vb_ipv6addr));
3198 dst->vb_ip.scope_id = src->vb_ip.scope_id;
3202 if (src->vb_length !=
sizeof(dst->vb_ipv6addr)) {
3203 fr_strerror_printf(
"Invalid cast from %s to %s. Needed octet string of length %zu, got %zu",
3206 sizeof(dst->vb_ipv6addr), src->vb_length);
3209 memcpy(&dst->vb_ipv6addr, src->vb_octets,
sizeof(dst->vb_ipv6addr));
3245 src->vb_strvalue, src->vb_length,
3258 dst->vb_ip.af = AF_INET6;
3263 uint8_t *p = dst->vb_ipv6addr;
3268 memcpy(p, (
uint8_t const *)&src->vb_ipv4addr,
sizeof(src->vb_ipv4addr));
3269 dst->vb_ip.prefix = 128;
3270 dst->vb_ip.scope_id = 0;
3276 uint8_t *p = dst->vb_ipv6addr;
3281 memcpy(p, (
uint8_t const *)&src->vb_ipv4addr,
sizeof(src->vb_ipv4addr));
3282 dst->vb_ip.prefix = (
sizeof(
v4_v6_map) << 3) + src->vb_ip.prefix;
3283 dst->vb_ip.scope_id = 0;
3288 dst->vb_ip.prefix = src->vb_ip.prefix;
3292 dst->vb_ip.prefix = 128;
3294 memcpy(dst->vb_ipv6addr, src->vb_ipv6addr,
3295 sizeof(dst->vb_ipv6addr));
3296 dst->vb_ip.scope_id = src->vb_ip.scope_id;
3300 if (src->vb_length != (
sizeof(dst->vb_ipv6addr) + 2)) {
3301 fr_strerror_printf(
"Invalid cast from %s to %s. Needed octet string of length %zu, got %zu",
3304 sizeof(dst->vb_ipv6addr) + 2, src->vb_length);
3307 dst->vb_ip.scope_id = src->vb_octets[0];
3308 dst->vb_ip.prefix = src->vb_octets[1];
3309 memcpy(&dst->vb_ipv6addr, src->vb_octets + 2,
sizeof(dst->vb_ipv6addr));
3338 switch (src->type) {
3341 src->vb_strvalue, src->vb_length,
3356 switch (src->type) {
3365 if ((array[0] != 0) || (array[1] != 0))
return -1;
3367 memcpy(dst->vb_ether, &array[2], 6);
3396 switch (src->type) {
3399 src->vb_strvalue, src->vb_length,
3417 switch (src->type) {
3419 dst->vb_bool = (src->vb_int8 != 0);
3423 dst->vb_bool = (src->vb_uint8 != 0);
3427 dst->vb_bool = (src->vb_int16 != 0);
3431 dst->vb_bool = (src->vb_uint16 != 0);
3435 dst->vb_bool = (src->vb_int32 != 0);
3439 dst->vb_bool = (src->vb_uint32 != 0);
3443 dst->vb_bool = (src->vb_int64 != 0);
3447 dst->vb_bool = (src->vb_uint64 != 0);
3451 dst->vb_bool = (src->vb_size != 0);
3459 dst->vb_bool = (fpclassify(src->vb_float32) != FP_ZERO);
3463 dst->vb_bool = (fpclassify(src->vb_float64) != FP_ZERO);
3486#define SIGN_BIT_HIGH(_int, _len) ((((uint64_t)1) << (((_len) << 3) - 1)) & (_int))
3487#define SIGN_PROMOTE(_int, _len) ((_len) < sizeof(_int) ? \
3488 (_int) | (~((__typeof__(_int))0)) << ((_len) << 3) : (_int))
3490#if !defined(NDEBUG) || defined(STATIC_ANALYZER)
3496 "invalid source type len, expected > 0, got %zu",
3502 "Invalid cast from %s to %s. "
3503 "invalid source type len, expected <= %zu, got %zu",
3506 sizeof(uint64_t),
len))
return -1;
3509 switch (src->type) {
3522 if (src->enumv) res = (
fr_time_res_t)src->enumv->flags.flag_time_res;
3538 if (src->enumv) res = (
fr_time_res_t)src->enumv->flags.flag_time_res;
3545#ifdef WORDS_BIGENDIAN
3546 memcpy(((
uint8_t *)&tmp) + (
sizeof(tmp) -
len),
3563 if ((int64_t)tmp <
min) {
3565 "outside value range %"PRId64
"-%"PRIu64,
3574 "outside value range 0-%"PRIu64,
3587 if (dst->enumv) res = (
fr_time_res_t)dst->enumv->flags.flag_time_res;
3601 if (dst->enumv) res = (
fr_time_res_t)dst->enumv->flags.flag_time_res;
3612#ifdef WORDS_BIGENDIAN
3637 switch (src->type) {
3640 src->vb_strvalue, src->vb_length,
3668 memcpy(&tmp.vb_uint32, &src->vb_ip.addr.v4,
sizeof(tmp.vb_uint32));
3689 memcpy(((
uint8_t *)&tmp.vb_uint64) + (
sizeof(tmp.vb_uint64) -
sizeof(src->vb_ether)),
3690 &src->vb_ether,
sizeof(src->vb_ether));
3691#ifndef WORDS_BIGENDIAN
3731 dst->vb_uint8 = src->vb_float32;
3735 dst->vb_uint16 = src->vb_float32;
3739 dst->vb_uint32 = src->vb_float32;
3743 dst->vb_uint64 = src->vb_float32;
3747 dst->vb_int8 = src->vb_float32;
3751 dst->vb_int16 = src->vb_float32;
3755 dst->vb_int32 = src->vb_float32;
3759 dst->vb_int64 = src->vb_float32;
3763 dst->vb_size = src->vb_float32;
3769 sec = src->vb_float32;
3771 nsec = ((src->vb_float32 *
NSEC) - ((
float) sec));
3784 sec = src->vb_float32;
3786 nsec = (((double) src->vb_float32 * res) - ((double) sec));
3806 dst->vb_uint8 = src->vb_float64;
3810 dst->vb_uint16 = src->vb_float64;
3814 dst->vb_uint32 = src->vb_float64;
3818 dst->vb_uint64 = src->vb_float64;
3822 dst->vb_int8 = src->vb_float64;
3826 dst->vb_int16 = src->vb_float64;
3830 dst->vb_int32 = src->vb_float64;
3834 dst->vb_int64 = src->vb_float64;
3838 dst->vb_size = src->vb_float64;
3844 sec = src->vb_float64;
3848 nsec = ((src->vb_float64 *
NSEC) - ((
double) sec));
3861 sec = src->vb_float64;
3863 if (
unlikely((sec > INT64_MAX / res) || (sec < INT64_MIN / res)))
goto overflow;
3865 nsec = ((src->vb_float64 * res) - ((
double) sec));
3900 switch (src->type) {
3903 num = (double) src->vb_float32;
3911 num = src->vb_float64;
3926 num = src->vb_int16;
3930 num = src->vb_int32;
3934 num = src->vb_int64;
3938 num = src->vb_uint8;
3942 num = src->vb_uint16;
3946 num = src->vb_uint32;
3950 num = src->vb_uint64;
3981 dst->vb_float32 = num;
3983 dst->vb_float64 = num;
4043 if (dst_type == src->type) {
4047 if (ret < 0)
return ret;
4049 if (dst_enumv) dst->enumv = dst_enumv;
4105 dst->enumv = dst_enumv;
4121 if (when > INT64_MAX) {
4127 dst->enumv = dst_enumv;
4156 switch (src->vb_attr->flags.length) {
4159 dst->vb_uint8 = src->vb_attr->attr;
4164 dst->vb_uint16 = src->vb_attr->attr;
4169 dst->vb_uint32 = src->vb_attr->attr;
4174 src->vb_attr->flags.length, src->vb_attr->name);
4200 src->vb_strvalue, src->vb_length,
4207 fr_strerror_printf(
"Invalid cast from %s to %s. Source is length %zu is smaller than "
4208 "destination type size %zu",
4218 "destination type size %zu",
4233 tmp.type = dst_type;
4234 dst->enumv = dst_enumv;
4244 dst->enumv = dst_enumv;
4272 fr_value_box_entry_t entry = vb->entry;
4278 if (vb->type == dst_type) {
4279 vb->enumv = dst_enumv;
4318#define O(_x, _y) case FR_TYPE_##_x: return vb->vb_##_y
4353 switch (ipaddr->
af) {
4368 memcpy(&dst->vb_ip, ipaddr,
sizeof(dst->vb_ip));
4389 memcpy(dst, &src->vb_ip,
sizeof(*dst));
4404 switch (
data->type) {
4421 while ((vb = fr_value_box_list_pop_head(&
data->vb_group)) != NULL) {
4439 memset(&
data->datum, 0,
sizeof(
data->datum));
4467 switch (src->type) {
4492 dst->vb_strvalue = str;
4501 if (src->vb_length) {
4502 bin = talloc_memdup(ctx, src->vb_octets, src->vb_length);
4507 talloc_set_type(bin,
uint8_t);
4509 bin = talloc_array(ctx,
uint8_t, 0);
4511 dst->vb_octets = bin;
4522 while ((child = fr_value_box_list_next(&src->vb_group, child))) {
4532 fr_value_box_list_talloc_free(&dst->vb_group);
4543 fr_value_box_list_insert_tail(&dst->vb_group,
new);
4552 if (src->vb_attr->flags.is_unknown) {
4554 if (!dst->vb_attr)
return -1;
4557 dst->vb_attr = src->vb_attr;
4593 switch (src->type) {
4600 dst->datum.ptr = ctx ? talloc_reference(ctx, src->datum.ptr) : src->datum.ptr;
4605 dst->vb_attr = src->vb_attr;
4610 dst->vb_void = src->vb_void;
4631 switch (src->type) {
4639 str = talloc_steal(ctx, src->vb_strvalue);
4644 talloc_set_type(str,
char);
4645 dst->vb_strvalue = str;
4647 memset(&src->datum, 0,
sizeof(src->datum));
4655 bin = talloc_steal(ctx, src->vb_octets);
4660 talloc_set_type(bin,
uint8_t);
4662 dst->vb_octets = bin;
4664 memset(&src->datum, 0,
sizeof(src->datum));
4672 while ((child = fr_value_box_list_pop_head(&src->vb_group))) {
4673 child = talloc_steal(ctx, child);
4678 fr_value_box_list_insert_tail(&dst->vb_group, child);
4703 char const *src,
bool tainted)
4714 dst->vb_strvalue = str;
4735 len = strlen(vb->vb_strvalue);
4736 str = talloc_realloc(ctx,
UNCONST(
char *, vb->vb_strvalue),
char,
len + 1);
4741 vb->vb_strvalue = str;
4742 vb->vb_length =
len;
4760 char const *
fmt, va_list ap)
4769 if (!str)
return -1;
4772 dst->vb_strvalue = str;
4791 char const *
fmt, ...)
4813 char const *src,
bool tainted)
4816 dst->vb_strvalue = src;
4817 dst->vb_length = strlen(src);
4831 vb->vb_strvalue = src;
4852 if (
len < 0)
len = strlen(src);
4861 vb->vb_strvalue = str;
4880 size_t len,
bool tainted)
4884 str = talloc_zero_array(ctx,
char,
len + 1);
4892 dst->vb_strvalue = str;
4893 dst->vb_length =
len;
4920 if (dstlen ==
len)
return 0;
4922 str = talloc_realloc(ctx,
UNCONST(
char *, dst->vb_strvalue),
char,
len + 1);
4932 memset(str + dstlen,
'\0', (
len - dstlen) + 1);
4936 dst->vb_strvalue = str;
4937 dst->vb_length =
len;
4954 char const *src,
size_t len,
bool tainted)
4971 dst->vb_strvalue = str;
4972 dst->vb_length =
len;
4982 str = talloc_array(ctx,
char,
len + 1);
4995 dst->vb_strvalue = str;
4996 dst->vb_length =
len;
5017 char const *src,
bool tainted)
5023 len = talloc_array_length(src);
5024 if ((
len == 0) || (src[
len - 1] !=
'\0')) {
5041 char const *src,
size_t len,
bool tainted)
5044 dst->vb_strvalue = src;
5045 dst->vb_length =
len;
5062 char const *src,
bool tainted)
5068 len = talloc_array_length(src);
5069 if ((
len == 0) || (src[
len - 1] !=
'\0')) {
5075 dst->vb_strvalue = ctx ? talloc_reference(ctx, src) : src;
5076 dst->vb_length =
len - 1;
5101 size_t len,
bool tainted)
5110 talloc_set_type(bin,
uint8_t);
5113 dst->vb_octets = bin;
5114 dst->vb_length =
len;
5140 dstlen = talloc_array_length(dst->vb_octets);
5141 if (dstlen ==
len)
return 0;
5151 bin = talloc_array(ctx,
uint8_t, 0);
5167 if (dstlen <
len) memset(bin + dstlen, 0x00,
len - dstlen);
5168 dst->vb_octets = bin;
5169 dst->vb_length =
len;
5195 uint8_t const *src,
size_t len,
bool tainted)
5205 bin = talloc_memdup(ctx, src,
len);
5210 talloc_set_type(bin,
uint8_t);
5213 dst->vb_octets = bin;
5214 dst->vb_length =
len;
5224 bin = talloc_size(ctx,
len);
5234 talloc_set_type(bin,
uint8_t);
5237 dst->vb_octets = bin;
5238 dst->vb_length =
len;
5257 uint8_t const *src,
bool tainted)
5279 uint8_t const *src,
size_t len,
bool tainted)
5282 dst->vb_octets = src;
5283 dst->vb_length =
len;
5297 uint8_t const *src,
bool tainted)
5302 dst->vb_octets = ctx ? talloc_reference(ctx, src) : src;
5303 dst->vb_length = talloc_array_length(src);
5314 dst->vb_cursor = cursor;
5315 dst->vb_cursor_name =
name;
5327 dst->vb_void =
UNCONST(
void *, ptr);
5349 if (!da->flags.has_value) {
5374 vb->vb_uint8 = vb->vb_uint8 ==
UINT8_MAX ? 0 : vb->vb_uint8 + 1;
5378 vb->vb_uint16 = vb->vb_uint16 == UINT16_MAX ? 0 : vb->vb_uint16 + 1;
5382 vb->vb_uint32 = vb->vb_uint32 == UINT32_MAX ? 0 : vb->vb_uint32 + 1;
5386 vb->vb_uint64 = vb->vb_uint64 == UINT64_MAX ? 0 : vb->vb_uint64 + 1;
5390 vb->vb_int8 = vb->vb_int8 == INT8_MAX ? INT8_MIN : vb->vb_int8 + 1;
5394 vb->vb_int16 = vb->vb_int16 == INT16_MAX ? INT16_MIN : vb->vb_int16 + 1;
5398 vb->vb_int32 = vb->vb_int32 == INT32_MAX ? INT32_MIN : vb->vb_int32 + 1;
5402 vb->vb_int64 = vb->vb_int64 == INT64_MAX ? INT64_MIN : vb->vb_int64 + 1;
5423static inline CC_HINT(always_inline)
5426 fr_sbuff_t *
in, fr_sbuff_parse_rules_t const *rules,
bool tainted)
5491 rules->escapes ? rules->escapes->chr :
'\0');
5503 fr_sbuff_err_to_strerror(err);
5527 static fr_sbuff_parse_rules_t default_rules;
5534 if (!rules) rules = &default_rules;
5542 if (dst_enumv && dst_enumv->flags.has_value && (dst_type !=
FR_TYPE_ATTR)) {
5559 if (!rules->escapes) {
5563 fr_sbuff_marker(&m, &our_in);
5568 fr_sbuff_marker_release(&m);
5570 if (!
len)
goto parse;
5604 rules->terminals, rules->escapes) < 0) {
5609 fr_sbuff_set_to_start(&our_in);
5615 fr_sbuff_set_to_start(&our_in);
5638 if (!dst_enumv || !unescaped) {
5641 if (
unlikely(fr_sbuff_out_aunescape_until(ctx, &
buff, NULL, &our_in, SIZE_MAX,
5642 rules->terminals, rules->escapes) < 0)) {
5668 if (!dst_enumv || !unescaped) {
5674 if (fr_sbuff_out_aunescape_until(ctx, &
buff, &
len, &our_in, SIZE_MAX,
5675 rules->terminals, rules->escapes) < 0) {
5704 bin = talloc_zero_array(ctx,
uint8_t, 0);
5719 fr_sbuff_marker(&hex_start, &our_in);
5736 if ((hex_len & 0x01) != 0) {
5762 if (!name_len)
goto empty_is_invalid;
5774 "for non-prefix types", addr.
prefix);
5778 memcpy(&dst->vb_ip, &addr,
sizeof(dst->vb_ip));
5785 if (!name_len)
goto empty_is_invalid;
5795 if (!name_len)
goto empty_is_invalid;
5811 if (addr.
prefix != 128) {
5814 "for non-prefix types", addr.
prefix);
5818 memcpy(&dst->vb_ip, &addr,
sizeof(dst->vb_ip));
5825 if (!name_len)
goto empty_is_invalid;
5835 if (!name_len)
goto empty_is_invalid;
5847 if ((addr.
af == AF_INET) && (addr.
prefix != 32)) {
5848 goto fail_ipv4_prefix;
5851 if ((addr.
af == AF_INET6) && (addr.
prefix != 128)) {
5852 goto fail_ipv6_prefix;
5855 memcpy(&dst->vb_ip, &addr,
sizeof(dst->vb_ip));
5862 if (!name_len)
goto empty_is_invalid;
5900 if (!rules->escapes) {
5905 dst->vb_bool = (stmp != 0);
5910 dst->vb_bool = (utmp != 0);
5916 "\"yes\", \"no\", \"true\", \"false\" or any unquoted integer");
5957 fr_sbuff_set_to_start(&our_in);
5962 fr_sbuff_err_to_strerror(err);
6005 false, rules->terminals);
6006 if (slen < 0)
return slen;
6037 fr_strerror_printf(
"Can only start from data type 'tlv' for data type 'attribute', and not from %s", dst_enumv->name);
6052 fr_sbuff_marker(&m, &our_in);
6058 fr_sbuff_marker_release(&m);
6069 if (!dst->vb_attr) {
6076 if (dst->vb_attr->dict != dst_enumv->dict) {
6109 if (slen <= 0)
goto invalid_attr;
6125 if (rules && rules->terminals) {
6130 rules->terminals, rules->escapes);
6164 dst->enumv = dst_enumv;
6181 dst->type = dst_type;
6182 dst->tainted =
false;
6188 dst->enumv = dst_enumv;
6189 fr_value_box_list_entry_init(dst);
6197 char const *
in,
size_t inlen,
6201 fr_sbuff_parse_rules_t prules = { .escapes = erules };
6204 if (slen <= 0)
return slen;
6207 fr_strerror_printf(
"Failed parsing '%s'. %zu bytes of trailing data after string value \"%pV\"",
6211 return (slen - inlen) - 1;
6238 if (
data->enumv &&
data->enumv->flags.has_value) {
6248 switch (
data->type) {
6251 data->vb_strvalue,
data->vb_length, e_rules);
6288 data->vb_ether[0],
data->vb_ether[1],
6289 data->vb_ether[2],
data->vb_ether[3],
6290 data->vb_ether[4],
data->vb_ether[5]);
6354 bool is_unsigned =
false;
6358 is_unsigned =
data->enumv->flags.is_unsigned;
6374 if (!e_rules || (!e_rules->do_oct && !e_rules->do_hex)) {
6385 NULL, &our_out,
UNCONST(fr_value_box_list_t *, &
data->vb_group),
6386 ", ", (
sizeof(
", ") - 1), e_rules,
6402 switch (
data->enumv->type) {
6478 switch (
data->type) {
6522 if (fr_value_box_list_empty(list))
return 0;
6529 if (!flatten)
goto print;
6531 sep, sep_len, e_rules,
6532 proc_action, safe_for, flatten);
6541 box_safe_for = safe_for;
6543 slen =
fr_sbuff_in_escape(&our_sbuff, (
char const *)vb->vb_strvalue, vb->vb_length, e_rules);
6563 if (e_rules) box_safe_for = safe_for;
6567 if (slen < 0)
return slen;
6572 if (sep && fr_value_box_list_next(list, vb)) {
6574 if (slen < 0)
return slen;
6586 (safety->
safe_for != box_safe_for)) {
6594 safety->
secret |= vb->vb_secret;
6633 uint8_t const *sep,
size_t sep_len,
6637 TALLOC_CTX *tmp_ctx = NULL;
6640 if (fr_value_box_list_empty(list))
return 0;
6645 if (!flatten)
goto cast;
6648 proc_action, flatten);
6667 if (!tmp_ctx) tmp_ctx = talloc_pool(NULL, 1024);
6689 if (sep && fr_value_box_list_next(list, vb)) {
6691 if (slen < 0)
goto error;
6738 fr_dbuff_uctx_talloc_t dbuff_tctx;
6745 fr_value_box_entry_t entry;
6748 if (fr_value_box_list_empty(list)) {
6757 if ((fr_value_box_list_num_elements(list) == 1) && (head_vb ==
out) && (head_vb->type ==
type))
return 0;
6767 if (
unlikely(!fr_sbuff_init_talloc(ctx, &sbuff, &sbuff_tctx, 256, max_size)))
return -1;
6789 if (
out == head_vb) {
6826 fr_value_box_list_insert_head(list, head_vb);
6842 proc_action, flatten) < 0) {
6843 fr_value_box_list_insert_head(list, head_vb);
6856 fr_value_box_list_insert_head(list,
out);
6883 proc_action, flatten) < 0)
goto error;
6942 ret = escape->
func(vb, uctx);
6948 if (!ret) vb->vb_safefor = escape->
safe_for;
6949 vb->tainted =
false;
6998 .always_escape =
false,
7038 .always_escape =
false,
7045 if (rcode < 0)
return rcode;
7050 if (rcode < 0)
return rcode;
7052 fr_assert(fr_value_box_list_num_elements(&vb->vb_group) == 0);
7064 if (slen < 0)
return -1;
7119 if (escape(escaped, &
FR_SBUFF_IN(vb->vb_strvalue, vb->vb_length)) < 0)
return -1;
7139 fr_value_box_list_remove(&child->vb_group, grandchild);
7140 if (steal) talloc_steal(ctx, grandchild);
7141 fr_value_box_list_insert_before(list, child, grandchild);
7162 char *aggr, *td = NULL;
7163 TALLOC_CTX *pool = NULL;
7165 if (!vb)
return NULL;
7168 if (!aggr)
return NULL;
7169 if (!fr_value_box_list_next(list, vb))
return aggr;
7175 pool = talloc_pool(NULL, 255);
7178 while ((vb = fr_value_box_list_next(list, vb))) {
7179 char *str, *new_aggr;
7212 char *aggr, *td = NULL;
7213 TALLOC_CTX *pool = NULL;
7215 if (!vb)
return NULL;
7222 if (!aggr)
return NULL;
7223 if (!fr_value_box_list_next(list, vb))
return aggr;
7229 pool = talloc_pool(NULL, 255);
7232 while ((vb = fr_value_box_list_next(list, vb))) {
7233 char *str, *new_aggr;
7267 return fr_hash(vb->vb_strvalue, vb->vb_length);
7270 return fr_hash(vb->vb_octets, vb->vb_length);
7273 return fr_hash(&vb->vb_attr,
sizeof(vb->vb_attr));
7300 while ((in_p = fr_value_box_list_next(
in, in_p))) {
7306 fr_value_box_list_talloc_free(
out);
7328 while ((vb = fr_value_box_list_next(
head, vb))) {
7330 if (vb->tainted)
return true;
7336#if defined(WITH_VERIFY_PTR) || !defined(NDEBUG)
7337#define VB_NAME "fr_value_box_t %p (from %s:%d)"
7338#define VB_NAME_LOCATION(_x) (void const *) (_x), (_x)->file ? (_x)->file : "", (_x)->line
7360 "incorrect, expected %" PRIx64
", got %" PRIx64,
7367 if (!vb->vb_length) {
7369 fr_fatal_assert_msg(!vb->vb_strvalue || (talloc_array_length(vb->vb_strvalue) == 1),
"CONSISTENCY CHECK FAILED %s[%d]: " VB_NAME " strvalue field "
7370 "wasn non-NULL, but length was %u",
7381 "CONSISTENCY CHECK FAILED %s[%i]: " VB_NAME " strvalue field "
7384 size_t len = talloc_array_length(vb->vb_strvalue);
7389 "len >= %zu, got %zu",
7392 vb->vb_length + 1,
len);
7398 if (!vb->vb_length) {
7400 fr_fatal_assert_msg(!vb->vb_octets || (talloc_array_length(vb->vb_octets) == 0),
"CONSISTENCY CHECK FAILED %s[%d]: " VB_NAME " octets field "
7401 "wasn non-NULL, but length was %u",
7460 vb->vb_safefor = safe_for;
7489 vb->vb_safefor = safe_for;
7499 if (
out ==
in)
return;
7501 out->vb_safefor =
in->vb_safefor;
7502 out->tainted =
in->tainted;
7503 out->vb_secret =
in->vb_secret;
7513 out->tainted =
in->tainted;
7514 out->vb_secret =
in->vb_secret;
7524 if (
out ==
in)
return;
7532 (
out->safe_for !=
in->safe_for)) {
7543 out->safe_for =
in->safe_for;
7550 out->secret |=
in->secret;
7558 out->tainted |=
in->tainted;
7568 box->safety = *safety;
7613 out->vb_secret =
false;
7641 return (fr_value_box_list_num_elements(&
in->vb_group) > 0);
7648 return (
in->vb_length > 0);
7671#define INFO_INDENT(_fmt, ...) fprintf(fp, "%*s" _fmt "\n", depth * 2, " ", ## __VA_ARGS__)
7717 vb->vb_secret ?
"s" :
"-",
7718 vb->tainted ?
"t" :
"-",
7723 vb->vb_secret ?
"s" :
"-",
7724 vb->tainted ?
"t" :
"-",
static int const char char buffer[256]
static int const char * fmt
#define fr_base16_encode(_out, _in)
#define fr_base16_decode(_err, _out, _in, _no_trailing)
static uint8_t overflow[100]
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define DIAG_OFF_OPTIONAL(_x)
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define SIZEOF_MEMBER(_t, _m)
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
#define DIAG_ON_OPTIONAL(_x)
#define MEMCMP_FIELDS(_a, _b, _field, _len_field)
Return the comparison of two opaque fields of a structure.
fr_cmp_ret_t
Result of an ordering comparison.
@ CMP_ERR
comparison failed
static fr_atomic_queue_t ** aq
static size_t min(size_t x, size_t y)
int fr_dbuff_trim_talloc(fr_dbuff_t *dbuff, size_t len)
Trim a talloced dbuff to the minimum length required to represent the contained string.
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
#define FR_DBUFF_OUT_UINT64V_RETURN(_num, _dbuff_or_marker, _len)
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer.
#define fr_dbuff_set(_dst, _src)
Set the 'current' position in a dbuff or marker using another dbuff or marker, a char pointer,...
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
#define fr_dbuff_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
#define FR_DBUFF_OUT_INT64V_RETURN(_num, _dbuff_or_marker, _len)
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer.
#define fr_dbuff_buff(_dbuff_or_marker)
Return the underlying buffer in a dbuff or one of marker.
#define fr_dbuff_out_memcpy(_out, _dbuff_or_marker, _outlen)
Copy exactly _outlen bytes from the dbuff.
#define FR_DBUFF_MEMSET_RETURN(_dbuff_or_marker, _c, _inlen)
Set _inlen bytes of a dbuff or marker to _c returning if there is insufficient space.
#define FR_DBUFF_OUT_MEMCPY_RETURN(_out, _dbuff_or_marker, _outlen)
Copy outlen bytes from the dbuff returning if there's insufficient data in the dbuff.
#define FR_DBUFF_IN_MEMCPY_RETURN(_dbuff_or_marker, _in, _inlen)
Copy exactly _inlen bytes into dbuff or marker returning if there's insufficient space.
#define fr_dbuff_in_memcpy(_dbuff_or_marker, _in, _inlen)
Copy exactly _inlen bytes into a dbuff or marker.
#define FR_DBUFF_IN_RETURN(_dbuff_or_marker, _in)
Copy data from a fixed sized C type into a dbuff returning if there is insufficient space.
#define FR_DBUFF(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
#define FR_DBUFF_OUT_RETURN(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type returning if there is insufficient data.
static fr_dbuff_t * fr_dbuff_init_talloc(TALLOC_CTX *ctx, fr_dbuff_t *dbuff, fr_dbuff_uctx_talloc_t *tctx, size_t init, size_t max)
Initialise a special dbuff which automatically extends as additional data is written.
#define FR_DBUFF_IN_BYTES_RETURN(_dbuff_or_marker,...)
Copy a byte sequence into a dbuff or marker returning if there's insufficient space.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
#define fr_fatal_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define fr_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error.
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_fatal_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
@ FR_DICT_ATTR_EXT_REF
Attribute references another attribute and/or dictionary.
#define da_is_length_field16(_da)
bool const fr_dict_attr_nested_allowed_chars[SBUFF_CHAR_CLASS]
Characters allowed in a nested dictionary attribute name.
static fr_dict_attr_t * fr_dict_attr_unknown_copy(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
#define da_is_length_field8(_da)
int fr_dict_protocol_reference(fr_dict_attr_t const **da_p, fr_dict_attr_t const *root, fr_sbuff_t *in)
Resolve a reference string to a dictionary attribute.
bool const fr_dict_enum_allowed_chars[SBUFF_CHAR_CLASS]
Characters that are allowed in dictionary enumeration value names.
static fr_cmp_ret_t fr_dict_attr_cmp(fr_dict_attr_t const *a, fr_dict_attr_t const *b)
fr_slen_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt))
Resolve an attribute using an OID string.
static fr_dict_attr_t * fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
fr_value_box_t const * value
Enum value (what name maps to).
char const * fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the name of an enum value in a fr_dict_attr_t.
fr_slen_t fr_dict_attr_unknown_afrom_oid_substr(TALLOC_CTX *ctx, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_type_t type))
Create a fr_dict_attr_t from an ASCII attribute and value.
#define FR_DICT_ATTR_OID_PRINT_RETURN(...)
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
fr_dict_enum_value_t const * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
Value of an enumerated attribute.
fr_dict_attr_ref_type_t type
The state of the reference.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
@ FR_DICT_ATTR_REF_ROOT
only for FR_TYPE_ATTR, point to the default root for enums
Attribute extension - Holds a reference to an attribute in another dictionary.
static int fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the tail of a list.
uint32_t fr_hash(void const *data, size_t size)
int fr_ipaddr_is_prefix(fr_ipaddr_t const *ipaddr)
Determine if an address is a prefix.
char * fr_inet_ntop_prefix(char out[static FR_IPADDR_PREFIX_STRLEN], size_t outlen, fr_ipaddr_t const *addr)
Print a fr_ipaddr_t as a CIDR style network prefix.
int fr_inet_pton6(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, bool fallback, bool mask)
Parse an IPv6 address or IPv6 prefix in presentation format (and others)
bool fr_hostname_lookups
hostname -> IP lookups?
int fr_inet_pton(fr_ipaddr_t *out, char const *value, ssize_t inlen, int af, bool resolve, bool mask)
Simple wrapper to decide whether an IP value is v4 or v6 and call the appropriate parser.
int fr_ipaddr_is_inaddr_any(fr_ipaddr_t const *ipaddr)
Determine if an address is the INADDR_ANY address for its address family.
char * fr_inet_ntop(char out[static FR_IPADDR_STRLEN], size_t outlen, fr_ipaddr_t const *addr)
Print the address portion of a fr_ipaddr_t.
void fr_ipaddr_mask(fr_ipaddr_t *addr, uint8_t prefix)
Zeroes out the host portion of an fr_ipaddr_t.
fr_cmp_ret_t fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
Compare two ip addresses.
char * fr_inet_ifid_ntop(char *out, size_t outlen, uint8_t const *ifid)
Print an interface-id in standard colon notation.
uint8_t * fr_inet_ifid_pton(uint8_t out[static 8], char const *ifid_str)
Convert interface-id in colon notation to 8 byte binary form.
uint8_t prefix
Prefix length - Between 0-32 for IPv4 and 0-128 for IPv6.
uint8_t addr[6]
Ethernet address.
Struct to represent an ethernet address.
#define fr_multiply(_out, _a, _b)
Multiplies two integers together.
static const uint8_t * zero
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_FLOAT32
Single precision floating point.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_MAX
Number of defined data types.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_COMBO_IP_PREFIX
IPv4 or IPv6 address prefix depending on length.
@ FR_TYPE_VALUE_BOX
A boxed value.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_IFID
Interface ID.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
@ FR_TYPE_FLOAT64
Double precision floating point.
int fr_inet_pton4(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, bool fallback, bool mask_bits)
fr_sbuff_err_t fr_sbuff_out_unescape_until(size_t *len, fr_sbuff_t *out, fr_sbuff_t *in, size_t max, fr_sbuff_term_t const *tt, fr_sbuff_unescape_rules_t const *u_rules)
static uint8_t depth(fr_minmax_heap_index_t i)
void * memset_explicit(void *ptr, int ch, size_t len)
static unsigned int fr_bytes_from_bits(unsigned int bits)
Convert bits (as in prefix length) to bytes, rounding up.
static uint64_t fr_nbo_to_uint64(uint8_t const data[static sizeof(uint64_t)])
Read an unsigned 64bit integer from wire format (big endian)
static void fr_nbo_from_uint64(uint8_t out[static sizeof(uint64_t)], uint64_t num)
Write out an unsigned 64bit integer in wire format (big endian)
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static SBUFF_CHAR_CLASS], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
int fr_sbuff_trim_talloc(fr_sbuff_t *sbuff, size_t len)
Trim a talloced sbuff to the minimum length required to represent the contained string.
ssize_t fr_sbuff_in_escape(fr_sbuff_t *sbuff, char const *in, size_t inlen, fr_sbuff_escape_rules_t const *e_rules)
Print an escaped string to an sbuff.
bool const sbuff_char_class_hex[SBUFF_CHAR_CLASS]
bool const sbuff_char_class_uint[SBUFF_CHAR_CLASS]
bool const sbuff_char_class_hostname[SBUFF_CHAR_CLASS]
bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Efficient terminal string search.
ssize_t fr_sbuff_in_bstrncpy(fr_sbuff_t *sbuff, char const *str, size_t len)
Copy bytes into the sbuff up to the first \0.
size_t fr_sbuff_adv_until(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt, char escape_chr)
Wind position until we hit a character in the terminal set.
fr_sbuff_err_t fr_sbuff_out_bstrncpy(size_t *len, fr_sbuff_t *out, fr_sbuff_t *in, size_t max)
Copy as many bytes as possible from a sbuff to a sbuff.
bool fr_sbuff_next_if_char(fr_sbuff_t *sbuff, char c)
Return true if the current char matches, and if it does, advance.
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_adv_past_str_literal(_sbuff, _needle)
#define FR_SBUFF_IN_CHAR_RETURN(_sbuff,...)
#define fr_sbuff_set(_dst, _src)
#define FR_SBUFF_IN(_start, _len_or_end)
#define fr_sbuff_adv_past_strcase_literal(_sbuff, _needle)
#define fr_sbuff_current(_sbuff_or_marker)
char chr
Character at the start of an escape sequence.
#define FR_SBUFF_IN_ESCAPE_BUFFER_RETURN(...)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
char const * name
Name for rule set to aid we debugging.
#define FR_SBUFF_IN_STRCPY_LITERAL_RETURN(_sbuff, _str)
#define fr_sbuff_extend(_sbuff_or_marker)
#define fr_sbuff_buff(_sbuff_or_marker)
#define FR_SBUFF_RETURN(_func, _sbuff,...)
#define fr_sbuff_is_char(_sbuff_or_marker, _c)
#define FR_SBUFF_ERROR_RETURN(_sbuff_or_marker)
#define FR_SBUFF_SET_RETURN(_dst, _src)
#define fr_sbuff_is_digit(_sbuff_or_marker)
#define FR_SBUFF_IN_SPRINTF_RETURN(...)
#define SBUFF_CHAR_UNPRINTABLES_EXTENDED
#define FR_SBUFF(_sbuff_or_marker)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define fr_sbuff_out(_out, _in)
#define FR_SBUFF_IN_ESCAPE_RETURN(...)
#define fr_sbuff_remaining(_sbuff_or_marker)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define SBUFF_CHAR_UNPRINTABLES_LOW
#define fr_sbuff_used(_sbuff_or_marker)
#define FR_SBUFF_TERM(_str)
Initialise a terminal structure with a single string.
#define FR_SBUFF_IN_STRCPY_RETURN(...)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
Talloc sbuff extension structure.
Set of parsing rules for *unescape_until functions.
fr_slen_t fr_size_from_str(size_t *out, fr_sbuff_t *in)
Parse a size string with optional unit.
fr_slen_t fr_size_to_str(fr_sbuff_t *out, size_t in)
Print a size string with unit.
static char buff[sizeof("18446744073709551615")+3]
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
fr_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
char * talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc,...)
Concatenate to + ...
uint8_t * talloc_typed_memdup(TALLOC_CTX *ctx, uint8_t const *in, size_t inlen)
Call talloc_memdup, setting the type on the new chunk correctly.
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
#define talloc_get_type_abort_const
static int talloc_const_free(void const *ptr)
Free const'd memory.
#define talloc_strdup(_ctx, _str)
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
fr_table_num_ordered_t const fr_time_precision_table[]
fr_slen_t fr_time_delta_from_substr(fr_time_delta_t *out, fr_sbuff_t *in, fr_time_res_t hint, bool no_trailing, fr_sbuff_term_t const *tt)
Create fr_time_delta_t from a string.
int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_res_t hint)
Convert string in various formats to a fr_unix_time_t.
int64_t fr_time_scale(int64_t t, fr_time_res_t hint)
Scale an input time to NSEC, clamping it at max / min.
fr_slen_t fr_time_delta_to_str(fr_sbuff_t *out, fr_time_delta_t delta, fr_time_res_t res, bool is_unsigned)
Print fr_time_delta_t to a string with an appropriate suffix.
fr_slen_t fr_unix_time_to_str(fr_sbuff_t *out, fr_unix_time_t time, fr_time_res_t res, bool utc)
Convert unix time to string.
int64_t const fr_time_multiplier_by_res[]
static fr_time_delta_t fr_time_delta_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
static int64_t fr_time_delta_to_integer(fr_time_delta_t delta, fr_time_res_t res)
static fr_unix_time_t fr_unix_time_from_nsec(int64_t nsec)
static int64_t fr_time_delta_unwrap(fr_time_delta_t time)
#define fr_time_delta_isneg(_a)
static fr_cmp_ret_t fr_unix_time_cmp(fr_unix_time_t a, fr_unix_time_t b)
Compare two fr_unix_time_t values.
#define fr_time_delta_wrap(_time)
#define fr_unix_time_wrap(_time)
fr_time_res_t
The base resolution for print parse operations.
static fr_unix_time_t fr_unix_time_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
static uint64_t fr_unix_time_unwrap(fr_unix_time_t time)
static fr_cmp_ret_t fr_time_delta_cmp(fr_time_delta_t a, fr_time_delta_t b)
Compare two fr_time_delta_t values.
static int64_t fr_unix_time_to_integer(fr_unix_time_t delta, fr_time_res_t res)
const char fr_token_quote[T_TOKEN_LAST]
Convert tokens back to a quoting character.
@ T_SOLIDUS_QUOTED_STRING
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const(_msg)
#define FR_TYPE_VARIABLE_SIZE
#define FR_TYPE_STRUCTURAL_EXCEPT_GROUP
#define fr_type_is_non_leaf(_x)
@ FR_TYPE_VALUE_BOX_CURSOR
cursor over a fr_value_box_t
@ FR_TYPE_UNION
A union of limited children.
@ FR_TYPE_ATTR
A contains an attribute reference.
@ FR_TYPE_PAIR_CURSOR
cursor over a fr_pair_t
#define fr_type_is_group(_x)
#define fr_type_is_variable_size(_x)
#define fr_type_is_structural(_x)
#define fr_type_is_fixed_size(_x)
#define FR_TYPE_STRUCTURAL
#define fr_type_is_ip(_x)
#define FR_TYPE_INTEGER_EXCEPT_BOOL
#define fr_type_is_leaf(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
#define FR_TYPE_FIXED_SIZE
int fr_value_box_bstrndup_dbuff(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
void fr_value_box_list_verify(char const *file, int line, fr_value_box_list_t const *list)
fr_cmp_ret_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
void fr_value_box_memdup_buffer_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, bool tainted)
Assign a talloced buffer to a box, but don't copy it.
size_t const fr_value_box_field_sizes[]
How many bytes wide each of the value data fields are.
fr_slen_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules)
int fr_value_box_hton(fr_value_box_t *dst, fr_value_box_t const *src)
Performs byte order reversal for types that need it.
size_t fr_value_box_network_length(fr_value_box_t const *value)
Get the size of the value held by the fr_value_box_t.
int fr_value_box_vasprintf(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, bool tainted, char const *fmt, va_list ap)
Print a formatted string using our internal printf wrapper and assign it to a value box.
void fr_value_box_set_void_shallow(fr_value_box_t *dst, void const *ptr)
Assign a void pointer to a box.
static void _fr_value_box_list_debug(FILE *fp, fr_value_box_list_t const *head, int depth)
#define INFO_INDENT(_fmt,...)
fr_sbuff_unescape_rules_t const fr_value_unescape_single
void fr_value_box_mark_unsafe(fr_value_box_t *vb)
Mark a value-box as "unsafe".
int fr_value_box_strtrim(TALLOC_CTX *ctx, fr_value_box_t *vb)
Trim the length of the string buffer to match the length of the C string.
uint32_t fr_value_box_hash(fr_value_box_t const *vb)
Hash the contents of a value box.
ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules)
Print one boxed value to a string.
fr_sbuff_escape_rules_t const fr_value_escape_double
fr_sbuff_err_t fr_value_substr_unescape(size_t *len, fr_sbuff_t *out, fr_sbuff_t *in, size_t max, char quote)
Convert a string value with escape sequences into its binary form.
fr_sbuff_parse_rules_t const value_parse_rules_single_3quoted
static fr_slen_t fr_value_box_from_numeric_substr(fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *rules, bool tainted)
Convert integer encoded as string to a fr_value_box_t type.
fr_sbuff_escape_rules_t const fr_value_escape_backtick
static int fr_value_box_cast_to_strvalue(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any supported type to a string.
int fr_value_box_escape_erules(fr_value_box_t *vb, void *uctx)
Escape a value-box in place using the supplied fr_sbuff_escape_rules_t in uctx.
fr_sbuff_escape_rules_t const fr_value_escape_secret
Escape secret fields by simply mashing all data to '.
fr_sbuff_parse_rules_t const value_parse_rules_double_unquoted
char * fr_value_box_list_aprint_secure(TALLOC_CTX *ctx, fr_value_box_list_t const *list, char const *delim, fr_sbuff_escape_rules_t const *e_rules)
Concatenate the string representations of a list of value boxes together hiding "secret" values.
fr_sbuff_parse_rules_t const value_parse_rules_solidus_quoted
ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
Decode a fr_value_box_t from serialized binary data.
int fr_value_box_mem_alloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Pre-allocate an octets buffer for filling by the caller.
int fr_value_box_memdup_buffer(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, bool tainted)
Copy a talloced buffer to a fr_value_box_t.
fr_sbuff_escape_rules_t const fr_value_escape_unprintables
#define network_min_size(_x)
How many bytes on-the-wire would a fr_value_box_t value consume.
int fr_value_box_bstrdup_buffer(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated talloced buffer to a fr_value_box_t.
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
int fr_value_box_asprintf(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, bool tainted, char const *fmt,...)
Print a formatted string using our internal printf wrapper and assign it to a value box.
ssize_t fr_value_box_list_concat_as_octets(fr_value_box_safety_t *safety, fr_dbuff_t *dbuff, fr_value_box_list_t *list, uint8_t const *sep, size_t sep_len, fr_value_box_list_action_t proc_action, bool flatten)
Concatenate a list of value boxes together.
fr_sbuff_parse_rules_t const * value_parse_rules_quoted[T_TOKEN_LAST]
Parse rules for quoted strings.
char * fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_list_t const *list, char const *delim, fr_sbuff_escape_rules_t const *e_rules)
Concatenate the string representations of a list of value boxes together.
int fr_value_box_mem_realloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
static size_t const fr_value_box_network_sizes[FR_TYPE_MAX+1][2]
fr_sbuff_escape_rules_t const fr_value_escape_solidus
static int fr_value_box_cast_to_float(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any value to a floating point value.
fr_sbuff_unescape_rules_t const * fr_value_unescape_by_quote[T_TOKEN_LAST]
#define SIGN_BIT_HIGH(_int, _len)
size_t const fr_value_box_offsets[]
Where the value starts in the fr_value_box_t.
#define VERIFY_CLEAR(_vb)
static void _fr_value_box_debug(FILE *fp, fr_value_box_t const *vb, int depth, int idx)
#define CAST_IP_FIX_COMBO
fr_sbuff_parse_rules_t const value_parse_rules_bareword_unquoted
Default formatting rules.
static int fr_value_box_cast_to_ipv4addr(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any supported type to an IPv4 address.
static const fr_value_box_ipaddr_sizes_t ipaddr_sizes[FR_TYPE_MAX]
int fr_value_box_escape_in_place_func(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_sbuff_escape_func_t escape)
Escape a value box in place using an sbuff escape function.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
fr_sbuff_parse_rules_t const value_parse_rules_single_unquoted
int fr_value_box_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two attributes using an operator.
int fr_value_box_list_escape_in_place(fr_value_box_list_t *list, fr_value_box_escape_t const *escape, void *uctx)
Escape a list of value boxes in place.
int fr_value_box_bstrndup_replace(TALLOC_CTX *ctx, fr_value_box_t *vb, char const *src, ssize_t len)
Free the existing buffer (if talloced) associated with the valuebox, and replace it with a copy of a ...
fr_sbuff_parse_rules_t const * value_parse_rules_unquoted_char[SBUFF_CHAR_CLASS]
uint64_t fr_value_box_as_uint64(fr_value_box_t const *vb)
Return a uint64_t from a fr_value_box_t.
bool fr_value_box_is_truthy(fr_value_box_t const *in)
Check truthiness of values.
int fr_value_box_cast_in_place(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv)
Convert one type of fr_value_box_t to another in place.
void fr_value_box_set_cursor_shallow(fr_value_box_t *dst, fr_type_t type, void *cursor, char const *name)
fr_sbuff_parse_rules_t const value_parse_rules_single_quoted
static uint8_t const v4_v6_map[]
v4 to v6 mapping prefix
void fr_value_box_memdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Assign a buffer to a box, but don't copy it.
static void _value_box_safety_merge(fr_value_box_safety_t *out, fr_value_box_safety_t const *in)
Merge one safety into another.
void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src)
Perform a shallow copy of a value_box.
static int fr_value_box_cast_to_octets(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any supported type to octets.
void fr_value_box_increment(fr_value_box_t *vb)
Increment a boxed value.
fr_slen_t fr_value_box_from_substr(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *rules)
Convert string value to a fr_value_box_t type.
void _fr_value_box_mark_safe_for(fr_value_box_t *vb, fr_value_box_safe_for_t safe_for)
Mark a value-box as "safe", of a particular type.
void fr_value_box_clear_value(fr_value_box_t *data)
Clear/free any existing value.
void fr_value_box_set_attr(fr_value_box_t *dst, fr_dict_attr_t const *da)
fr_sbuff_unescape_rules_t const fr_value_unescape_backtick
void fr_value_box_verify(char const *file, int line, fr_value_box_t const *vb)
Validation function to check that a fr_value_box_t is correctly initialised.
void fr_value_box_set_secret(fr_value_box_t *box, bool secret)
Mark a box as holding a secret, or not.
fr_sbuff_parse_rules_t const * value_parse_rules_3quoted[T_TOKEN_LAST]
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
#define network_max_size(_x)
void fr_value_box_strdup_shallow_replace(fr_value_box_t *vb, char const *src, ssize_t len)
Free the existing buffer (if talloced) associated with the valuebox, and replace it with a new one.
void fr_value_box_safety_set(fr_value_box_t *box, fr_value_box_safety_t const *safety)
Replace the safety of a box.
fr_sbuff_unescape_rules_t const fr_value_unescape_double
ssize_t fr_value_box_print_quoted(fr_sbuff_t *out, fr_value_box_t const *data, fr_token_t quote)
Print one boxed value to a string with quotes (where needed)
fr_sbuff_parse_rules_t const value_parse_rules_double_3quoted
static int fr_value_box_cast_to_integer(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any value to a signed or unsigned integer.
static int value_box_ipv6_scope_id_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value)
Encode the scope_id of an IPv6 address or prefix as one byte.
ssize_t fr_value_box_list_concat_as_string(fr_value_box_safety_t *safety, fr_sbuff_t *sbuff, fr_value_box_list_t *list, char const *sep, size_t sep_len, fr_sbuff_escape_rules_t const *e_rules, fr_value_box_list_action_t proc_action, fr_value_box_safe_for_t safe_for, bool flatten)
Concatenate a list of value boxes together.
static int fr_value_box_cast_to_ipv6prefix(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any supported type to an IPv6 address.
ssize_t fr_value_box_from_memory(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, void const *src, size_t len)
Decode a fr_value_box_t from a C type in memory.
void fr_value_box_safety_copy_changed(fr_value_box_t *out, fr_value_box_t const *in)
Copy the safety values from one box to another.
int fr_value_box_ipaddr(fr_value_box_t *dst, fr_dict_attr_t const *enumv, fr_ipaddr_t const *ipaddr, bool tainted)
Assign a fr_value_box_t value from an fr_ipaddr_t.
static void _value_box_list_safety_merge(fr_value_box_t *out, fr_value_box_list_t const *list)
Merge the safety of every leaf box in a list into out.
static int fr_value_box_cidr_cmp_op(fr_token_t op, int bytes, uint8_t a_net, uint8_t const *a, uint8_t b_net, uint8_t const *b)
static void fr_value_box_copy_meta(fr_value_box_t *dst, fr_value_box_t const *src)
Copy flags and type data from one value box to another.
void fr_value_box_list_mark_safe_for(fr_value_box_list_t *list, fr_value_box_safe_for_t safe_for)
Set the escaped flag for all value boxes in a list.
static int fr_value_box_fixed_size_from_octets(fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert octets to a fixed size value box value.
static int fr_value_box_cast_to_bool(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any supported type to a bool.
int fr_value_unbox_ipaddr(fr_ipaddr_t *dst, fr_value_box_t *src)
Unbox an IP address performing a type check.
int fr_value_box_escape_in_place_erules(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_sbuff_escape_rules_t const *erules)
Escape a value-box in place using sbuff escaping rules, and mark it safe-for.
fr_sbuff_parse_rules_t const value_parse_rules_bareword_quoted
void fr_value_box_safety_merge(fr_value_box_t *out, fr_value_box_t const *in)
Merge safety results.
fr_sbuff_parse_rules_t const value_parse_rules_backtick_3quoted
fr_sbuff_escape_rules_t const fr_value_escape_single
static uint64_t const fr_value_box_integer_max[]
void fr_value_box_strdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a box, but don't copy it.
void fr_value_box_list_debug(FILE *fp, fr_value_box_list_t const *head)
Print a list of value boxes as info messages.
fr_sbuff_parse_rules_t const * value_parse_rules_quoted_char[SBUFF_CHAR_CLASS]
fr_sbuff_parse_rules_t const value_parse_rules_solidus_unquoted
fr_sbuff_parse_rules_t const value_parse_rules_backtick_quoted
fr_sbuff_parse_rules_t const * value_parse_rules_unquoted[T_TOKEN_LAST]
Parse rules for non-quoted strings.
static int fr_value_box_cast_to_ipv4prefix(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any supported type to an IPv6 address.
static int fr_value_box_cast_to_ethernet(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any supported type to an ethernet address.
void fr_value_box_safety_copy(fr_value_box_t *out, fr_value_box_t const *in)
Copy the safety values from one box to another.
fr_sbuff_parse_rules_t const value_parse_rules_backtick_unquoted
ssize_t fr_value_box_ipaddr_from_network(fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, int prefix_len, uint8_t const *data, size_t data_len, bool fixed, bool tainted)
Decode a fr_value_box_t of type IP address / prefix.
fr_sbuff_parse_rules_t const value_parse_rules_double_quoted
fr_sbuff_escape_rules_t const * erules
int fr_value_box_bstr_alloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Alloc and assign an empty \0 terminated string to a fr_value_box_t.
#define SIGN_PROMOTE(_int, _len)
fr_sbuff_parse_rules_t const value_parse_rules_solidus_3quoted
static int _value_box_escape_rules(fr_value_box_t *vb, void *uctx)
int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t *src)
Copy value data verbatim moving any buffers to the specified context.
static int fr_value_box_cast_unsupported(fr_type_t dst, fr_type_t src)
int fr_value_box_to_key(uint8_t **out, size_t *outlen, fr_value_box_t const *value)
Get a key from a value box.
void fr_value_box_flatten(TALLOC_CTX *ctx, fr_value_box_list_t *list, bool steal, bool free)
Removes a single layer of nesting, moving all children into the parent list.
int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_list_t *out, fr_value_box_list_t const *in)
Do a full copy of a list of value boxes.
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
bool fr_value_box_list_tainted(fr_value_box_list_t const *head)
Check to see if any list members (or their children) are tainted.
ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value)
Encode a single value box, serializing its contents in generic network format.
#define VERIFY_IS_SET(_vb)
Sanity checks.
void fr_value_box_list_safety_merge(fr_value_box_t *out, fr_value_box_list_t const *list)
Set the safety of out to the most restrictive safety of any leaf box in a list.
static fr_cmp_ret_t float_cmp(double a, double b)
Compare two floating point numbers for equality.
static int64_t const fr_value_box_integer_min[]
int fr_value_box_bstr_realloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
int fr_value_box_memdup_dbuff(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
fr_sbuff_unescape_rules_t const * fr_value_unescape_by_char[SBUFF_CHAR_CLASS]
void fr_value_box_debug(FILE *fp, fr_value_box_t const *vb)
Print the value of a box as info messages.
int fr_regex_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two boxes using an operator.
fr_sbuff_unescape_rules_t const fr_value_unescape_solidus
fr_sbuff_escape_rules_t const * fr_value_escape_by_quote[T_TOKEN_LAST]
int fr_value_box_bstrdup_buffer_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a talloced buffer containing a nul terminated string to a box, but don't copy it.
static fr_dict_attr_t const * fr_value_box_attr_enumv(fr_dict_attr_t const *da)
int fr_value_box_escape_in_place(fr_value_box_t *vb, fr_value_box_escape_t const *escape, void *uctx)
Escape a single value box in place.
void fr_value_box_bstrndup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Assign a string to to a fr_value_box_t.
static int fr_value_box_cast_to_ipv6addr(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any supported type to an IPv6 address.
fr_sbuff_escape_rules_t const * fr_value_escape_by_char[SBUFF_CHAR_CLASS]
int fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Copy a buffer to a fr_value_box_t.
#define VB_NAME_LOCATION(_x)
fr_sbuff_err_t fr_value_str_unescape(size_t *len, fr_sbuff_t *out, fr_sbuff_t *in, size_t max, char quote)
Convert a string value with escape sequences into its binary form.
static int fr_value_box_cast_integer_to_integer(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert any signed or unsigned integer type to any other signed or unsigned integer type.
int fr_value_box_list_concat_in_place(TALLOC_CTX *ctx, fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, fr_value_box_list_action_t proc_action, bool flatten, size_t max_size)
Concatenate a list of value boxes.
fr_value_box_list_action_t
Actions to perform when we process a box in a list.
@ FR_VALUE_BOX_LIST_NONE
Do nothing to processed boxes.
@ FR_VALUE_BOX_LIST_REMOVE
Remove the box from the input list.
#define vb_should_free(_action)
#define vb_should_free_value(_action)
#define vb_should_remove(_action)
static fr_sbuff_err_t char size_t fr_sbuff_t * in
static int fr_value_box_memcpy_out(void *out, fr_value_box_t const *vb)
Copy the value of a value box to a field in a C struct.
fr_value_box_safe_for_t safe_for
A unique value to indicate if that value box is safe for consumption by a particular module for a par...
#define fr_value_box_mark_safe_for(_box, _safe_for)
static fr_slen_t fr_value_box_aprint(TALLOC_CTX *ctx, char **out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules) 1(fr_value_box_print
static fr_sbuff_err_t char size_t fr_sbuff_t size_t max
static bool fr_value_box_contains_secret(fr_value_box_t const *box)
unsigned int secret
Same as fr_dict_attr_flags_t secret.
#define FR_VALUE_BOX_NET_ERROR
Special value to indicate fr_value_box_from_network experienced a general error.
static uint8_t * fr_value_box_raw(fr_value_box_t const *vb, fr_type_t type)
Return a pointer to the "raw" value from a value-box.
#define fr_box_strvalue_len(_val, _len)
#define FR_VALUE_BOX_MAGIC
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
#define fr_value_box_is_safe_for(_box, _safe_for)
static fr_sbuff_err_t char ** out
static fr_sbuff_err_t char size_t * len
fr_value_box_safe_for_t safe_for
#define FR_VALUE_BOX_SAFE_FOR_NONE
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
#define VALUE_BOX_VERIFY(_x)
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
fr_value_box_escape_func_t func
static always_inline int fr_value_box_ethernet_addr(fr_value_box_t *dst, fr_dict_attr_t const *enumv, fr_ethernet_t const *src, bool tainted)
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
#define fr_value_box_list_foreach(_list_head, _iter)
#define FR_VALUE_BOX_NET_OOM
Special value to indicate fr_value_box_from_network hit an out of memory error.
#define FR_VALUE_BOX_SAFE_FOR_ANY