26RCSID(
"$Id: 281706eb41d5c550202d5b77ce2d457c137fc564 $")
28#include <freeradius-devel/util/strerror.h>
29#include <freeradius-devel/util/regex.h>
33#define swap(_a, _b) do { __typeof__ (_a) _tmp = _a; _a = _b; _b = _tmp; } while (0)
36#define ERR_UNDERFLOW (-4)
37#define ERR_OVERFLOW (-3)
38#define ERR_INVALID (-2)
40#define COERCE(_vb, _box, _type, _enumv) do { \
41 if (_vb->type != _type) { \
42 if (fr_value_box_cast(NULL, &_box, _type, _enumv, _vb) < 0) return -1; \
47#define COERCE_A(_type, _enumv) COERCE(a, one, _type, _enumv)
48#define COERCE_B(_type, _enumv) COERCE(b, two, _type, _enumv)
743 dst->vb_bool = a->vb_bool | b->vb_bool;
752 dst->vb_bool = a->vb_bool - b->vb_bool;
757 dst->vb_bool = a->vb_bool & b->vb_bool;
761 dst->vb_bool = a->vb_bool | b->vb_bool;
765 dst->vb_bool = a->vb_bool ^ b->vb_bool;
784 fr_strerror_const(
"Cannot perform operation on two values of type 'date'. One value must be a number.");
920 }
else if (op ==
T_MUL) {
929 len = a->vb_length + b->vb_length;
933 buf = talloc_array(ctx,
uint8_t, len);
940 memcpy(buf, a->vb_octets, a->vb_length);
941 memcpy(buf + a->vb_length, b->vb_octets, b->vb_length);
952 if (a->vb_length < b->vb_length) {
957 if (memcmp(a->vb_octets + a->vb_length - b->vb_length, b->vb_strvalue, b->vb_length) != 0) {
962 len = a->vb_length - b->vb_length;
963 buf = talloc_array(ctx,
uint8_t, len);
966 memcpy(buf, a->vb_strvalue, len);
973 if (a->vb_length != b->vb_length) {
979 buf = talloc_array(ctx,
uint8_t, a->vb_length);
982 for (len = 0; len < a->vb_length; len++) {
983 buf[len] = a->vb_octets[len] & b->vb_octets[len];
993 if (a->vb_length != b->vb_length)
goto length_error;
995 buf = talloc_array(ctx,
uint8_t, a->vb_length);
998 for (len = 0; len < a->vb_length; len++) {
999 buf[len] = a->vb_octets[len] | b->vb_octets[len];
1004 if (a->vb_length != b->vb_length)
goto length_error;
1006 buf = talloc_array(ctx,
uint8_t, a->vb_length);
1009 for (len = 0; len < a->vb_length; len++) {
1010 buf[len] = a->vb_octets[len] ^ b->vb_octets[len];
1018 len = a->vb_length - b->vb_uint32;
1019 buf = talloc_array(ctx,
uint8_t, len);
1022 memcpy(buf, a->vb_octets, len);
1031 len = a->vb_length - b->vb_uint32;
1033 buf = talloc_array(ctx,
uint8_t, len);
1036 memcpy(buf, a->vb_octets + b->vb_uint32, len);
1046 if (!b->vb_uint64 || !a->vb_length) {
1055 len = a->vb_length * b->vb_uint64;
1057 buf = talloc_array(ctx,
uint8_t, len);
1060 for (i = 0, p = buf; i < b->vb_uint64; i++, p += a->vb_length) {
1061 memcpy(p, a->vb_octets, a->vb_length);
1095 }
else if (op ==
T_MUL) {
1104 len = a->vb_length + b->vb_length;
1108 buf = talloc_array(ctx,
char, len + 1);
1115 len = a->vb_length + b->vb_length;
1116 memcpy(buf, a->vb_strvalue, a->vb_length);
1117 memcpy(buf + a->vb_length, b->vb_strvalue, b->vb_length);
1126 buf = talloc_array(ctx,
char, len + 1);
1129 len = a->vb_length + b->vb_length;
1130 memcpy(buf, b->vb_strvalue, b->vb_length);
1131 memcpy(buf + b->vb_length, a->vb_strvalue, a->vb_length);
1143 if (a->vb_length < b->vb_length) {
1148 if (memcmp(a->vb_strvalue + a->vb_length - b->vb_length, b->vb_strvalue, b->vb_length) != 0) {
1149 fr_strerror_const(
"Right side of substract is not a suffix of the input string");
1153 len = a->vb_length - b->vb_length;
1154 buf = talloc_array(ctx,
char, len + 1);
1157 memcpy(buf, a->vb_strvalue, len);
1167 len = a->vb_length - b->vb_uint32;
1168 buf = talloc_array(ctx,
char, len + 1);
1171 memcpy(buf, a->vb_strvalue, len);
1181 len = a->vb_length - b->vb_uint32;
1183 buf = talloc_array(ctx,
char, len + 1);
1186 memcpy(buf, a->vb_strvalue + b->vb_uint32, len);
1197 if (!b->vb_uint64 || !a->vb_length) {
1206 len = a->vb_length * b->vb_uint64;
1208 buf = talloc_array(ctx,
char, len + 1);
1211 for (i = 0, p = buf; i < b->vb_uint64; i++, p += a->vb_length) {
1212 memcpy(p, a->vb_strvalue, a->vb_length);
1242 out->vb_ip =
in->vb_ip;
1246 if (
in->vb_ip.af == AF_INET6)
goto cast_ipv6_prefix;
1249 out->vb_ip =
in->vb_ip;
1332 dst->vb_ip.af = AF_INET;
1333 dst->vb_ipv4addr = htonl(ntohl(a->vb_ipv4addr) | b->vb_uint32);
1334 dst->vb_ip.prefix = 32;
1387 if (b->vb_uint32 == 0) {
1388 dst->vb_ipv4addr = 0;
1391 }
else if ((~b->vb_uint32) == 0) {
1392 dst->vb_ipv4addr = a->vb_ipv4addr;
1398 mask = ~b->vb_uint32;
1400 if ((
mask & b->vb_uint32) !=
mask) {
1408 while (prefix > 0) {
1409 if (
mask == b->vb_uint32)
break;
1417 dst->vb_ipv4addr = htonl(ntohl(a->vb_ipv4addr) & b->vb_uint32);
1420 dst->vb_ip.af = AF_INET;
1421 dst->vb_ip.prefix = prefix;
1444 out->vb_ip =
in->vb_ip;
1448 if (
in->vb_ip.af == AF_INET)
goto cast_ipv4_prefix;
1452 out->vb_ip =
in->vb_ip;
1541 if (b->vb_uint64 >= (((uint64_t) 1) << (128 - a->vb_ip.prefix)))
return ERR_OVERFLOW;
1546 memcpy(&dst->vb_ipv6addr, a->vb_ipv6addr,
sizeof(dst->vb_ipv6addr));
1547 mask = b->vb_uint64;
1548 for (i = 15; i >= ((a->vb_ip.prefix + 7) >> 3); i--) {
1549 dst->vb_ipv6addr[i] |=
mask & 0xff;
1553 dst->vb_ip.af = AF_INET6;
1554 dst->vb_ip.prefix = 128;
1555 dst->vb_ip.scope_id = a->vb_ip.scope_id;
1571 for (i = 15; i >= 0; i--) {
1577 for (j = 0; j < 8; j++) {
1578 if ((
in[i] & (1 << j)) == 0) {
1591 int i, prefix = 128;
1598 if (a->vb_length != (128 / 8)) {
1606 pa = (
const uint8_t *) &a->vb_ipv6addr;
1613 if (b->vb_length != (128 / 8)) {
1621 pb = (
const uint8_t *) &b->vb_ip.addr.v6;
1630 pdst = (
uint8_t *) &dst->vb_ip.addr.v6;
1632 for (i = 0; i < 16; i++) {
1633 pdst[i] = pa[i] & pb[i];
1636 dst->vb_ip.af = AF_INET6;
1637 dst->vb_ip.prefix = prefix;
1649#define is_ipv6(_x) (((_x)->type == FR_TYPE_IPV6_ADDR) || ((_x)->type == FR_TYPE_IPV6_PREFIX) || ((((_x)->type == FR_TYPE_COMBO_IP_ADDR) || ((_x)->type == FR_TYPE_COMBO_IP_PREFIX)) && ((_x)->vb_ip.af == AF_INET6)))
1689 dst->vb_float32 = a->vb_float64 + b->vb_float64;
1693 dst->vb_float32 = a->vb_float64 - b->vb_float64;
1697 dst->vb_float32 = a->vb_float64 * b->vb_float64;
1701 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1703 dst->vb_float32 = a->vb_float64 / b->vb_float64;
1707 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1709 dst->vb_float32 = fmod(a->vb_float64, b->vb_float64);
1736 dst->vb_float64 = a->vb_float64 + b->vb_float64;
1740 dst->vb_float64 = a->vb_float64 - b->vb_float64;
1744 dst->vb_float64 = a->vb_float64 * b->vb_float64;
1748 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1750 dst->vb_float64 = a->vb_float64 / b->vb_float64;
1754 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1756 dst->vb_float64 = fmod(a->vb_float64, b->vb_float64);
1806 if (b->vb_uint64 == 0)
return ERR_ZERO;
1808 result.vb_uint64 = a->vb_uint64 / b->vb_uint64;
1812 if (b->vb_uint64 == 0)
return ERR_ZERO;
1814 result.vb_uint64 = a->vb_uint64 % b->vb_uint64;
1818 result.vb_uint64 = a->vb_uint64 & b->vb_uint64;
1822 result.vb_uint64 = a->vb_uint64 | b->vb_uint64;
1826 result.vb_uint64 = a->vb_uint64 ^ b->vb_uint64;
1830 if (b->vb_uint32 >= (8 *
sizeof(a->vb_uint64)))
return ERR_UNDERFLOW;
1832 result.vb_uint64 = a->vb_uint64 >> b->vb_uint32;
1836 if (b->vb_uint32 >= (8 *
sizeof(a->vb_uint64)))
return ERR_OVERFLOW;
1838 result.vb_uint64 = a->vb_uint64 << b->vb_uint32;
1893 if (b->vb_int64 == 0)
return ERR_ZERO;
1895 result.vb_int64 = a->vb_int64 / b->vb_int64;
1899 if (b->vb_int64 == 0)
return ERR_ZERO;
1901 result.vb_int64 = a->vb_int64 % b->vb_int64;
1905 result.vb_int64 = a->vb_int64 & b->vb_int64;
1909 result.vb_int64 = a->vb_int64 | b->vb_int64;
1913 result.vb_int64 = a->vb_int64 ^ b->vb_int64;
1917 if (b->vb_uint32 >= (8 *
sizeof(a->vb_int64)))
return ERR_UNDERFLOW;
1919 result.vb_int64 = a->vb_int64 >> b->vb_uint32;
1923 if (b->vb_uint32 >= (8 *
sizeof(a->vb_int64)))
return ERR_OVERFLOW;
1925 result.vb_int64 = a->vb_int64 << b->vb_uint32;
2013 if (a->type != b->type) {
2016 dst->vb_bool =
false;
2023 if (a->type != b->type)
goto mismatch_type;
2036 if (rcode < 0)
return rcode;
2039 dst->vb_bool = (rcode != 0);
2146 }
else if (a->type != b->type) {
2207 if (a->type != b->type) {
2246 if (hint == a->type) enumv = a->enumv;
2247 if (hint == b->type) enumv = b->enumv;
2262 if (a->type != hint) {
2267 if (b->type != hint) {
2274 if (rcode < 0)
goto done;
2277 dst->vb_bool = (rcode > 0);
2321 rcode = func(ctx, &
out, a, op, b);
2322 if (rcode < 0)
goto done;
2325 dst->tainted = a->tainted | b->tainted;
2448 vb = fr_value_box_list_head(&group->vb_group);
2456 while ((vb = fr_value_box_list_next(&group->vb_group, vb)) != NULL) {
2460 if (vb->type ==
type) {
2461 rcode = calc(ctx, &
out, &
out, op, vb);
2462 if (rcode < 0)
return rcode;
2467 rcode = calc(ctx, &
out, &
out, op, &box);
2468 if (rcode < 0)
return rcode;
2476#define T(_x) [T_OP_ ## _x ## _EQ] = T_ ## _x
2504 if (dst->immutable) {
2517 if (src == dst)
return 0;
2543 while ((vb = fr_value_box_list_next(&src->vb_group, vb)) != NULL) {
2545 if (rcode < 0)
break;
2565 if (dst->immutable) {
2575 switch (src->type) {
2635#define COMP(_type, _field) case FR_TYPE_ ## _type: dst->vb_ ##_field = (_field ## _t) ~src->vb_ ##_field; break
2636 switch (src->type) {
2638 COMP(UINT16, uint16);
2639 COMP(UINT32, uint32);
2640 COMP(UINT64, uint64);
2654 }
else if (op ==
T_SUB) {
2670 }
else if (op ==
T_NOT) {
2675 dst->vb_bool = !
value;
2699 switch (
item->type) {
2709 if (
item->vb_length != 0)
return false;
2727 bool invert =
false;
2728 bool a_empty, b_empty;
2756 if (a_empty && b_empty) {
2777 if (rcode < 0)
return rcode;
2783 if (!dst->vb_bool)
continue;
2788 dst->vb_bool = !invert;
2799 dst->vb_bool = invert;
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
static int calc_date(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static const fr_type_t upcast_cmp[FR_TYPE_MAX+1][FR_TYPE_MAX+1]
Updates type (a,b) -> c.
static int calc_ipv4_addr(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int get_ipv6_prefix(uint8_t const *in)
static const fr_binary_op_t calc_type[FR_TYPE_MAX+1]
Map output type to its associated function.
static int calc_ipv6_addr(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int invalid_type(fr_type_t type)
static const fr_type_t upcast_op[FR_TYPE_MAX+1][FR_TYPE_MAX+1]
Updates type (a,b) -> c.
static int calc_float32(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
#define COERCE_A(_type, _enumv)
static int calc_ipv4_prefix(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static const fr_type_t upcast_unsigned[FR_TYPE_MAX+1]
static int calc_uint64(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int calc_octets(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static int calc_combo_ip_addr(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int calc_ipv6_prefix(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static int cast_ipv6_addr(fr_value_box_t *out, fr_value_box_t const *in)
static int handle_result(fr_type_t type, fr_token_t op, int rcode)
static int calc_int64(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int calc_bool(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static int calc_string(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
int fr_value_calc_list_cmp(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_list_t const *list1, fr_token_t op, fr_value_box_list_t const *list2)
static int calc_combo_ip_prefix(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int calc_time_delta(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
int(* fr_binary_op_t)(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static int cast_ipv4_addr(fr_value_box_t *out, fr_value_box_t const *in)
static bool fr_value_calc_list_empty(fr_value_box_list_t const *list)
static int calc_float64(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
int fr_value_calc_nary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_token_t op, fr_value_box_t const *group)
Calculate DST = OP { A, B, C, ... }.
#define COERCE_B(_type, _enumv)
static const fr_token_t assignment2op[T_TOKEN_LAST]
int fr_value_calc_assignment_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
Calculate DST OP SRC.
int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
Calculate DST = A OP B.
#define COMP(_type, _field)
int fr_value_calc_unary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
Calculate unary operations.
#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_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
#define FR_DBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
Create a function local and thread local extensible dbuff.
static void * item(fr_lst_t const *lst, fr_lst_index_t idx)
#define fr_sub(_out, _a, _b)
Subtracts two integers.
#define fr_add(_out, _a, _b)
Adds two integers.
#define fr_multiply(_out, _a, _b)
Multiplies two integers together.
@ 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_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_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_INT32
32 Bit signed integer.
@ 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_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.
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_used(_sbuff_or_marker)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
fr_aka_sim_id_type_t type
static int64_t fr_time_delta_unwrap(fr_time_delta_t time)
#define fr_time_delta_wrap(_time)
#define fr_time_delta_ispos(_a)
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)
char const * fr_tokens[T_TOKEN_LAST]
const bool fr_comparison_op[T_TOKEN_LAST]
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.
char const * fr_strerror(void)
Get the last library error.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
#define fr_type_is_structural(_x)
#define fr_type_is_integer_except_bool(_x)
#define fr_type_is_numeric(_x)
#define fr_type_is_signed(_x)
#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_is_integer(_x)
ssize_t fr_value_box_list_concat_as_string(fr_value_box_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.
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_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
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.
bool fr_value_box_is_truthy(fr_value_box_t const *in)
Check truthiness of values.
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.
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.
ssize_t fr_value_box_list_concat_as_octets(fr_value_box_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.
void fr_value_box_clear_value(fr_value_box_t *data)
Clear/free any existing value.
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.
void fr_value_box_safety_merge(fr_value_box_t *out, fr_value_box_t const *in)
Merge safety results.
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.
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
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.
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.
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.
@ FR_VALUE_BOX_LIST_NONE
Do nothing to processed boxes.
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
#define fr_value_box_list_foreach(_list_head, _iter)
static size_t char ** out
#define FR_VALUE_BOX_SAFE_FOR_ANY