... and modify all the hundres of places which get pair type from vp->da->type, to get it from the boxed value instead.
Add additional validation functions to check for places where the box type isn't set correctly.
References #1883
Closes #1012
extern size_t const value_box_field_sizes[];
extern size_t const value_box_offsets[];
-int value_box_cmp(PW_TYPE a_type, value_box_t const *a,
- PW_TYPE b_type, value_box_t const *b);
+int value_box_cmp(value_box_t const *a, value_box_t const *b);
-int value_box_cmp_op(FR_TOKEN op,
- PW_TYPE a_type, value_box_t const *a,
- PW_TYPE b_type, value_box_t const *b);
+int value_box_cmp_op(FR_TOKEN op, value_box_t const *a, value_box_t const *b);
size_t fr_value_str_unescape(uint8_t *out, char const *in, size_t inlen, char quote);
+void value_box_clear(value_box_t *data);
+
int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
- PW_TYPE *src_type, fr_dict_attr_t const *src_enumv,
- char const *src, ssize_t src_len, char quote);
+ PW_TYPE *type, fr_dict_attr_t const *enumv,
+ char const *in, ssize_t inlen, char quote);
-void value_box_hton(value_box_t *dst, PW_TYPE type, value_box_t const *src);
+int value_box_hton(value_box_t *dst, value_box_t const *src);
int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
- PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv,
- PW_TYPE src_type, fr_dict_attr_t const *src_enumv,
- value_box_t const *src);
+ PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv,
+ value_box_t const *src);
-int value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE type, const value_box_t *src);
+int value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, const value_box_t *src);
size_t value_box_snprint(char *out, size_t outlen,
- PW_TYPE type, fr_dict_attr_t const *enumv,
value_box_t const *data, char quote);
-int value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE type, value_box_t const *src);
+int value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, value_box_t const *src);
-char *value_box_asprint(TALLOC_CTX *ctx,
- PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data,
- char quote);
+char *value_box_asprint(TALLOC_CTX *ctx, value_box_t const *data, char quote);
extern uint32_t fr_max_attributes; /* per incoming packet */
#define FR_MAX_PACKET_CODE (52)
double decimal; //!< Double precision float.
uint32_t date; //!< Date (32bit Unix timestamp).
- uint8_t filter[32]; //!< Ascend binary format a packed data structure.
+ uint8_t filter[32]; //!< Ascend binary format (a packed data structure).
} datum;
#define vp_decimal data.datum.decimal
#define vp_ptr data.datum.ptr //!< Either octets or strvalue
+#define vp_type data.type
#define vp_length data.length
#define vp_tainted data.tainted
void fr_pair_replace(VALUE_PAIR **head, VALUE_PAIR *add);
int fr_pair_update_by_num(TALLOC_CTX *ctx, VALUE_PAIR **list,
- unsigned int vendor, unsigned int attr, int8_t tag, PW_TYPE type,
+ unsigned int vendor, unsigned int attr, int8_t tag,
value_box_t *value);
void fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int attr, int8_t tag);
* - 0 if not equal.
* - -1 on failure.
*/
-#define fr_pair_cmp_op(_op, _a, _b) value_box_cmp_op(_op, _a->da->type, &_a->data, _b->da->type, &_b->data)
+#define fr_pair_cmp_op(_op, _a, _b) value_box_cmp_op(_op, &_a->data, &_b->data)
int8_t fr_pair_cmp_by_da_tag(void const *a, void const *b);
int8_t fr_pair_cmp_by_parent_num_tag(void const *a, void const *b);
int fr_pair_cmp(VALUE_PAIR *a, VALUE_PAIR *b);
/*
* Attribute value. Typically used as the RHS of an update map.
*/
- struct {
- PW_TYPE type; //!< Type of data.
- value_box_t data; //!< Value data.
- } literal;
+ value_box_t literal; //!< Value data.
xlat_exp_t *xlat; //!< pre-parsed xlat_exp_t
* @{
*/
#define tmpl_value_box data.literal
-#define tmpl_value_box_type data.literal.type
-#define tmpl_value_box_length data.literal.data.length
-#define tmpl_value_box_datum data.literal.data
+#define tmpl_value_box_datum data.literal.datum
+#define tmpl_value_box_type data.literal.type
+#define tmpl_value_box_length data.literal.length
/* @} **/
/** @name Field accessors for #TMPL_TYPE_REGEX_STRUCT and #TMPL_TYPE_REGEX
void tmpl_from_da(vp_tmpl_t *vpt, fr_dict_attr_t const *da, int8_t tag, int num,
request_refs_t request, pair_lists_t list);
-int tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, value_box_t *data,
- PW_TYPE type, fr_dict_attr_t const *enumv, bool steal);
+int tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, value_box_t *data, bool steal);
ssize_t tmpl_from_attr_substr(vp_tmpl_t *vpt, char const *name,
request_refs_t request_def, pair_lists_t list_def,
int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
vp_tmpl_t const *vpt, fr_dict_attr_t const *cast);
-size_t tmpl_snprint(char *buffer, size_t bufsize, vp_tmpl_t const *vpt,
- fr_dict_attr_t const *values);
+size_t tmpl_snprint(char *buffer, size_t bufsize, vp_tmpl_t const *vpt);
ssize_t _tmpl_to_type(void *out,
uint8_t *buff, size_t outlen,
*/
vp->da = da;
vp->vp_length = da->flags.length;
+ vp->vp_type = da->type;
+ if (fr_dict_enum_types[da->type]) vp->data.datum.enumv = da;
return vp;
}
return n;
}
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
n->vp_octets = NULL; /* else fr_pair_value_memcpy will free vp's value */
fr_pair_value_memcpy(n, vp->vp_octets, n->vp_length);
char const *attribute, char const *value,
FR_TOKEN op)
{
- ssize_t len;
- VALUE_PAIR *vp, *vp2;
- fr_dict_attr_t const *da;
- vp_cursor_t cursor;
+ ssize_t len;
+ VALUE_PAIR *vp, *vp2;
+ fr_dict_attr_t const *da;
+ vp_cursor_t cursor;
vp = fr_pair_alloc(ctx);
if (!vp) return NULL;
/*
* We allow this for stupidity, but it's really a bad idea.
*/
- if (vp->da->type == PW_TYPE_TLV) {
+ if (vp->vp_type == PW_TYPE_TLV) {
ssize_t len;
VALUE_PAIR *head = NULL;
PW_TYPE type = PW_TYPE_OCTETS;
* @param[in] attr Number of attribute to update.
* @param[in] vendor of attribute to update.
* @param[in] tag of attribute to update.
- * @param[in] type of value.
* @param[in] value to set.
* @return
* - 0 on success.
*/
int fr_pair_update_by_num(TALLOC_CTX *ctx, VALUE_PAIR **list,
unsigned int vendor, unsigned int attr, int8_t tag,
- PW_TYPE type, value_box_t *value)
+ value_box_t *value)
{
vp_cursor_t cursor;
VALUE_PAIR *vp;
vp = fr_pair_cursor_next_by_num(&cursor, vendor, attr, tag);
if (vp) {
VERIFY_VP(vp);
- if (value_box_steal(vp, &vp->data, type, value) < 0) return -1;
+ if (value_box_steal(vp, &vp->data, value) < 0) return -1;
return 0;
}
vp = fr_pair_afrom_num(ctx, vendor, attr);
if (!vp) return -1;
vp->tag = tag;
- if (value_box_steal(vp, &vp->data, type, value) < 0) return -1;
+ if (value_box_steal(vp, &vp->data, value) < 0) return -1;
fr_pair_cursor_append(&cursor, vp);
regex_t *preg;
char *value;
- if (!fr_cond_assert(a->da->type == PW_TYPE_STRING)) return -1;
+ if (!fr_cond_assert(a->vp_type == PW_TYPE_STRING)) return -1;
slen = regex_compile(NULL, &preg, a->xlat, talloc_array_length(a->xlat) - 1, false, false, false, true);
if (slen <= 0) {
return 1;
}
- ret = value_box_cmp(a_p->da->type, &a_p->data,
- b_p->da->type, &b_p->data);
+ ret = value_box_cmp(&a_p->data, &b_p->data);
if (ret != 0) {
(void)fr_cond_assert(ret >= -1); /* Comparison error */
return ret;
* so instead we over-write the
* vp that it's pointing to.
*/
- switch (found->da->type) {
+ switch (found->vp_type) {
default:
j = found->next;
memcpy(found, i, sizeof(*found));
return;
}
- for(i = *from; i; i = next) {
+ for (i = *from; i; i = next) {
VERIFY_VP(i);
next = i->next;
int fr_pair_value_from_str(VALUE_PAIR *vp, char const *value, size_t inlen)
{
PW_TYPE type;
- VERIFY_VP(vp);
if (!value) return -1;
return -1;
}
vp->da = da;
+ if (fr_dict_enum_types[da->type]) vp->data.datum.enumv = da;
}
vp->type = VT_DATA;
return 0;
}
-/** Set the type of the VALUE_PAIR value buffer to match it's fr_dict_attr_t
- *
- * @param vp to fixup.
- */
-inline static void fr_pair_value_set_type(VALUE_PAIR *vp)
-{
- if (!vp->vp_ptr) return;
-
- switch (vp->da->type) {
- case PW_TYPE_OCTETS:
- talloc_set_type(vp->vp_ptr, uint8_t);
- return;
-
- case PW_TYPE_STRING:
- talloc_set_type(vp->vp_ptr, char);
- return;
-
- default:
- return;
- }
-}
-
/** Copy data into an "octets" data type.
*
- * @param[in,out] vp to update
- * @param[in] src data to copy
- * @param[in] size of the data, may be 0 in which case previous value will be freed.
+ * @param[in,out] vp to update
+ * @param[in] src data to copy
+ * @param[in] size of the data.
*/
void fr_pair_value_memcpy(VALUE_PAIR *vp, uint8_t const *src, size_t size)
{
- uint8_t *p = NULL, *q;
-
- VERIFY_VP(vp);
+ uint8_t *p = NULL;
- if (size > 0) {
- p = talloc_memdup(vp, src, size);
- if (!p) return;
- talloc_set_type(p, uint8_t);
- }
+ p = talloc_memdup(vp, src, size);
+ if (!p) return;
- memcpy(&q, &vp->vp_octets, sizeof(q));
- TALLOC_FREE(q);
+ value_box_clear(&vp->data);
vp->vp_octets = p;
vp->vp_length = size;
+ vp->vp_type = PW_TYPE_OCTETS;
+ talloc_set_type(vp->vp_ptr, uint8_t);
- if (size > 0) fr_pair_value_set_type(vp);
+ vp->type = VT_DATA;
VERIFY_VP(vp);
}
/** Reparent an allocated octet buffer to a VALUE_PAIR
*
- * @param[in,out] vp to update
- * @param[in] src buffer to steal.
+ * @param[in,out] vp to update
+ * @param[in] src buffer to steal.
*/
void fr_pair_value_memsteal(VALUE_PAIR *vp, uint8_t const *src)
{
- uint8_t *q;
-
- VERIFY_VP(vp);
-
- memcpy(&q, &vp->vp_octets, sizeof(q));
- talloc_free(q);
+ value_box_clear(&vp->data);
vp->vp_octets = talloc_steal(vp, src);
- vp->type = VT_DATA;
vp->vp_length = talloc_array_length(vp->vp_octets);
- fr_pair_value_set_type(vp);
+ vp->vp_type = PW_TYPE_OCTETS;
+ talloc_set_type(vp->vp_ptr, uint8_t);
+
+ vp->type = VT_DATA;
VERIFY_VP(vp);
}
/** Reparent an allocated char buffer to a VALUE_PAIR
*
- * @param[in,out] vp to update
- * @param[in] src buffer to steal.
+ * @param[in,out] vp to update
+ * @param[in] src buffer to steal.
*/
void fr_pair_value_strsteal(VALUE_PAIR *vp, char const *src)
{
- uint8_t *q;
-
- VERIFY_VP(vp);
+ if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
- memcpy(&q, &vp->vp_octets, sizeof(q));
- talloc_free(q);
+ value_box_clear(&vp->data);
vp->vp_strvalue = talloc_steal(vp, src);
- vp->type = VT_DATA;
vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
- fr_pair_value_set_type(vp);
+ vp->vp_type = PW_TYPE_STRING;
+ talloc_set_type(vp->vp_ptr, char);
+
+ vp->type = VT_DATA;
VERIFY_VP(vp);
}
*
* If len is larger than the current buffer, the additional space will be filled with '\0'
*
- * @param[in,out] vp to update
- * @param[in] src buffer to steal.
- * @param[in] len of data in buffer.
+ * @note vp->da must be of type PW_TYPE_STRING.
+ *
+ * @param[in,out] vp to update
+ * @param[in] src buffer to steal.
+ * @param[in] len of data in buffer.
*/
void fr_pair_value_strnsteal(VALUE_PAIR *vp, char *src, size_t len)
{
- uint8_t *q;
char *p;
size_t buf_len;
- VERIFY_VP(vp);
+ if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
- memcpy(&q, &vp->vp_octets, sizeof(q));
- talloc_free(q);
+ value_box_clear(&vp->data);
buf_len = talloc_array_length(src);
if (buf_len > (len + 1)) {
} else {
vp->vp_strvalue = talloc_steal(vp, src);
}
- vp->vp_strvalue = talloc_steal(vp, src);
- vp->type = VT_DATA;
vp->vp_length = len;
- fr_pair_value_set_type(vp);
+ vp->vp_type = PW_TYPE_STRING;
+ talloc_set_type(vp->vp_ptr, char);
+
+ vp->type = VT_DATA;
VERIFY_VP(vp);
}
/** Copy data into an "string" data type.
+ *
+ * @note vp->da must be of type PW_TYPE_STRING.
*
* @param[in,out] vp to update
* @param[in] src data to copy
*/
void fr_pair_value_strcpy(VALUE_PAIR *vp, char const *src)
{
- char *p, *q;
+ char *p;
- VERIFY_VP(vp);
+ if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
p = talloc_strdup(vp, src);
-
if (!p) return;
- memcpy(&q, &vp->vp_strvalue, sizeof(q));
- talloc_free(q);
+ value_box_clear(&vp->data);
vp->vp_strvalue = p;
vp->type = VT_DATA;
vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
- fr_pair_value_set_type(vp);
+ vp->vp_type = PW_TYPE_STRING;
+ talloc_set_type(vp->vp_ptr, char);
VERIFY_VP(vp);
}
* @note unlike the original strncpy, this function does not stop
* if it finds \0 bytes embedded in the string.
*
+ * @note vp->da must be of type PW_TYPE_STRING.
+ *
* @param[in,out] vp to update.
* @param[in] src data to copy.
* @param[in] len of data to copy.
*/
void fr_pair_value_bstrncpy(VALUE_PAIR *vp, void const *src, size_t len)
{
- char *p, *q;
+ char *p;
- VERIFY_VP(vp);
+ if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
p = talloc_array(vp, char, len + 1);
if (!p) return;
memcpy(p, src, len); /* embdedded \0 safe */
p[len] = '\0';
- memcpy(&q, &vp->vp_strvalue, sizeof(q));
- talloc_free(q);
+ value_box_clear(&vp->data);
vp->vp_strvalue = p;
- vp->type = VT_DATA;
vp->vp_length = len;
- fr_pair_value_set_type(vp);
+ vp->vp_type = PW_TYPE_STRING;
+ talloc_set_type(vp->vp_ptr, char);
+
+ vp->type = VT_DATA;
VERIFY_VP(vp);
}
/** Print data into an "string" data type.
+ *
+ * @note vp->da must be of type PW_TYPE_STRING.
*
* @param[in,out] vp to update
* @param[in] fmt the format string
void fr_pair_value_snprintf(VALUE_PAIR *vp, char const *fmt, ...)
{
va_list ap;
- char *p, *q;
+ char *p;
- VERIFY_VP(vp);
+ if (!fr_cond_assert(vp->da->type == PW_TYPE_STRING)) return;
va_start(ap, fmt);
p = talloc_vasprintf(vp, fmt, ap);
va_end(ap);
-
if (!p) return;
- memcpy(&q, &vp->vp_strvalue, sizeof(q));
- talloc_free(q);
+ value_box_clear(&vp->data);
vp->vp_strvalue = p;
- vp->type = VT_DATA;
-
vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1;
- fr_pair_value_set_type(vp);
+ vp->vp_type = PW_TYPE_STRING;
+ talloc_set_type(vp->vp_ptr, char);
+
+ vp->type = VT_DATA;
VERIFY_VP(vp);
}
if (vp->type == VT_XLAT) return snprintf(out, outlen, "%c%s%c", quote, vp->xlat, quote);
- return value_box_snprint(out, outlen, vp->da->type, vp->da, &vp->data, quote);
+ return value_box_snprint(out, outlen, &vp->data, quote);
}
/** Print one attribute value to a string
{
VERIFY_VP(vp);
- if (vp->type == VT_XLAT) {
- return fr_asprint(ctx, vp->xlat, talloc_array_length(vp->xlat) - 1, quote);
- }
+ if (vp->type == VT_XLAT) return fr_asprint(ctx, vp->xlat, talloc_array_length(vp->xlat) - 1, quote);
- return value_box_asprint(ctx, vp->da->type, vp->da, &vp->data, quote);
+ return value_box_asprint(ctx, &vp->data, quote);
}
/** Return a const buffer for an enum type attribute
char const *str;
fr_dict_enum_t const *enumv = NULL;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_NUMERIC:
break;
return NULL;
}
- if (vp->da->flags.has_value) switch (vp->da->type) {
+ if (vp->da->flags.has_value) switch (vp->vp_type) {
case PW_TYPE_BOOLEAN:
return vp->vp_bool ? "yes" : "no";
value = fr_pair_value_asprint(ctx, vp, quote);
if (vp->da->flags.has_tag) {
- if (quote && (vp->da->type == PW_TYPE_STRING)) {
+ if (quote && (vp->vp_type == PW_TYPE_STRING)) {
str = talloc_asprintf(ctx, "%s:%d %s %c%s%c", vp->da->name, vp->tag, token, quote, value, quote);
} else {
str = talloc_asprintf(ctx, "%s:%d %s %s", vp->da->name, vp->tag, token, value);
}
} else {
- if (quote && (vp->da->type == PW_TYPE_STRING)) {
+ if (quote && (vp->vp_type == PW_TYPE_STRING)) {
str = talloc_asprintf(ctx, "%s %s %c%s%c", vp->da->name, token, quote, value, quote);
} else {
str = talloc_asprintf(ctx, "%s %s %s", vp->da->name, token, value);
fr_dict_verify(file, line, vp->da);
- if (vp->vp_ptr) switch (vp->da->type) {
+ if (vp->vp_ptr) switch (vp->vp_type) {
case PW_TYPE_OCTETS:
{
size_t len;
FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR attribute %p \"%s\" (%s) "
"not found in global dictionary",
file, line, vp->da, vp->da->name,
- fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
+ fr_int2str(dict_attr_types, vp->vp_type, "<INVALID>"));
if (!fr_cond_assert(0)) fr_exit_now(1);
}
if (!fr_cond_assert(0)) fr_exit_now(1);
}
}
+
+ if (vp->da->flags.is_raw || vp->da->flags.is_unknown) {
+ if (vp->data.type != PW_TYPE_OCTETS) {
+ FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR (raw/unknown) attribute %p \"%s\" "
+ "data type incorrect. Expected %s, got %s",
+ file, line, vp->da, vp->da->name,
+ fr_int2str(dict_attr_types, PW_TYPE_OCTETS, "<INVALID>"),
+ fr_int2str(dict_attr_types, vp->data.type, "<INVALID>"));
+ if (!fr_cond_assert(0)) fr_exit_now(1);
+ }
+ } else if (vp->da->type != vp->data.type) {
+ FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: VALUE_PAIR attribute %p \"%s\" "
+ "data type (%s) does not match da type (%s)",
+ file, line, vp->da, vp->da->name,
+ fr_int2str(dict_attr_types, vp->data.type, "<INVALID>"),
+ fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
+ if (!fr_cond_assert(0)) fr_exit_now(1);
+ }
}
/*
* string need to occur in the NULL ctx so we don't fragment
* any pool associated with it.
*/
- subst = value_box_asprint(NULL, in->type, in->datum.enumv, in, '"');
+ subst = value_box_asprint(NULL, in, '"');
if (!subst) {
talloc_free(out);
return NULL;
* because the talloc API won't let us. So, we
* just create a fake attribute.
*/
- vp = fr_pair_afrom_da(ctx,da);
+ vp = fr_pair_afrom_da(ctx, da);
if (!vp) return -1;
fr_pair_cursor_append(cursor, vp);
vp->vp_tainted = true; /* not REALLY necessary, but what the heck */
*/
if (outlen > vp->vp_length) outlen = vp->vp_length;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_STRING:
case PW_TYPE_OCTETS:
memcpy(out, vp->vp_ptr, outlen);
case PW_TYPE_TIMEVAL:
case PW_TYPE_DECIMAL:
case PW_TYPE_MAX:
- fr_strerror_printf("Cannot get data for VALUE_PAIR type %i", vp->da->type);
+ fr_strerror_printf("Cannot get data for VALUE_PAIR type %i", vp->vp_type);
return -1;
/* Don't add default */
default:
if (vp->da->flags.has_tag && TAG_VALID(vp->tag)) {
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
if (len > ((ssize_t) (outlen - 1))) len = outlen - 1;
ptr[0] = vp->tag;
ptr++;
- } else if (vp->da->type == PW_TYPE_INTEGER) {
+ } else if (vp->vp_type == PW_TYPE_INTEGER) {
buffer[0] = vp->tag;
} /* else it can't be any other type */
}
/*
* Fast path for the common case.
*/
- if (vp->da->parent->flags.is_root && !vp->da->flags.concat && (vp->da->type != PW_TYPE_TLV)) {
+ if (vp->da->parent->flags.is_root && !vp->da->flags.concat && (vp->vp_type != PW_TYPE_TLV)) {
tlv_stack[0] = vp->da;
tlv_stack[1] = NULL;
FR_PROTO_STACK_PRINT(tlv_stack, 0);
[PW_TYPE_MAX] = 0 /* Force compiler to allocate memory for all types */
};
+/** Copy flags and type data from one value box to another
+ *
+ * @param[in] dst to copy flags to
+ * @param[in] src of data.
+ */
+static inline void value_box_copy_attrs(value_box_t *dst, value_box_t const *src)
+{
+ dst->type = src->type;
+ dst->length = src->length;
+ dst->tainted = src->tainted;
+ if (fr_dict_enum_types[dst->type]) dst->datum.enumv = src->datum.enumv;
+}
+
/** Compare two values
*
- * @param[in] a_type of data to compare.
* @param[in] a Value to compare.
- * @param[in] b_type of data to compare.
* @param[in] b Value to compare.
* @return
* - -1 if a is less than b.
* - 1 if a is more than b.
* - < -1 on failure.
*/
-int value_box_cmp(PW_TYPE a_type, value_box_t const *a,
- PW_TYPE b_type, value_box_t const *b)
+int value_box_cmp(value_box_t const *a, value_box_t const *b)
{
int compare = 0;
- if (a_type != b_type) {
+ if (!fr_cond_assert(a->type != PW_TYPE_INVALID)) return -1;
+ if (!fr_cond_assert(b->type != PW_TYPE_INVALID)) return -1;
+
+ if (a->type != b->type) {
fr_strerror_printf("Can't compare values of different types");
return -2;
}
* After doing the previous check for special comparisons,
* do the per-type comparison here.
*/
- switch (a_type) {
+ switch (a->type) {
case PW_TYPE_ABINARY:
case PW_TYPE_OCTETS:
case PW_TYPE_STRING: /* We use memcmp to be \0 safe */
/** Compare two attributes using an operator
*
* @param[in] op to use in comparison.
- * @param[in] a_type of data to compare.
* @param[in] a Value to compare.
- * @param[in] b_type of data to compare.
* @param[in] b Value to compare.
* @return
* - 1 if true
* - 0 if false
* - -1 on failure.
*/
-int value_box_cmp_op(FR_TOKEN op,
- PW_TYPE a_type, value_box_t const *a,
- PW_TYPE b_type, value_box_t const *b)
+int value_box_cmp_op(FR_TOKEN op, value_box_t const *a, value_box_t const *b)
{
int compare = 0;
if (!a || !b) return -1;
- switch (a_type) {
+ if (!fr_cond_assert(a->type != PW_TYPE_INVALID)) return -1;
+ if (!fr_cond_assert(b->type != PW_TYPE_INVALID)) return -1;
+
+ switch (a->type) {
case PW_TYPE_IPV4_ADDR:
- switch (b_type) {
+ switch (b->type) {
case PW_TYPE_IPV4_ADDR: /* IPv4 and IPv4 */
goto cmp;
case PW_TYPE_IPV4_PREFIX: /* IPv4 and IPv4 Prefix */
return value_box_cidr_cmp_op(op, 4, 32, (uint8_t const *) &a->datum.ipaddr,
- b->datum.ipv4prefix[1], (uint8_t const *) &b->datum.ipv4prefix[2]);
+ b->datum.ipv4prefix[1], (uint8_t const *) &b->datum.ipv4prefix[2]);
default:
fr_strerror_printf("Cannot compare IPv4 with IPv6 address");
}
case PW_TYPE_IPV4_PREFIX: /* IPv4 and IPv4 Prefix */
- switch (b_type) {
+ switch (b->type) {
case PW_TYPE_IPV4_ADDR:
return value_box_cidr_cmp_op(op, 4, a->datum.ipv4prefix[1],
- (uint8_t const *) &a->datum.ipv4prefix[2],
- 32, (uint8_t const *) &b->datum.ipaddr);
+ (uint8_t const *) &a->datum.ipv4prefix[2],
+ 32, (uint8_t const *) &b->datum.ipaddr);
case PW_TYPE_IPV4_PREFIX: /* IPv4 Prefix and IPv4 Prefix */
return value_box_cidr_cmp_op(op, 4, a->datum.ipv4prefix[1],
- (uint8_t const *) &a->datum.ipv4prefix[2],
- b->datum.ipv4prefix[1], (uint8_t const *) &b->datum.ipv4prefix[2]);
+ (uint8_t const *) &a->datum.ipv4prefix[2],
+ b->datum.ipv4prefix[1], (uint8_t const *) &b->datum.ipv4prefix[2]);
default:
fr_strerror_printf("Cannot compare IPv4 with IPv6 address");
}
case PW_TYPE_IPV6_ADDR:
- switch (b_type) {
+ switch (b->type) {
case PW_TYPE_IPV6_ADDR: /* IPv6 and IPv6 */
goto cmp;
case PW_TYPE_IPV6_PREFIX: /* IPv6 and IPv6 Preifx */
return value_box_cidr_cmp_op(op, 16, 128, (uint8_t const *) &a->datum.ipv6addr,
- b->datum.ipv6prefix[1], (uint8_t const *) &b->datum.ipv6prefix[2]);
+ b->datum.ipv6prefix[1], (uint8_t const *) &b->datum.ipv6prefix[2]);
default:
fr_strerror_printf("Cannot compare IPv6 with IPv4 address");
}
case PW_TYPE_IPV6_PREFIX:
- switch (b_type) {
+ switch (b->type) {
case PW_TYPE_IPV6_ADDR: /* IPv6 Prefix and IPv6 */
return value_box_cidr_cmp_op(op, 16, a->datum.ipv6prefix[1],
- (uint8_t const *) &a->datum.ipv6prefix[2],
- 128, (uint8_t const *) &b->datum.ipv6addr);
+ (uint8_t const *) &a->datum.ipv6prefix[2],
+ 128, (uint8_t const *) &b->datum.ipv6addr);
case PW_TYPE_IPV6_PREFIX: /* IPv6 Prefix and IPv6 */
return value_box_cidr_cmp_op(op, 16, a->datum.ipv6prefix[1],
- (uint8_t const *) &a->datum.ipv6prefix[2],
- b->datum.ipv6prefix[1], (uint8_t const *) &b->datum.ipv6prefix[2]);
+ (uint8_t const *) &a->datum.ipv6prefix[2],
+ b->datum.ipv6prefix[1], (uint8_t const *) &b->datum.ipv6prefix[2]);
default:
fr_strerror_printf("Cannot compare IPv6 with IPv4 address");
default:
cmp:
- compare = value_box_cmp(a_type, a, b_type, b);
+ compare = value_box_cmp(a, b);
if (compare < -1) { /* comparison error */
return -1;
}
return out_p - out;
}
+/** Clear/free any existing value
+ *
+ * @note Do not use on uninitialised memory.
+ *
+ * @param[in] data to clear.
+ */
+void value_box_clear(value_box_t *data)
+{
+ switch (data->type) {
+ case PW_TYPE_OCTETS:
+ case PW_TYPE_STRING:
+ TALLOC_FREE(data->datum.ptr);
+ break;
+
+ case PW_TYPE_STRUCTURAL:
+ if (!fr_cond_assert(0)) return;
+
+ case PW_TYPE_INVALID:
+ return;
+
+ default:
+ memset(&data->datum, 0, dict_attr_sizes[data->type][1]);
+ break;
+ }
+
+ data->tainted = false;
+ data->type = PW_TYPE_INVALID;
+ data->length = 0;
+}
+
/** Convert string value to a value_box_t type
+ *
+ * @fixme Should take taint param.
*
* @param[in] ctx to alloc strings in.
* @param[out] dst where to write parsed value.
- * @param[in,out] src_type of value data to create/type of value created.
- * @param[in] src_enumv fr_dict_attr_t with string aliases for integer values.
+ * @param[in,out] dst_type of value data to create/dst_type of value created.
+ * @param[in] dst_enumv fr_dict_attr_t with string aliases for integer values.
* @param[in] in String to convert. Binary safe for variable length values
* if len is provided.
* @param[in] inlen may be < 0 in which case strlen(len) is used to determine
* - -1 on parse error.
*/
int value_box_from_str(TALLOC_CTX *ctx, value_box_t *dst,
- PW_TYPE *src_type, fr_dict_attr_t const *src_enumv,
- char const *in, ssize_t inlen, char quote)
+ PW_TYPE *dst_type, fr_dict_attr_t const *dst_enumv,
+ char const *in, ssize_t inlen, char quote)
{
fr_dict_enum_t *dval;
size_t len;
ssize_t ret;
char buffer[256];
+ if (!fr_cond_assert(*dst_type != PW_TYPE_INVALID)) return -1;
+
if (!in) return -1;
len = (inlen < 0) ? strlen(in) : (size_t)inlen;
/*
* Set size for all fixed length attributes.
*/
- ret = dict_attr_sizes[*src_type][1]; /* Max length */
+ ret = dict_attr_sizes[*dst_type][1]; /* Max length */
/*
- * It's a variable ret src_type so we just alloc a new buffer
+ * It's a variable ret src->dst_type so we just alloc a new buffer
* of size len and copy.
*/
- switch (*src_type) {
+ switch (*dst_type) {
case PW_TYPE_STRING:
{
char *buff, *p;
case PW_TYPE_STRUCTURAL_EXCEPT_VSA:
case PW_TYPE_VENDOR:
case PW_TYPE_BAD:
- fr_strerror_printf("Invalid type %d", *src_type);
+ fr_strerror_printf("Invalid dst_type %d", *dst_type);
return -1;
}
/*
- * It's a fixed size src_type, copy to a temporary buffer and
+ * It's a fixed size src->dst_type, copy to a temporary buffer and
* \0 terminate if insize >= 0.
*/
if (inlen > 0) {
in = buffer;
}
- switch (*src_type) {
+ switch (*dst_type) {
case PW_TYPE_BYTE:
{
char *p;
* Look for the named in for the given
* attribute.
*/
- if (src_enumv && *p && !is_whitespace(p)) {
- if ((dval = fr_dict_enum_by_name(NULL, src_enumv, in)) == NULL) {
+ if (dst_enumv && *p && !is_whitespace(p)) {
+ if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) {
fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s",
- in, src_enumv->name);
+ in, dst_enumv->name);
return -1;
}
* Look for the named in for the given
* attribute.
*/
- if (src_enumv && *p && !is_whitespace(p)) {
- if ((dval = fr_dict_enum_by_name(NULL, src_enumv, in)) == NULL) {
+ if (dst_enumv && *p && !is_whitespace(p)) {
+ if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) {
fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s",
- in, src_enumv->name);
+ in, dst_enumv->name);
return -1;
}
* Look for the named in for the given
* attribute.
*/
- if (src_enumv && *p && !is_whitespace(p)) {
- if ((dval = fr_dict_enum_by_name(NULL, src_enumv, in)) == NULL) {
+ if (dst_enumv && *p && !is_whitespace(p)) {
+ if ((dval = fr_dict_enum_by_name(NULL, dst_enumv, in)) == NULL) {
fr_strerror_printf("Unknown or invalid value \"%s\" for attribute %s",
- in, src_enumv->name);
+ in, dst_enumv->name);
return -1;
}
break;
/*
- * Crazy polymorphic (IPv4/IPv6) attribute src_type for WiMAX.
+ * Crazy polymorphic (IPv4/IPv6) attribute src->dst_type for WiMAX.
*
* We try and make is saner by replacing the original
- * da, with either an IPv4 or IPv6 da src_type.
+ * da, with either an IPv4 or IPv6 da src->dst_type.
*
* These are not dynamic da, and will have the same vendor
* and attribute as the original.
case PW_TYPE_COMBO_IP_ADDR:
{
if (inet_pton(AF_INET6, in, &dst->datum.ipv6addr) > 0) {
- *src_type = PW_TYPE_IPV6_ADDR;
+ *dst_type = PW_TYPE_IPV6_ADDR;
ret = dict_attr_sizes[PW_TYPE_COMBO_IP_ADDR][1]; /* size of IPv6 address */
} else {
fr_ipaddr_t ipaddr;
return -1;
}
- *src_type = PW_TYPE_IPV4_ADDR;
+ *dst_type = PW_TYPE_IPV4_ADDR;
dst->datum.ipaddr.s_addr = ipaddr.ipaddr.ip4addr.s_addr;
ret = dict_attr_sizes[PW_TYPE_COMBO_IP_ADDR][0]; /* size of IPv4 address */
}
case PW_TYPE_UNBOUNDED: /* Should have been dealt with above */
case PW_TYPE_STRUCTURAL: /* Listed again to suppress compiler warnings */
case PW_TYPE_BAD:
- fr_strerror_printf("Unknown attribute type %d", *src_type);
+ fr_strerror_printf("Unknown attribute dst_type %d", *dst_type);
return -1;
}
finish:
dst->length = ret;
+ dst->type = *dst_type;
+
+ /*
+ * Fixup enumv
+ */
+ if (fr_dict_enum_types[dst->type]) dst->datum.enumv = dst_enumv;
+
return 0;
}
/** Performs byte order reversal for types that need it
*
+ * @param[in] dst Where to write the result. May be the same as src.
+ * @param[in] src #value_box_t containing an integer value.
+ * @return
+ * - 0 on success.
+ * - -1 on failure.
*/
-void value_box_hton(value_box_t *dst, PW_TYPE type, value_box_t const *src)
+int value_box_hton(value_box_t *dst, value_box_t const *src)
{
+ if (!fr_cond_assert(src->type != PW_TYPE_INVALID)) return -1;
+
/* 8 byte integers */
- switch (type) {
+ switch (src->type) {
case PW_TYPE_INTEGER64:
dst->datum.integer64 = htonll(src->datum.integer64);
break;
case PW_TYPE_OCTETS:
case PW_TYPE_STRING:
- (void)fr_cond_assert(0);
- return; /* shouldn't happen */
+ if (!fr_cond_assert(0)) return -1; /* shouldn't happen */
default:
- value_box_copy(NULL, dst, type, src);
+ value_box_copy(NULL, dst, src);
break;
}
+
+ value_box_copy_attrs(dst, src);
+
+ return 0;
}
/** Convert one type of value_box_t to another
* @param dst Where to write result of casting.
* @param dst_type to cast to.
* @param dst_enumv Enumerated values used to converts strings to integers.
- * @param src_type to cast from.
- * @param src_enumv Enumerated values used to convert integers to strings.
* @param src Input data.
* @return
* - 0 on success.
* - -1 on failure.
*/
int value_box_cast(TALLOC_CTX *ctx, value_box_t *dst,
- PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv,
- PW_TYPE src_type, fr_dict_attr_t const *src_enumv,
- value_box_t const *src)
+ PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv,
+ value_box_t const *src)
{
+ if (!fr_cond_assert(dst_type != PW_TYPE_INVALID)) return -1;
+ if (!fr_cond_assert(src->type != PW_TYPE_INVALID)) return -1;
+
if (fr_dict_non_data_types[dst_type]) {
fr_strerror_printf("Invalid cast from %s to %s. Can only cast simple data types.",
- fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+ fr_int2str(dict_attr_types, src->type, "<INVALID>"),
fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
return -1;
}
/*
* If it's the same type, copy.
*/
- if (dst_type == src_type) return value_box_copy(ctx, dst, src_type, src);
+ if (dst_type == src->type) return value_box_copy(ctx, dst, src);
/*
* Deserialise a value_box_t
*/
- if (src_type == PW_TYPE_STRING) {
+ if (src->type == PW_TYPE_STRING) {
return value_box_from_str(ctx, dst, &dst_type, dst_enumv, src->datum.strvalue, src->length, '\0');
}
* Converts the src data to octets with no processing.
*/
if (dst_type == PW_TYPE_OCTETS) {
- value_box_hton(dst, src_type, src);
+ value_box_hton(dst, src);
dst->datum.octets = talloc_memdup(ctx, &dst->datum, src->length);
dst->length = src->length;
+ dst->type = dst_type;
talloc_set_type(dst->datum.octets, uint8_t);
return 0;
}
* Serialise a value_box_t
*/
if (dst_type == PW_TYPE_STRING) {
- dst->datum.strvalue = value_box_asprint(ctx, src_type, src_enumv, src, '\0');
+ dst->datum.strvalue = value_box_asprint(ctx, src, '\0');
dst->length = talloc_array_length(dst->datum.strvalue) - 1;
+ dst->type = dst_type;
return 0;
}
- if ((src_type == PW_TYPE_IFID) &&
+ if ((src->type == PW_TYPE_IFID) &&
(dst_type == PW_TYPE_INTEGER64)) {
memcpy(&dst->datum.integer64, src->datum.ifid, sizeof(src->datum.ifid));
dst->datum.integer64 = htonll(dst->datum.integer64);
+
fixed_length:
dst->length = dict_attr_sizes[dst_type][0];
+ dst->type = dst_type;
+ if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv;
+
return 0;
}
- if ((src_type == PW_TYPE_INTEGER64) &&
+ if ((src->type == PW_TYPE_INTEGER64) &&
(dst_type == PW_TYPE_ETHERNET)) {
uint8_t array[8];
uint64_t i;
}
if (dst_type == PW_TYPE_SHORT) {
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_BYTE:
dst->datum.ushort = src->datum.byte;
break;
* as the long one is on the LHS.
*/
if (dst_type == PW_TYPE_INTEGER) {
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_BYTE:
dst->datum.integer = src->datum.byte;
break;
* a larger type, but not vice-versa.
*/
if (dst_type == PW_TYPE_INTEGER64) {
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_BYTE:
dst->datum.integer64 = src->datum.byte;
break;
default:
invalid_cast:
fr_strerror_printf("Invalid cast from %s to %s",
- fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+ fr_int2str(dict_attr_types, src->type, "<INVALID>"),
fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
return -1;
* We can cast integers less that < INT_MAX to signed
*/
if (dst_type == PW_TYPE_SIGNED) {
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_BYTE:
dst->datum.sinteger = src->datum.byte;
break;
}
if (dst_type == PW_TYPE_TIMEVAL) {
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_BYTE:
dst->datum.timeval.tv_sec = src->datum.byte;
dst->datum.timeval.tv_usec = 0;
switch (dst_type) {
case PW_TYPE_IPV4_ADDR:
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_IPV6_ADDR:
if (memcmp(src->datum.ipv6addr.s6_addr, v4_v6_map, sizeof(v4_v6_map)) != 0) {
bad_v6_prefix_map:
fr_strerror_printf("Invalid cast from %s to %s. No IPv4-IPv6 mapping prefix",
- fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+ fr_int2str(dict_attr_types, src->type, "<INVALID>"),
fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
return -1;
}
bad_v4_prefix_len:
fr_strerror_printf("Invalid cast from %s to %s. Only /32 prefixes may be "
"cast to IP address types",
- fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+ fr_int2str(dict_attr_types, src->type, "<INVALID>"),
fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
return -1;
}
bad_v6_prefix_len:
fr_strerror_printf("Invalid cast from %s to %s. Only /128 prefixes may be "
"cast to IP address types",
- fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+ fr_int2str(dict_attr_types, src->type, "<INVALID>"),
fr_int2str(dict_attr_types, dst_type, "<INVALID>"));
return -1;
}
break;
case PW_TYPE_IPV6_ADDR:
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_IPV4_ADDR:
/* Add the v4/v6 mapping prefix */
memcpy(dst->datum.ipv6addr.s6_addr, v4_v6_map, sizeof(v4_v6_map));
break;
case PW_TYPE_IPV4_PREFIX:
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_IPV4_ADDR:
memcpy(&dst->datum.ipv4prefix[2], &src->datum.ipaddr, sizeof(dst->datum.ipv4prefix) - 2);
dst->datum.ipv4prefix[0] = 0;
break;
case PW_TYPE_IPV6_PREFIX:
- switch (src_type) {
+ switch (src->type) {
case PW_TYPE_IPV4_ADDR:
/* Add the v4/v6 mapping prefix */
memcpy(&dst->datum.ipv6prefix[2], v4_v6_map, sizeof(v4_v6_map));
*/
if ((src->length < dict_attr_sizes[dst_type][0]) ||
(src->length > dict_attr_sizes[dst_type][1])) {
- char const *src_type_name;
+ char const *type_name;
- src_type_name = fr_int2str(dict_attr_types, src_type, "<INVALID>");
+ type_name = fr_int2str(dict_attr_types, src->type, "<INVALID>");
fr_strerror_printf("Invalid cast from %s to %s. Length should be between %zu and %zu but is %zu",
- src_type_name,
+ type_name,
fr_int2str(dict_attr_types, dst_type, "<INVALID>"),
dict_attr_sizes[dst_type][0], dict_attr_sizes[dst_type][1],
src->length);
return -1;
}
- if (src_type == PW_TYPE_OCTETS) {
+ if (src->type == PW_TYPE_OCTETS) {
value_box_t tmp;
do_octets:
if (src->length < value_box_field_sizes[dst_type]) {
fr_strerror_printf("Invalid cast from %s to %s. Source is length %zd is smaller than destination type size %zd",
- fr_int2str(dict_attr_types, src_type, "<INVALID>"),
+ fr_int2str(dict_attr_types, src->type, "<INVALID>"),
fr_int2str(dict_attr_types, dst_type, "<INVALID>"),
src->length,
value_box_field_sizes[dst_type]);
return -1;
}
+ /*
+ * Copy the raw octets into the datum of a value_box
+ * inverting bytesex for integers (if LE).
+ */
memcpy(&tmp.datum, src->datum.octets, value_box_field_sizes[dst_type]);
+ tmp.type = dst_type;
+ tmp.length = value_box_field_sizes[dst_type];
+ if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv;
+
+ value_box_hton(dst, &tmp);
- value_box_hton(dst, dst_type, &tmp);
- dst->length = value_box_field_sizes[dst_type];
return 0;
}
* Convert host order to network byte order.
*/
if ((dst_type == PW_TYPE_IPV4_ADDR) &&
- ((src_type == PW_TYPE_INTEGER) ||
- (src_type == PW_TYPE_DATE) ||
- (src_type == PW_TYPE_SIGNED))) {
+ ((src->type == PW_TYPE_INTEGER) ||
+ (src->type == PW_TYPE_DATE) ||
+ (src->type == PW_TYPE_SIGNED))) {
dst->datum.ipaddr.s_addr = htonl(src->datum.integer);
- } else if ((src_type == PW_TYPE_IPV4_ADDR) &&
+ } else if ((src->type == PW_TYPE_IPV4_ADDR) &&
((dst_type == PW_TYPE_INTEGER) ||
(dst_type == PW_TYPE_DATE) ||
(dst_type == PW_TYPE_SIGNED))) {
} else { /* they're of the same byte order */
memcpy(&dst->datum, &src->datum, src->length);
}
+
dst->length = src->length;
+ dst->type = dst_type;
+ if (fr_dict_enum_types[dst_type]) dst->datum.enumv = dst_enumv;
return 0;
}
*
* @param ctx To allocate buffers in.
* @param dst Where to copy value_box to.
- * @param src_type Type of src.
* @param src Where to copy value_box from.
* @return
* - 0 on success.
* - -1 on failure.
*/
-int value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE src_type, const value_box_t *src)
+int value_box_copy(TALLOC_CTX *ctx, value_box_t *dst, const value_box_t *src)
{
- switch (src_type) {
+ if (!fr_cond_assert(src->type != PW_TYPE_INVALID)) return -1;
+
+ switch (src->type) {
default:
- memcpy(((uint8_t *)dst) + value_box_offsets[src_type],
- ((uint8_t const *)src) + value_box_offsets[src_type],
- value_box_field_sizes[src_type]);
+ memcpy(((uint8_t *)dst) + value_box_offsets[src->type],
+ ((uint8_t const *)src) + value_box_offsets[src->type],
+ value_box_field_sizes[src->type]);
break;
case PW_TYPE_STRING:
break;
}
- dst->type = src_type;
- dst->length = src->length;
- dst->tainted = src->tainted;
+ value_box_copy_attrs(dst, src);
return 0;
}
*
* @param ctx To allocate buffers in.
* @param dst Where to copy value_box to.
- * @param src_type Type of src.
* @param src Where to copy value_box from.
* @return
* - 0 on success.
* - -1 on failure.
*/
-int value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, PW_TYPE src_type, const value_box_t *src)
+int value_box_steal(TALLOC_CTX *ctx, value_box_t *dst, const value_box_t *src)
{
- switch (src_type) {
+ if (!fr_cond_assert(src->type != PW_TYPE_INVALID)) return -1;
+
+ switch (src->type) {
default:
memcpy(dst, src, sizeof(*src));
break;
}
break;
}
- dst->length = src->length;
+
+ value_box_copy_attrs(dst, src);
return 0;
}
/** Print one attribute value to a string
*
*/
-char *value_box_asprint(TALLOC_CTX *ctx,
- PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data, char quote)
+char *value_box_asprint(TALLOC_CTX *ctx, value_box_t const *data, char quote)
{
char *p = NULL;
- unsigned int i;
- switch (type) {
+ if (!fr_cond_assert(data->type != PW_TYPE_INVALID)) return NULL;
+
+ if (fr_dict_enum_types[data->type] && data->datum.enumv) {
+ fr_dict_enum_t const *dv;
+ value_box_t tmp;
+
+ value_box_cast(ctx, &tmp, PW_TYPE_INTEGER, NULL, data);
+
+ dv = fr_dict_enum_by_da(NULL, data->datum.enumv, tmp.datum.integer);
+ if (dv) return talloc_typed_strdup(ctx, dv->name);
+ }
+
+ switch (data->type) {
case PW_TYPE_STRING:
{
size_t len, ret;
break;
}
-
case PW_TYPE_BYTE:
- i = data->datum.byte;
-
- print_int:
- {
- fr_dict_enum_t const *dv;
-
- if (enumv && (dv = fr_dict_enum_by_da(NULL, enumv, i))) {
- p = talloc_typed_strdup(ctx, dv->name);
- } else {
- p = talloc_typed_asprintf(ctx, "%u", i);
- }
- }
+ p = talloc_typed_asprintf(ctx, "%u", data->datum.byte);
break;
case PW_TYPE_SHORT:
- i = data->datum.ushort;
- goto print_int;
+ p = talloc_typed_asprintf(ctx, "%u", data->datum.ushort);
+ break;
case PW_TYPE_INTEGER:
- i = data->datum.integer;
- goto print_int;
+ p = talloc_typed_asprintf(ctx, "%u", data->datum.integer);
+ break;
case PW_TYPE_INTEGER64:
p = talloc_typed_asprintf(ctx, "%" PRIu64, data->datum.integer64);
char buff[INET_ADDRSTRLEN + 4]; // + /prefix
buff[0] = '\0';
- value_box_snprint(buff, sizeof(buff), type, enumv, data, '\0');
+ value_box_snprint(buff, sizeof(buff), data, '\0');
p = talloc_typed_strdup(ctx, buff);
}
char buff[INET6_ADDRSTRLEN + 4]; // + /prefix
buff[0] = '\0';
- value_box_snprint(buff, sizeof(buff), type, enumv, data, '\0');
+ value_box_snprint(buff, sizeof(buff), data, '\0');
p = talloc_typed_strdup(ctx, buff);
}
*
* @param out Where to write the printed version of the attribute value.
* @param outlen Length of the output buffer.
- * @param type of data being printed.
- * @param enumv Enumerated string values for integer types.
* @param data to print.
* @param quote char to escape in string output.
* @return
* - The number of bytes written to the out buffer.
* - A number >= outlen if truncation has occurred.
*/
-size_t value_box_snprint(char *out, size_t outlen,
- PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data, char quote)
+size_t value_box_snprint(char *out, size_t outlen, value_box_t const *data, char quote)
{
- fr_dict_enum_t *v;
char buf[1024]; /* Interim buffer to use with poorly behaved printing functions */
char const *a = NULL;
char *p = out;
time_t t;
struct tm s_tm;
- unsigned int i;
size_t len = 0, freespace = outlen;
+ if (!fr_cond_assert(data->type != PW_TYPE_INVALID)) return -1;
+
if (!data) return 0;
if (outlen == 0) return data->length;
p = out;
- switch (type) {
+ if (fr_dict_enum_types[data->type] && data->datum.enumv) {
+ fr_dict_enum_t const *dv;
+ value_box_t tmp;
+
+ value_box_cast(NULL, &tmp, PW_TYPE_INTEGER, NULL, data);
+
+ dv = fr_dict_enum_by_da(NULL, data->datum.enumv, tmp.datum.integer);
+ if (dv) return strlcpy(out, dv->name, outlen);
+ }
+
+ switch (data->type) {
case PW_TYPE_STRING:
/*
return fr_snprint(out, outlen, data->datum.strvalue, data->length, quote);
case PW_TYPE_BYTE:
- i = data->datum.byte;
-
- print_int:
- /* Normal, non-tagged attribute */
- if (enumv && (v = fr_dict_enum_by_da(NULL, enumv, i)) != NULL) {
- a = v->name;
- len = strlen(a);
- } else {
- /* should never be truncated */
- len = snprintf(buf, sizeof(buf), "%u", i);
- a = buf;
- }
- break;
+ return snprintf(out, outlen, "%u", data->datum.byte);
case PW_TYPE_SHORT:
- i = data->datum.ushort;
- goto print_int;
+ return snprintf(out, outlen, "%u", data->datum.ushort);
case PW_TYPE_INTEGER:
- i = data->datum.integer;
- goto print_int;
+ return snprintf(out, outlen, "%u", data->datum.integer);
case PW_TYPE_INTEGER64:
return snprintf(out, outlen, "%" PRIu64, data->datum.integer64);
goto error;
}
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
RDEBUG2("%s = '%s'", vp->da->name, value);
cp = cf_pair_alloc(c->cs, vp->da->name, value, T_OP_SET,
T_BARE_WORD, T_SINGLE_QUOTED_STRING);
* - 1 for "match".
*/
static int cond_do_regex(REQUEST *request, fr_cond_t const *c,
- PW_TYPE lhs_type, value_box_t const *lhs,
- PW_TYPE rhs_type, value_box_t const *rhs)
+ value_box_t const *lhs,
+ value_box_t const *rhs)
{
vp_map_t const *map = c->data.map;
size_t nmatch = sizeof(rxmatch) / sizeof(regmatch_t);
if (!rad_cond_assert(lhs != NULL)) return -1;
- if (!rad_cond_assert(lhs_type == PW_TYPE_STRING)) return -1;
+ if (!rad_cond_assert(lhs->type == PW_TYPE_STRING)) return -1;
EVAL_DEBUG("CMP WITH REGEX %s %s",
map->rhs->tmpl_iflag ? "CASE INSENSITIVE" : "CASE SENSITIVE",
break;
default:
- if (!rad_cond_assert(rhs_type == PW_TYPE_STRING)) return -1;
+ if (!rad_cond_assert(rhs && rhs->type == PW_TYPE_STRING)) return -1;
if (!rad_cond_assert(rhs && rhs->datum.strvalue)) return -1;
slen = regex_compile(request, &rreg, rhs->datum.strvalue, rhs->length,
map->rhs->tmpl_iflag, map->rhs->tmpl_mflag, true, true);
#ifdef WITH_EVAL_DEBUG
static void cond_print_operands(REQUEST *request,
- PW_TYPE lhs_type, value_box_t const *lhs,
- PW_TYPE rhs_type, value_box_t const *rhs)
+ value_box_t const *lhs,
+ value_box_t const *rhs)
{
if (lhs) {
- if (lhs_type == PW_TYPE_STRING) {
+ if (lhs->type == PW_TYPE_STRING) {
EVAL_DEBUG("LHS: \"%s\" (%zu)" , lhs->datum.strvalue, lhs->length);
} else {
char *lhs_hex;
lhs_hex = talloc_array(request, char, (lhs->length * 2) + 1);
- if (lhs_type == PW_TYPE_OCTETS) {
+ if (lhs->type == PW_TYPE_OCTETS) {
fr_bin2hex(lhs_hex, lhs->datum.octets, lhs->length);
} else {
fr_bin2hex(lhs_hex, (uint8_t const *)&lhs->datum, lhs->length);
}
if (rhs) {
- if (rhs_type == PW_TYPE_STRING) {
+ if (rhs->type == PW_TYPE_STRING) {
EVAL_DEBUG("RHS: \"%s\" (%zu)" , rhs->datum.strvalue, rhs->length);
} else {
char *rhs_hex;
rhs_hex = talloc_array(request, char, (rhs->length * 2) + 1);
- if (rhs_type == PW_TYPE_OCTETS) {
+ if (rhs->type == PW_TYPE_OCTETS) {
fr_bin2hex(rhs_hex, rhs->datum.octets, rhs->length);
} else {
fr_bin2hex(rhs_hex, (uint8_t const *)&rhs->datum, rhs->length);
* - 0 for "no match".
* - 1 for "match".
*/
-static int cond_cmp_values(REQUEST *request, fr_cond_t const *c,
- PW_TYPE lhs_type, value_box_t const *lhs,
- PW_TYPE rhs_type, value_box_t const *rhs)
+static int cond_cmp_values(REQUEST *request, fr_cond_t const *c, value_box_t const *lhs, value_box_t const *rhs)
{
vp_map_t const *map = c->data.map;
int rcode;
#ifdef WITH_EVAL_DEBUG
- EVAL_DEBUG("CMP OPERANDS");
- cond_print_operands(request, lhs_type, lhs, rhs_type, rhs);
+ EVAL_DEBUG("CMP OPERANDS");
+ cond_print_operands(request, lhs, rhs);
#endif
#ifdef HAVE_REGEX
* Regex comparison
*/
if (map->op == T_OP_REG_EQ) {
- rcode = cond_do_regex(request, c, lhs_type, lhs, rhs_type, rhs);
+ rcode = cond_do_regex(request, c, lhs, rhs);
goto finish;
}
#endif
vp = fr_pair_afrom_da(request, map->lhs->tmpl_da);
vp->op = c->data.map->op;
- value_box_copy(vp, &vp->data, rhs_type, rhs);
+ value_box_copy(vp, &vp->data, rhs);
rcode = paircompare(request, request->packet->vps, vp, NULL);
rcode = (rcode == 0) ? 1 : 0;
goto finish;
}
- /*
- * At this point both operands should have been normalised
- * to the same type, and there's no special comparisons
- * left.
- */
- rad_assert(lhs_type == rhs_type);
-
EVAL_DEBUG("CMP WITH VALUE DATA");
- rcode = value_box_cmp_op(map->op, lhs_type, lhs, rhs_type, rhs);
+ rcode = value_box_cmp_op(map->op, lhs, rhs);
finish:
switch (rcode) {
case 0:
* - 0 for "no match".
* - 1 for "match".
*/
-static int cond_normalise_and_cmp(REQUEST *request, fr_cond_t const *c,
- PW_TYPE lhs_type, fr_dict_attr_t const *lhs_enumv,
- value_box_t const *lhs)
+static int cond_normalise_and_cmp(REQUEST *request, fr_cond_t const *c, value_box_t const *lhs)
{
- vp_map_t const *map = c->data.map;
+ vp_map_t const *map = c->data.map;
- fr_dict_attr_t const *cast = NULL;
- PW_TYPE cast_type = PW_TYPE_INVALID;
+ int rcode;
- int rcode;
+ value_box_t *rhs = NULL;
- PW_TYPE rhs_type = PW_TYPE_INVALID;
- fr_dict_attr_t const *rhs_enumv = NULL;
- value_box_t *rhs = NULL;
+ fr_dict_attr_t const *cast = NULL;
+ PW_TYPE cast_type = PW_TYPE_INVALID;
- value_box_t lhs_cast, rhs_cast;
- void *lhs_cast_buff = NULL, *rhs_cast_buff = NULL;
+ value_box_t lhs_cast, rhs_cast;
+ void *lhs_cast_buff = NULL, *rhs_cast_buff = NULL;
- xlat_escape_t escape = NULL;
+ xlat_escape_t escape = NULL;
/*
* Cast operand to correct type.
*/
#define CAST(_s) \
do {\
- if ((cast_type != PW_TYPE_INVALID) && (_s ## _type != PW_TYPE_INVALID) && (cast_type != _s ## _type)) {\
+ if ((cast_type != PW_TYPE_INVALID) && _s && (_s ->type != PW_TYPE_INVALID) && (cast_type != _s->type)) {\
EVAL_DEBUG("CASTING " #_s " FROM %s TO %s",\
- fr_int2str(dict_attr_types, _s ## _type, "<INVALID>"),\
+ fr_int2str(dict_attr_types, _s->type, "<INVALID>"),\
fr_int2str(dict_attr_types, cast_type, "<INVALID>"));\
- if (value_box_cast(request, &_s ## _cast, cast_type, cast, _s ## _type, _s ## _enumv, _s) < 0) {\
+ if (value_box_cast(request, &_s ## _cast, cast_type, cast, _s) < 0) {\
REDEBUG("Failed casting " #_s " operand: %s", fr_strerror());\
rcode = -1;\
goto finish;\
}\
if (cast && cast->flags.is_pointer) _s ## _cast_buff = _s ## _cast.datum.ptr;\
- _s ## _type = cast_type;\
_s = &_s ## _cast;\
}\
} while (0)
#define CHECK_INT_CAST(_l, _r) \
do {\
if ((cast_type == PW_TYPE_INVALID) &&\
- _l && (_l ## _type == PW_TYPE_STRING) &&\
- _r && (_r ## _type == PW_TYPE_STRING) &&\
+ _l && (_l->type == PW_TYPE_STRING) &&\
+ _r && (_r->type == PW_TYPE_STRING) &&\
all_digits(lhs->datum.strvalue) && all_digits(rhs->datum.strvalue)) {\
cast_type = PW_TYPE_INTEGER64;\
EVAL_DEBUG("OPERANDS ARE NUMBER STRINGS, SETTING CAST TO integer64");\
if (c->pass2_fixup == PASS2_PAIRCOMPARE) {
rad_assert(!c->cast);
rad_assert(map->lhs->type == TMPL_TYPE_ATTR);
-#ifndef NDEBUG
- /* expensive assert */
- rad_assert((map->rhs->type != TMPL_TYPE_ATTR) || !radius_find_compare(map->rhs->tmpl_da));
-#endif
+ rad_assert((map->rhs->type != TMPL_TYPE_ATTR) || !radius_find_compare(map->rhs->tmpl_da)); /* expensive assert */
+
cast = map->lhs->tmpl_da;
- cast_type = cast->type;
EVAL_DEBUG("NORMALISATION TYPE %s (PAIRCMP TYPE)",
fr_int2str(dict_attr_types, cast->type, "<INVALID>"));
for (vp = tmpl_cursor_init(&rcode, &cursor, request, map->rhs);
vp;
vp = tmpl_cursor_next(&cursor, map->rhs)) {
- rhs_type = vp->da->type;
- rhs_enumv = vp->da;
rhs = &vp->data;
CHECK_INT_CAST(lhs, rhs);
CAST(lhs);
CAST(rhs);
- rcode = cond_cmp_values(request, c, lhs_type, lhs, rhs_type, rhs);
+ rcode = cond_cmp_values(request, c, lhs, rhs);
if (rcode != 0) break;
TALLOC_FREE(rhs_cast_buff);
break;
case TMPL_TYPE_DATA:
- rhs_type = map->rhs->tmpl_value_box_type;
- rhs = &map->rhs->tmpl_value_box_datum;
+ rhs = &map->rhs->tmpl_value_box;
CHECK_INT_CAST(lhs, rhs);
CAST(lhs);
CAST(rhs);
- rcode = cond_cmp_values(request, c, lhs_type, lhs, rhs_type, rhs);
+ rcode = cond_cmp_values(request, c, lhs, rhs);
break;
/*
data.datum.strvalue = map->rhs->name;
data.length = map->rhs->len;
}
+ data.type = PW_TYPE_STRING;
+
rad_assert(data.datum.strvalue);
- rhs_type = PW_TYPE_STRING;
rhs = &data;
CHECK_INT_CAST(lhs, rhs);
CAST(lhs);
CAST(rhs);
- rcode = cond_cmp_values(request, c, lhs_type, lhs, rhs_type, rhs);
+ rcode = cond_cmp_values(request, c, lhs, rhs);
if (map->rhs->type != TMPL_TYPE_UNPARSED) talloc_free(data.datum.ptr);
break;
*/
case TMPL_TYPE_REGEX_STRUCT:
CAST(lhs);
- rcode = cond_cmp_values(request, c, lhs_type, lhs, PW_TYPE_INVALID, NULL);
+ rcode = cond_cmp_values(request, c, lhs, NULL);
break;
/*
* Unsupported types (should have been parse errors)
#ifndef NDEBUG
rad_assert(radius_find_compare(map->lhs->tmpl_da)); /* expensive assert */
#endif
- rcode = cond_normalise_and_cmp(request, c, PW_TYPE_INVALID, NULL, NULL);
+ rcode = cond_normalise_and_cmp(request, c, NULL);
break;
}
for (vp = tmpl_cursor_init(&rcode, &cursor, request, map->lhs);
* if we get at least one set of operands that
* evaluates to true.
*/
- rcode = cond_normalise_and_cmp(request, c, vp->da->type, vp->da, &vp->data);
+ rcode = cond_normalise_and_cmp(request, c, &vp->data);
if (rcode != 0) break;
}
}
break;
case TMPL_TYPE_DATA:
- rcode = cond_normalise_and_cmp(request, c,
- map->lhs->tmpl_value_box_type, NULL, &map->lhs->tmpl_value_box_datum);
+ rcode = cond_normalise_and_cmp(request, c, &map->lhs->tmpl_value_box);
break;
case TMPL_TYPE_UNPARSED:
data.length = map->lhs->len;
}
rad_assert(data.datum.strvalue);
+ data.type = PW_TYPE_STRING;
- rcode = cond_normalise_and_cmp(request, c, PW_TYPE_STRING, NULL, &data);
+ rcode = cond_normalise_and_cmp(request, c, &data);
if (p) talloc_free(p);
}
break;
p += len;
}
- len = tmpl_snprint(p, end - p, c->data.vpt, NULL);
+ len = tmpl_snprint(p, end - p, c->data.vpt);
RETURN_IF_TRUNCATED(p, len, end - p);
break;
/*
* Get the name.
- */
+ */
ptr = buffer;
getword(&ptr, entry, sizeof(entry), false);
entry_lineno = lineno;
vp = fr_pair_cursor_next(&cursor)) {
if (((vp->op == T_OP_REG_EQ) ||
(vp->op == T_OP_REG_NE)) &&
- (vp->da->type != PW_TYPE_STRING)) {
+ (vp->vp_type != PW_TYPE_STRING)) {
pairlist_free(&pl);
talloc_free(check_tmp);
ERROR("%s[%d]: Cannot use regular expressions for non-string attributes in entry %s",
map->rhs->tmpl_value_box_type = da->type;
map->rhs->tmpl_value_box_length = vp->vp_length;
if (vp->da->flags.is_pointer) {
- if (vp->da->type == PW_TYPE_STRING) {
- map->rhs->tmpl_value_box_datum.datum.ptr = talloc_bstrndup(map->rhs, vp->vp_ptr, vp->vp_length);
+ if (vp->vp_type == PW_TYPE_STRING) {
+ map->rhs->tmpl_value_box_datum.ptr = talloc_bstrndup(map->rhs, vp->vp_ptr, vp->vp_length);
map->rhs->quote = T_SINGLE_QUOTED_STRING;
} else {
- map->rhs->tmpl_value_box_datum.datum.ptr = talloc_memdup(map->rhs, vp->vp_ptr, vp->vp_length);
+ map->rhs->tmpl_value_box_datum.ptr = talloc_memdup(map->rhs, vp->vp_ptr, vp->vp_length);
map->rhs->quote = T_BARE_WORD;
}
} else {
- value_box_copy(map->rhs, &map->rhs->tmpl_value_box_datum, vp->da->type, &vp->data);
+ value_box_copy(map->rhs, &map->rhs->tmpl_value_box, &vp->data);
map->rhs->quote = T_BARE_WORD;
}
map->rhs->name = fr_pair_value_asprint(map->rhs, vp, fr_token_quote[map->rhs->quote]);
new = fr_pair_afrom_da(ctx, map->lhs->tmpl_da);
if (!new) return -1;
- if (value_box_cast(new, &new->data, new->da->type, new->da,
- vp->da->type, vp->da, &vp->data) < 0) {
+ if (value_box_cast(new, &new->data,
+ map->lhs->tmpl_da->type, map->lhs->tmpl_da, &vp->data) < 0) {
REDEBUG("Attribute conversion failed: %s", fr_strerror());
fr_pair_list_free(&found);
fr_pair_list_free(&new);
vp = fr_pair_cursor_remove(&from);
talloc_free(vp);
- if (new->da->type == PW_TYPE_STRING) {
- rad_assert(new->vp_strvalue != NULL);
- }
+ if (new->vp_type == PW_TYPE_STRING) rad_assert(new->vp_strvalue != NULL);
new->op = map->op;
new->tag = map->lhs->tmpl_tag;
if (!new) return -1;
if (map->lhs->tmpl_da->type == map->rhs->tmpl_value_box_type) {
- if (value_box_copy(new, &new->data, new->da->type, &map->rhs->tmpl_value_box_datum) < 0) {
+ if (value_box_copy(new, &new->data, &map->rhs->tmpl_value_box) < 0) {
rcode = -1;
goto error;
}
} else {
- if (value_box_cast(new, &new->data, new->da->type, new->da, map->rhs->tmpl_value_box_type,
- NULL, &map->rhs->tmpl_value_box_datum) < 0) {
+ if (value_box_cast(new, &new->data, new->vp_type, new->da,
+ &map->rhs->tmpl_value_box) < 0) {
REDEBUG("Implicit cast failed: %s", fr_strerror());
rcode = -1;
goto error;
if (cmp > 0) break;
else if (cmp < 0) continue;
- cmp = (value_box_cmp_op(map->op, a->da->type, &a->data, b->da->type, &b->data) == 0);
+ cmp = (value_box_cmp_op(map->op, &a->data, &b->data) == 0);
if (cmp != 0) {
a = fr_pair_cursor_remove(&dst_list);
talloc_free(a);
if (!vp->da->parent->flags.is_root) continue;
if (vp->da->vendor != 0) continue;
if (vp->da->flags.has_tag) continue;
- if (vp->da->type != PW_TYPE_STRING) continue;
+ if (vp->vp_type != PW_TYPE_STRING) continue;
if (!context->username && (vp->da->attr == PW_USER_NAME)) {
context->username = vp;
size_t map_snprint(char *out, size_t outlen, vp_map_t const *map)
{
size_t len;
- fr_dict_attr_t const *da = NULL;
char *p = out;
char *end = out + outlen;
VERIFY_MAP(map);
- if (map->lhs->type == TMPL_TYPE_ATTR) da = map->lhs->tmpl_da;
-
- len = tmpl_snprint(out, (end - p) - 1, map->lhs, da); /* -1 for proceeding ' ' */
+ len = tmpl_snprint(out, (end - p) - 1, map->lhs); /* -1 for proceeding ' ' */
RETURN_IF_TRUNCATED(p, len, (end - p) - 1);
*(p++) = ' ';
(map->lhs->tmpl_da->type == PW_TYPE_STRING) &&
(map->rhs->type == TMPL_TYPE_UNPARSED)) {
*(p++) = '\'';
- len = tmpl_snprint(p, (end - p) - 1, map->rhs, da); /* -1 for proceeding '\'' */
+ len = tmpl_snprint(p, (end - p) - 1, map->rhs); /* -1 for proceeding '\'' */
RETURN_IF_TRUNCATED(p, len, (end - p) - 1);
*(p++) = '\'';
} else {
- len = tmpl_snprint(p, end - p, map->rhs, da);
+ len = tmpl_snprint(p, end - p, map->rhs);
RETURN_IF_TRUNCATED(p, len, (end - p) - 1);
}
vp_tmpl_t vpt;
char const *quote;
- quote = (vp->da->type == PW_TYPE_STRING) ? "\"" : "";
+ quote = (vp->vp_type == PW_TYPE_STRING) ? "\"" : "";
/*
* Fudge a temporary tmpl that describes the attribute we're copying
* the quoting based on the data type.
*/
value = fr_pair_value_asprint(request, vp, quote[0]);
- tmpl_snprint(buffer, sizeof(buffer), &vpt, vp->da);
+ tmpl_snprint(buffer, sizeof(buffer), &vpt);
rhs = talloc_typed_asprintf(request, "%s -> %s%s%s", buffer, quote, value, quote);
}
break;
{
char const *quote;
- quote = (vp->da->type == PW_TYPE_STRING) ? "\"" : "";
+ quote = (vp->vp_type == PW_TYPE_STRING) ? "\"" : "";
/*
* Not appropriate to use map->rhs->quote here, as that's the quoting
* the quoting based on the data type.
*/
value = fr_pair_value_asprint(request, vp, quote[0]);
- tmpl_snprint(buffer, sizeof(buffer), map->rhs, vp->da);
+ tmpl_snprint(buffer, sizeof(buffer), map->rhs);
rhs = talloc_typed_asprintf(request, "%s -> %s%s%s", buffer, quote, value, quote);
}
break;
switch (map->lhs->type) {
case TMPL_TYPE_ATTR:
case TMPL_TYPE_LIST:
- tmpl_snprint(buffer, sizeof(buffer), map->lhs, NULL);
+ tmpl_snprint(buffer, sizeof(buffer), map->lhs);
RDEBUG("%s %s %s", buffer, fr_int2str(fr_tokens_table, vp ? vp->op : map->op, "<INVALID>"), rhs);
break;
char *expr = NULL, *value = NULL;
char const *expr_p, *value_p;
- if (check->da->type == PW_TYPE_STRING) {
+ if (check->vp_type == PW_TYPE_STRING) {
expr_p = check->vp_strvalue;
} else {
expr_p = expr = fr_pair_value_asprint(check, check, '\0');
}
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
value_p = vp->vp_strvalue;
} else {
value_p = value = fr_pair_value_asprint(vp, vp, '\0');
* a string
*
*/
- if (vp->da->type != check->da->type) return -1;
+ if (vp->vp_type != check->vp_type) return -1;
/*
* Tagged attributes are equal if and only if both the
/*
* Not a regular expression, compare the types.
*/
- switch (check->da->type) {
+ switch (check->vp_type) {
#ifdef WITH_ASCEND_BINARY
/*
* Ascend binary attributes can be treated
{
size_t i;
- if (!vp || (vp->da->type != PW_TYPE_OCTETS)) return true;
+ if (!vp || (vp->vp_type != PW_TYPE_OCTETS)) return true;
/*
* If it's 17 octets, it *might* be already encoded.
talloc_free(q);
vp->vp_octets = talloc_steal(vp, p);
+ vp->data.type = PW_TYPE_OCTETS;
vp->type = VT_DATA;
VERIFY_VP(vp);
slen = dict_print_attr_oid(p, end - p, parent, vp->da->parent);
if (slen < 0) return -1;
- if (vp->da->type != PW_TYPE_INTEGER) {
+ if (vp->vp_type != PW_TYPE_INTEGER) {
fr_strerror_printf("Index attribute \"%s\" is not of type \"integer\"", vp->da->name);
return -1;
}
io_vector[3].iov_base = newline;
io_vector[3].iov_len = 1;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
memcpy(&io_vector[4].iov_base, &vp->vp_strvalue, sizeof(io_vector[4].iov_base));
io_vector[4].iov_len = vp->vp_length;
* because we always need return integer values not
* value aliases.
*/
- len = value_box_snprint(value_buff, sizeof(value_buff), vp->da->type, NULL, &vp->data, '\0');
+ len = value_box_snprint(value_buff, sizeof(value_buff), &vp->data, '\0');
if (is_truncated(len, sizeof(value_buff))) {
fr_strerror_printf("Insufficient fixed value buffer");
return -1;
if (!request->proxy->packet) {
VALUE_PAIR *vp;
+ char buff[11]; /* 4294967295 + \0 */
MEM(request->proxy->packet = fr_radius_alloc(request->proxy, true));
* doesn't need it.
*/
vp = radius_pair_create(request->proxy->packet, &request->proxy->packet->vps, PW_PROXY_STATE, 0);
- fr_pair_value_snprintf(vp, "%u", request->packet->id);
+ snprintf(buff, sizeof(buff), "%u", request->packet->id);
+ fr_pair_value_memcpy(vp, (uint8_t *)buff, strlen(buff));
/*
* If there is no PW_CHAP_CHALLENGE attribute but
if (map_p->get(request->reply, &data, map_p, snmp_ctx) < 0) goto error;
vp = fr_pair_afrom_da(request->reply, map_p->da);
- value_box_steal(vp, &vp->data, vp->da->type, &data);
+ value_box_steal(vp, &vp->data, &data);
fr_pair_cursor_append(out, vp);
vp = fr_pair_afrom_da(request->reply, fr_snmp_type);
* Clear out any junk values
*/
if (da->type == PW_TYPE_TLV) {
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
case PW_TYPE_STRING:
talloc_free(vp->data.datum.ptr);
* When retrieving client by number, also
* echo back it's IP address.
*/
- if ((vp->da->type == PW_TYPE_INTEGER) &&
+ if ((vp->vp_type == PW_TYPE_INTEGER) &&
(client->ipaddr.af == AF_INET)) {
vp = radius_pair_create(request->reply,
&request->reply->vps,
* @param[in,out] ctx to allocate #vp_tmpl_t in.
* @param[out] out Where to write pointer to new #vp_tmpl_t.
* @param[in] data to convert.
- * @param[in] type of data.
- * @param[in] enumv Used to convert integers to string types for printing. May be NULL.
* @param[in] steal If true, any buffers are moved to the new ctx instead of being duplicated.
* @return
* - 0 on success.
* - -1 on failure.
*/
-int tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, value_box_t *data,
- PW_TYPE type, fr_dict_attr_t const *enumv, bool steal)
+int tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, value_box_t *data, bool steal)
{
char const *name;
vp_tmpl_t *vpt;
vpt = talloc(ctx, vp_tmpl_t);
- name = value_box_asprint(vpt, type, enumv, data, '\0');
+ name = value_box_asprint(vpt, data, '\0');
tmpl_init(vpt, TMPL_TYPE_DATA, name, talloc_array_length(name),
- (type == PW_TYPE_STRING) ? T_DOUBLE_QUOTED_STRING : T_BARE_WORD);
+ (data->type == PW_TYPE_STRING) ? T_DOUBLE_QUOTED_STRING : T_BARE_WORD);
if (steal) {
- if (value_box_steal(vpt, &vpt->tmpl_value_box_datum, type, data) < 0) {
+ if (value_box_steal(vpt, &vpt->tmpl_value_box, data) < 0) {
talloc_free(vpt);
return -1;
}
- vpt->tmpl_value_box_type = type;
} else {
- if (value_box_copy(vpt, &vpt->tmpl_value_box_datum, type, data) < 0) {
+ if (value_box_copy(vpt, &vpt->tmpl_value_box, data) < 0) {
talloc_free(vpt);
return -1;
}
- vpt->tmpl_value_box_type = type;
}
*out = vpt;
binlen = (inlen - 2) / 2;
vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, in, inlen, type);
- vpt->tmpl_value_box_datum.datum.ptr = talloc_array(vpt, uint8_t, binlen);
+ vpt->tmpl_value_box_datum.ptr = talloc_array(vpt, uint8_t, binlen);
vpt->tmpl_value_box_length = binlen;
vpt->tmpl_value_box_type = PW_TYPE_OCTETS;
- len = fr_hex2bin(vpt->tmpl_value_box_datum.datum.ptr, binlen, in + 2, inlen - 2);
+ len = fr_hex2bin(vpt->tmpl_value_box_datum.ptr, binlen, in + 2, inlen - 2);
if (len != binlen) {
fr_strerror_printf("Hex string contains none hex char");
talloc_free(vpt);
/*
* Why do we pass a pointer to the tmpl type? Goddamn WiMAX.
*/
- if (value_box_from_str(vpt, &vpt->tmpl_value_box_datum, &vpt->tmpl_value_box_type,
- enumv, vpt->name, vpt->len, '\0') < 0) return -1;
+ if (value_box_from_str(vpt, &vpt->tmpl_value_box, &vpt->tmpl_value_box_type,
+ enumv, vpt->name, vpt->len, '\0') < 0) return -1;
vpt->type = TMPL_TYPE_DATA;
break;
if (type == vpt->tmpl_value_box_type) return 0; /* noop */
- if (value_box_cast(vpt, &new, type, enumv, vpt->tmpl_value_box_type,
- NULL, &vpt->tmpl_value_box_datum) < 0) return -1;
+ if (value_box_cast(vpt, &new, type, enumv, &vpt->tmpl_value_box) < 0) return -1;
/*
* Free old value buffers
switch (vpt->tmpl_value_box_type) {
case PW_TYPE_STRING:
case PW_TYPE_OCTETS:
- talloc_free(vpt->tmpl_value_box_datum.datum.ptr);
+ talloc_free(vpt->tmpl_value_box_datum.ptr);
break;
default:
break;
}
- value_box_copy(vpt, &vpt->tmpl_value_box_datum, type, &new);
- vpt->tmpl_value_box_type = type;
+ value_box_copy(vpt, &vpt->tmpl_value_box, &new);
}
break;
rad_assert(vpt != NULL);
rad_assert(vpt->type == TMPL_TYPE_UNPARSED);
- vpt->tmpl_value_box.vp_strvalue = talloc_typed_strdup(vpt, vpt->name);
- rad_assert(vpt->tmpl_value_box.vp_strvalue != NULL);
+ vpt->tmpl_value_box_datum.strvalue = talloc_typed_strdup(vpt, vpt->name);
+ rad_assert(vpt->tmpl_value_box_datum.strvalue != NULL);
vpt->type = TMPL_TYPE_DATA;
vpt->tmpl_value_box_type = PW_TYPE_STRING;
- vpt->tmpl_value_box_length = talloc_array_length(vpt->tmpl_value_box.vp_strvalue) - 1;
+ vpt->tmpl_value_box_length = talloc_array_length(vpt->tmpl_value_box_datum.strvalue) - 1;
}
/** Expand a #vp_tmpl_t to a string, parse it as an attribute of type cast, create a #VALUE_PAIR from the result
int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
vp_tmpl_t const *vpt, fr_dict_attr_t const *cast)
{
- int rcode;
- VALUE_PAIR *vp;
- value_box_t data;
- char *p;
+ int rcode;
+ VALUE_PAIR *vp;
+ value_box_t data;
+ char *p;
VERIFY_TMPL(vpt);
if (vpt->type == TMPL_TYPE_DATA) {
VERIFY_VP(vp);
- rad_assert(vp->da->type == vpt->tmpl_value_box_type);
+ rad_assert(vp->vp_type == vpt->tmpl_value_box_type);
- value_box_copy(vp, &vp->data, vpt->tmpl_value_box_type, &vpt->tmpl_value_box_datum);
+ value_box_copy(vp, &vp->data, &vpt->tmpl_value_box);
*out = vp;
return 0;
}
/*
* New escapes: strings are in binary form.
*/
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
vp->data.datum.ptr = talloc_steal(vp, data.datum.ptr);
vp->vp_length = rcode;
} else if (fr_pair_value_from_str(vp, data.datum.strvalue, rcode) < 0) {
ret = tmpl_find_vp(&vp, request, vpt);
if (ret < 0) return -2;
- to_cast = &vpt->tmpl_value_box_datum;
+ to_cast = &vpt->tmpl_value_box;
src_type = vpt->tmpl_value_box_type;
}
break;
/*
* Data type conversion...
*/
- ret = value_box_cast(ctx, &vd_from_cast, dst_type, NULL, src_type, vp ? vp->da : NULL, to_cast);
+ ret = value_box_cast(ctx, &vd_from_cast, dst_type, NULL, to_cast);
if (ret < 0) return -1;
VALUE_PAIR *vp = NULL;
value_box_t vd;
- PW_TYPE src_type = PW_TYPE_STRING;
bool needs_dup = false;
ssize_t slen = -1;
vd.length = vpt->len;
vd.datum.strvalue = vpt->name;
+ vd.type = PW_TYPE_STRING;
to_cast = &vd;
needs_dup = true;
break;
return slen;
}
vd.length = strlen(vd.datum.strvalue);
+ vd.type = PW_TYPE_STRING;
MEM(vd.datum.strvalue = talloc_realloc(tmp_ctx, vd.datum.ptr, char, vd.length + 1)); /* Trim */
rad_assert(vd.datum.strvalue[vd.length] == '\0');
to_cast = &vd;
case TMPL_TYPE_XLAT:
{
value_box_t tmp;
+ PW_TYPE src_type = PW_TYPE_STRING;
RDEBUG4("EXPAND TMPL XLAT");
vd.datum.strvalue = tmp.datum.strvalue;
vd.length = tmp.length;
+ vd.type = PW_TYPE_STRING;
to_cast = &vd;
}
break;
case TMPL_TYPE_XLAT_STRUCT:
{
value_box_t tmp;
+ PW_TYPE src_type = PW_TYPE_STRING;
RDEBUG4("EXPAND TMPL XLAT STRUCT");
RDEBUG2("EXPAND %s", vpt->name); /* xlat_struct doesn't do this */
vd.datum.strvalue = tmp.datum.strvalue;
vd.length = tmp.length;
+ vd.type = PW_TYPE_STRING;
to_cast = &vd;
RDEBUG2(" --> %s", vd.datum.strvalue); /* Print post-unescaping */
rad_assert(vp);
to_cast = &vp->data;
- src_type = vp->da->type;
-
- switch (src_type) {
+ switch (to_cast->type) {
case PW_TYPE_STRING:
case PW_TYPE_OCTETS:
rad_assert(to_cast->datum.ptr);
{
RDEBUG4("EXPAND TMPL DATA");
- to_cast = &vpt->tmpl_value_box_datum;
- src_type = vpt->tmpl_value_box_type;
-
- switch (src_type) {
+ to_cast = &vpt->tmpl_value_box;
+ switch (to_cast->type) {
case PW_TYPE_STRING:
case PW_TYPE_OCTETS:
rad_assert(to_cast->datum.ptr);
/*
* Don't dup the buffers unless we need to.
*/
- if ((src_type != dst_type) || needs_dup) {
- ret = value_box_cast(ctx, &from_cast, dst_type, NULL, src_type, vp ? vp->da : NULL, to_cast);
+ if ((to_cast->type != dst_type) || needs_dup) {
+ ret = value_box_cast(ctx, &from_cast, dst_type, NULL, to_cast);
if (ret < 0) goto error;
} else {
- switch (src_type) {
+ switch (to_cast->type) {
case PW_TYPE_OCTETS:
case PW_TYPE_STRING:
/*
* @param[out] out Where to write the presentation format #vp_tmpl_t string.
* @param[in] outlen Size of output buffer.
* @param[in] vpt to print.
- * @param[in] values Used for #TMPL_TYPE_DATA only. #fr_dict_attr_t to use when mapping integer
- * values to strings.
* @return
* - The number of bytes written to the out buffer.
* - A number >= outlen if truncation has occurred.
*/
-size_t tmpl_snprint(char *out, size_t outlen, vp_tmpl_t const *vpt, fr_dict_attr_t const *values)
+size_t tmpl_snprint(char *out, size_t outlen, vp_tmpl_t const *vpt)
{
size_t len;
char const *p;
break;
case TMPL_TYPE_DATA:
- return value_box_snprint(out, outlen, vpt->tmpl_value_box_type, values, &vpt->tmpl_value_box_datum,
- fr_token_quote[vpt->quote]);
+ return value_box_snprint(out, outlen, &vpt->tmpl_value_box, fr_token_quote[vpt->quote]);
default:
goto empty;
*/
switch (vpt->tmpl_value_box_type) {
case PW_TYPE_STRING:
- if (vpt->tmpl_value_box.vp_strvalue[vpt->tmpl_value_box_length] != '\0') {
+ if (vpt->tmpl_value_box_datum.strvalue[vpt->tmpl_value_box_length] != '\0') {
FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_DATA char buffer not \\0 "
"terminated", file, line);
if (!fr_cond_assert(0)) fr_exit_now(1);
talloc_free(q);
vp->vp_octets = talloc_steal(vp, p);
+ vp->data.type = PW_TYPE_OCTETS;
vp->type = VT_DATA;
VERIFY_VP(vp);
case UNLANG_TYPE_SWITCH:
case UNLANG_TYPE_CASE:
g = unlang_group_to_module_call(this);
- tmpl_snprint(buffer, sizeof(buffer), g->vpt, NULL);
+ tmpl_snprint(buffer, sizeof(buffer), g->vpt);
DEBUG("%.*s%s %s {", depth, modcall_spaces,
unlang_ops[this->type].name, buffer);
unlang_dump(g->children, depth + 1);
if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
case PW_TYPE_STRING:
if (vp->vp_length > 8) {
}
REDEBUG("Type '%s' of length %zu cannot be converted to integer",
- fr_int2str(dict_attr_types, vp->da->type, "???"), vp->vp_length);
+ fr_int2str(dict_attr_types, vp->vp_type, "???"), vp->vp_length);
return -1;
}
/*
* The easy case.
*/
- if (vp->da->type == PW_TYPE_OCTETS) {
+ if (vp->vp_type == PW_TYPE_OCTETS) {
p = vp->vp_octets;
len = vp->vp_length;
/*
* print that as hex.
*/
} else {
- if (value_box_cast(request, &dst, PW_TYPE_OCTETS, NULL, vp->da->type, NULL, &vp->data) < 0) {
+ if (value_box_cast(request, &dst, PW_TYPE_OCTETS, NULL, &vp->data) < 0) {
REDEBUG("%s", fr_strerror());
goto error;
}
dv = fr_dict_vendor_by_num(NULL, vp->da->vendor);
RIDEBUG2("Vendor : %i (%s)", vp->da->vendor, dv ? dv->name : "unknown");
}
- RIDEBUG2("Type : %s", fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
+ RIDEBUG2("Type : %s", fr_int2str(dict_attr_types, vp->vp_type, "<INVALID>"));
RIDEBUG2("Length : %zu", vp->vp_length);
if (!RDEBUG_ENABLED4) continue;
value_box_t *dst = NULL;
- if ((PW_TYPE) type->number == vp->da->type) {
- goto next_type;
- }
+ if ((PW_TYPE) type->number == vp->vp_type) goto next_type;
switch (type->number) {
case PW_TYPE_INVALID: /* Not real type */
dst = talloc_zero(vp, value_box_t);
/* We expect some to fail */
- if (value_box_cast(dst, dst, type->number, NULL, vp->da->type, vp->da, &vp->data) < 0) {
+ if (value_box_cast(dst, dst, type->number, NULL, &vp->data) < 0) {
goto next_type;
}
- value = value_box_asprint(dst, type->number, NULL, dst, '\'');
+ value = value_box_asprint(dst, dst, '\'');
if (!value) goto next_type;
if ((pad = (11 - strlen(type->name))) < 0) {
/*
* These are printed specially.
*/
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
return fr_snprint(*out, outlen, (char const *) vp->vp_octets, vp->vp_length, '"');
/*
* If it's a string, expand it again
*/
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
slen = xlat_eval(*out, outlen, request, vp->vp_strvalue, NULL, NULL);
if (slen <= 0) return slen;
/*
break;
default:
- fr_strerror_printf("Internal sanity check %d %d", vp->da->type, __LINE__);
+ fr_strerror_printf("Internal sanity check %d %d", vp->vp_type, __LINE__);
talloc_free(vp);
return -1;
} /* switch over type */
}
}
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_BYTE:
vp->vp_byte = p[0];
vp->vp_length = 1;
break;
default:
- fr_strerror_printf("BAD TYPE %d", vp->da->type);
+ fr_strerror_printf("BAD TYPE %d", vp->vp_type);
fr_pair_list_free(&vp);
break;
}
break;
default:
- fr_strerror_printf("Unsupported option type %d", vp->da->type);
+ fr_strerror_printf("Unsupported option type %d", vp->vp_type);
(void)fr_pair_cursor_next(cursor);
return -2;
}
#endif
if (!fr_cond_assert(macaddr) ||
- !fr_cond_assert((macaddr->da->type == PW_TYPE_ETHERNET) || (macaddr->da->type == PW_TYPE_OCTETS))) {
+ !fr_cond_assert((macaddr->vp_type == PW_TYPE_ETHERNET) || (macaddr->vp_type == PW_TYPE_OCTETS))) {
fr_strerror_printf("Wrong VP type (%s) for chaddr",
- fr_int2str(dict_attr_types, macaddr->da->type, "<invalid>"));
+ fr_int2str(dict_attr_types, macaddr->vp_type, "<invalid>"));
return -1;
}
strlcpy(req.arp_dev, interface, sizeof(req.arp_dev));
- if (macaddr->da->type == PW_TYPE_ETHERNET) {
+ if (macaddr->vp_type == PW_TYPE_ETHERNET) {
memcpy(&req.arp_ha.sa_data, macaddr->vp_ether, sizeof(macaddr->vp_ether));
} else {
memcpy(&req.arp_ha.sa_data, macaddr->vp_octets, macaddr->vp_length);
return -1;
}
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_ETHERNET:
if (attr_len != 6) goto unknown;
out += 6;
/* Data */
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_IPV4_ADDR:
memcpy(out, &vp->vp_ipaddr, 4);
break;
if ((head->lhs->tmpl_da->vendor == 0) && (head->lhs->tmpl_da->attr == PW_CACHE_CREATED)) {
vp_map_t *map;
- c->created = head->rhs->tmpl_value_box_datum.datum.date;
+ c->created = head->rhs->tmpl_value_box_datum.date;
map = head;
head = head->next;
if ((head->lhs->tmpl_da->vendor == 0) && (head->lhs->tmpl_da->attr == PW_CACHE_EXPIRES)) {
vp_map_t *map;
- c->expires = head->rhs->tmpl_value_box_datum.datum.date;
+ c->expires = head->rhs->tmpl_value_box_datum.date;
map = head;
head = head->next;
*/
tmpl_init(&created_value, TMPL_TYPE_DATA, "<TEMP>", 6, T_BARE_WORD);
created_value.tmpl_value_box_type = PW_TYPE_DATE;
- created_value.tmpl_value_box_length = sizeof(created_value.tmpl_value_box_datum.datum.date);
- created_value.tmpl_value_box_datum.datum.date = c->created;
+ created_value.tmpl_value_box_length = sizeof(created_value.tmpl_value_box_datum.date);
+ created_value.tmpl_value_box_datum.date = c->created;
/*
* Encode the entry expiry time
*/
tmpl_init(&expires_value, TMPL_TYPE_DATA, "<TEMP>", 6, T_BARE_WORD);
expires_value.tmpl_value_box_type = PW_TYPE_DATE;
- expires_value.tmpl_value_box_length = sizeof(expires_value.tmpl_value_box_datum.datum.date);
- expires_value.tmpl_value_box_datum.datum.date = c->expires;
+ expires_value.tmpl_value_box_length = sizeof(expires_value.tmpl_value_box_datum.date);
+ expires_value.tmpl_value_box_datum.date = c->expires;
expires.next = c->maps; /* Head of the list */
for (cnt = 0, map = &created; map; cnt++, map = map->next);
do_rhs:
MEM(c_map->rhs = tmpl_init(talloc(c_map, vp_tmpl_t),
TMPL_TYPE_DATA, map->rhs->name, map->rhs->len, T_BARE_WORD));
- if (value_box_copy(c_map->rhs, &c_map->rhs->tmpl_value_box_datum,
- vp->da->type, &vp->data) < 0) {
+ if (value_box_copy(c_map->rhs, &c_map->rhs->tmpl_value_box, &vp->data) < 0) {
REDEBUG("Failed copying attribute value");
error:
talloc_free(pool);
talloc_free(c);
return RLM_MODULE_FAIL;
}
- c_map->rhs->tmpl_value_box_type = vp->da->type;
- if (vp->da->type == PW_TYPE_STRING) {
+ c_map->rhs->tmpl_value_box_type = vp->vp_type;
+ if (vp->vp_type == PW_TYPE_STRING) {
c_map->rhs->quote = is_printable(vp->vp_strvalue, vp->vp_length) ?
T_SINGLE_QUOTED_STRING : T_DOUBLE_QUOTED_STRING;
}
* We need to rebuild the attribute name, to be the
* one we copied from the source list.
*/
- len = tmpl_snprint(attr, sizeof(attr), c_map->lhs, NULL);
+ len = tmpl_snprint(attr, sizeof(attr), c_map->lhs);
if (is_truncated(len, sizeof(attr))) {
REDEBUG("Serialized attribute too long. Must be < "
STRINGIFY(sizeof(attr)) " bytes, got %zu bytes", len);
(map->lhs->tmpl_tag != target.tmpl_tag) ||
(map->lhs->tmpl_list != target.tmpl_list)) continue;
- *out = value_box_asprint(request, map->rhs->tmpl_value_box_type, map->lhs->tmpl_da,
- &map->rhs->tmpl_value_box_datum, '\0');
+ *out = value_box_asprint(request, &map->rhs->tmpl_value_box, '\0');
ret = talloc_array_length(*out) - 1;
break;
}
char *value;
size_t len;
- len = tmpl_snprint(attr, sizeof(attr), map->lhs, map->lhs->tmpl_da);
+ len = tmpl_snprint(attr, sizeof(attr), map->lhs);
if (is_truncated(len, sizeof(attr))) {
fr_strerror_printf("Serialized attribute too long. Must be < " STRINGIFY(sizeof(attr)) " "
"bytes, got %zu bytes", len);
}
value = value_box_asprint(value_pool, map->rhs->tmpl_value_box_type,
- map->lhs->tmpl_da, &map->rhs->tmpl_value_box_datum, '\'');
+ map->lhs->tmpl_da, &map->rhs->tmpl_value_box, '\'');
if (!value) goto error;
to_store = talloc_asprintf_append_buffer(to_store, "%s %s %s\n", attr,
*/
if (map->lhs->tmpl_da->vendor == 0) switch (map->lhs->tmpl_da->attr) {
case PW_CACHE_CREATED:
- c->created = map->rhs->tmpl_value_box_datum.datum.date;
+ c->created = map->rhs->tmpl_value_box_datum.date;
talloc_free(map);
goto next;
case PW_CACHE_EXPIRES:
- c->expires = map->rhs->tmpl_value_box_datum.datum.date;
+ c->expires = map->rhs->tmpl_value_box_datum.date;
talloc_free(map);
goto next;
if (!vp->da->flags.has_tag) {
unsigned int i;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_INTEGER:
i = vp->vp_integer;
goto print_int;
}
/* keep going if not set above */
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_STRING:
/* debug */
RDEBUG3("assigning string '%s' as string", vp->da->name);
if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
/*
* These are 'to' types, i.e. we'll convert the integers
* to a time structure, and then output it in the specified
/*
* String attributes have a 16bit "Actual Length" field at the start.
*/
- } else if (vp->da->type == PW_TYPE_STRING) {
+ } else if (vp->vp_type == PW_TYPE_STRING) {
vp_len = vp->vp_length + 2;
/*
* All other attributes we trust the length.
/*
* For strings we have an 'actual' value field.
*/
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
vp_len = vp->vp_length + 2;
/*
* All other attributes we trust the length.
p[0] = vp->da->attr;
p[1] = rounded_len >> 2;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
memcpy(&p[2], vp->vp_octets, vp->vp_length);
break;
{
value_box_t data;
- value_box_hton(&data, vp->da->type, &vp->data);
+ value_box_hton(&data, &vp->data);
memcpy(&p[2], &data, vp->vp_length);
}
/*
* Diameter pads strings (i.e. User-Password) with trailing zeros.
*/
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
fr_pair_value_strcpy(vp, vp->vp_strvalue);
}
total += 4;
}
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_INTEGER:
case PW_TYPE_DATE:
attr = htonl(vp->vp_integer); /* stored in host order */
static int rlm_example_cmp(UNUSED void *instance, REQUEST *request, UNUSED VALUE_PAIR *thing, VALUE_PAIR *check,
UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
{
- rad_assert(check->da->type == PW_TYPE_STRING);
+ rad_assert(check->vp_type == PW_TYPE_STRING);
RINFO("Example-Paircmp called with \"%s\"", check->vp_strvalue);
VERIFY_VP(req);
VERIFY_VP(check);
- rad_assert(req->da->type == PW_TYPE_STRING);
+ rad_assert(req->vp_type == PW_TYPE_STRING);
name = req->vp_strvalue;
i++, vp = tmpl_cursor_next(&cursor, &vpt)) {
int64_t y;
- if (vp->da->type != PW_TYPE_INTEGER64) {
+ if (vp->vp_type != PW_TYPE_INTEGER64) {
value_box_t value;
- if (value_box_cast(vp, &value, PW_TYPE_INTEGER64, NULL, vp->da->type, vp->da, &vp->data) < 0) {
+ if (value_box_cast(vp, &value, PW_TYPE_INTEGER64, NULL, &vp->data) < 0) {
REDEBUG("Failed converting &%.*s to an integer value: %s", (int) vpt.len,
vpt.name, fr_strerror());
return false;
* These are large types. Return pointers to the
* data instead of copying the data.
*/
- if ((vp->da->type == PW_TYPE_STRING) ||
- (vp->da->type == PW_TYPE_OCTETS)) {
+ if ((vp->vp_type == PW_TYPE_STRING) ||
+ (vp->vp_type == PW_TYPE_OCTETS)) {
*out = vp->vp_ptr;
*outlen = vp->vp_length;
return 0;
* This can theoretically operate on lists too
* so we need to check the type of each attribute.
*/
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
case PW_TYPE_STRING:
break;
}
new->tag = vp->tag;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
{
uint8_t *buff;
/** Convert json object to value_box_t
*
- * @param ctx to allocate any value buffers in (should usually be the same as out).
- * @param out Where to write value_box.
- * @param object to convert.
- * @param dst_type FreeRADIUS type to convert to.
- * @param dst_enumv Enumeration values to allow string to integer conversions.
+ * @param[in] ctx to allocate any value buffers in (should usually be the same as out).
+ * @param[in] out Where to write value_box.
+ * @param[in] object to convert.
+ * @param[in] dst_type FreeRADIUS type to convert to.
+ * @param[in] dst_enumv Enumeration values to allow string to integer conversions.
* @return
* - 0 on success.
* - -1 on failure.
*/
int fr_json_object_to_value_box(TALLOC_CTX *ctx, value_box_t *out, json_object *object,
- PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv)
+ PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv)
{
- PW_TYPE src_type = PW_TYPE_INVALID;
value_box_t in;
memset(&in, 0, sizeof(in));
switch (fr_json_object_get_type(object)) {
case json_type_string:
- src_type = PW_TYPE_STRING;
+ in.type = PW_TYPE_STRING;
in.datum.strvalue = json_object_get_string(object);
in.length = json_object_get_string_len(object);
break;
case json_type_double:
- src_type = PW_TYPE_DECIMAL;
+ in.type = PW_TYPE_DECIMAL;
in.datum.decimal = json_object_get_double(object);
in.length = sizeof(in.datum.decimal);
break;
return -1;
}
if (num > UINT32_MAX) { /* 64bit unsigned (supported) */
- src_type = PW_TYPE_INTEGER64;
+ in.type = PW_TYPE_INTEGER64;
in.datum.integer64 = (uint64_t) num;
in.length = sizeof(in.datum.integer64);
} else
#endif
if (num < 0) { /* 32bit signed (supported) */
- src_type = PW_TYPE_SIGNED;
+ in.type = PW_TYPE_SIGNED;
in.datum.sinteger = num;
in.length = sizeof(in.datum.sinteger);
} else if (num > UINT16_MAX) { /* 32bit unsigned (supported) */
- src_type = PW_TYPE_INTEGER;
+ in.type = PW_TYPE_INTEGER;
in.datum.integer = (uint32_t) num;
in.length = sizeof(in.datum.integer);
} else if (num > UINT8_MAX) { /* 16bit unsigned (supported) */
- src_type = PW_TYPE_SHORT;
+ in.type = PW_TYPE_SHORT;
in.datum.ushort = (uint16_t) num;
in.length = sizeof(in.datum.ushort);
} else { /* 8bit unsigned (supported) */
- src_type = PW_TYPE_BYTE;
+ in.type = PW_TYPE_BYTE;
in.datum.byte = (uint8_t) num;
in.length = sizeof(in.datum.byte);
}
break;
case json_type_boolean:
- src_type = PW_TYPE_BOOLEAN;
+ in.type = PW_TYPE_BOOLEAN;
in.datum.boolean = json_object_get_boolean(object);
in.length = sizeof(in.datum.boolean);
break;
case json_type_null:
case json_type_array:
case json_type_object:
- src_type = PW_TYPE_STRING;
+ in.type = PW_TYPE_STRING;
in.datum.strvalue = json_object_to_json_string(object);
in.length = strlen(in.datum.strvalue);
break;
}
- if (src_type == dst_type) {
- if (value_box_copy(ctx, out, src_type, &in) < 0) return -1;
- } else {
- if (value_box_cast(ctx, out, dst_type, dst_enumv, src_type, NULL, &in) < 0) return -1;
- }
+ if (value_box_cast(ctx, out, dst_type, dst_enumv, &in) < 0) return -1;
+
return 0;
}
/** Convert boxed value_box to a JSON object
*
* @param[in] ctx to allocate temporary buffers in
- * @param[in] type of value data.
- * @param[in] enumv of value data.
* @param[in] data to convert.
*/
-json_object *json_object_from_value_box(TALLOC_CTX *ctx,
- PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data)
+json_object *json_object_from_value_box(TALLOC_CTX *ctx, value_box_t const *data)
{
- switch (type) {
+ switch (data->type) {
default:
do_string:
{
char *p;
json_object *obj;
- p = value_box_asprint(ctx, type, enumv, data, '\0');
+ p = value_box_asprint(ctx, data, '\0');
if (!p) return NULL;
obj = json_object_new_string(p);
size_t len, freespace = outlen;
if (!vp->da->flags.has_tag) {
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_INTEGER:
if (vp->da->flags.has_value) break;
}
}
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
char *tmp = fr_json_from_string(NULL, vp->vp_strvalue, true);
/* Indicate truncation */
MEM(vp_object = json_object_new_object());
json_object_object_add(obj, name_with_prefix, vp_object);
- MEM(type_name = json_object_new_string(fr_int2str(dict_attr_types, vp->da->type, "<INVALID>")));
+ MEM(type_name = json_object_new_string(fr_int2str(dict_attr_types, vp->vp_type, "<INVALID>")));
json_object_object_add(vp_object, "type", type_name);
MEM(values = json_object_new_array());
return NULL;
}
- MEM(value = json_object_from_value_box(ctx, vp->da->type, vp->da, &vp->data));
+ MEM(value = json_object_from_value_box(ctx, &vp->data));
json_object_array_add(values, value);
/*
/* json.c */
int fr_json_object_to_value_box(TALLOC_CTX *ctx, value_box_t *out, json_object *object,
- PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv);
+ PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv);
-json_object *json_object_from_value_box(TALLOC_CTX *ctx,
- PW_TYPE type, fr_dict_attr_t const *enumv, value_box_t const *data);
+json_object *json_object_from_value_box(TALLOC_CTX *ctx, value_box_t const *data);
char *fr_json_from_string(TALLOC_CTX *ctx, char const *s, bool include_quotes);
cf_log_err_cp(cp, "Right side of map must be a string");
return -1;
}
- p = map->rhs->tmpl_value_box_datum.datum.strvalue;
+ p = map->rhs->tmpl_value_box_datum.strvalue;
slen = fr_jpath_parse(cache, &cache->jpath, p, map->rhs->tmpl_value_box_length);
if (slen <= 0) goto error;
break;
}
vp->op = map->op;
- if (value_box_steal(vp, &vp->data, vp->da->type, value) < 0) {
+ if (value_box_steal(vp, &vp->data, value) < 0) {
REDEBUG("Copying data to attribute failed: %s", fr_strerror());
talloc_free(vp);
goto error;
MEM(vector = talloc_realloc(request, vector, struct iovec, alloced));
}
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_OCTETS:
case PW_TYPE_STRING:
vector[i].iov_base = vp->vp_ptr;
if (!vp) return -1;
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_DATE:
case PW_TYPE_ETHERNET:
case PW_TYPE_IPV4_ADDR:
break;
default:
- ERROR("Cannot convert %s to Lua type", fr_int2str(dict_attr_types, vp->da->type, "<INVALID>"));
+ ERROR("Cannot convert %s to Lua type", fr_int2str(dict_attr_types, vp->vp_type, "<INVALID>"));
return -1;
}
return 0;
MEM(vp = fr_pair_afrom_da(request, da));
switch (lua_type(L, -1)) {
case LUA_TNUMBER:
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_STRING:
{
char *p;
return;
}
- if (vp->da->type == PW_TYPE_STRING) {
+ if (vp->vp_type == PW_TYPE_STRING) {
char *p;
p = talloc_array(vp, char, len + 1 + 1); /* Account for the ident byte */
char buffer[1024];
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_STRING:
RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
list_name, vp->da->name, vp->vp_strvalue);
/*
* It's a normal single valued attribute
*/
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_STRING:
RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name, list_name,
vp->da->name, vp->vp_strvalue);
return -1;
}
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_STRING:
fr_pair_value_bstrncpy(vp, val, len);
break;
continue; /* not a Cisco or Quintum VSA, continue */
}
- if (vp->da->type != PW_TYPE_STRING) {
- continue;
- }
+ if (vp->vp_type != PW_TYPE_STRING) continue;
/*
* No weird packing. Ignore it.
vp = fr_pair_cursor_next(&cursor)) {
fr_dict_attr_t const *da;
- if (vp->da->vendor != 12394) {
- continue;
- }
+ if (vp->da->vendor != 12394) continue;
- if (vp->da->type != PW_TYPE_STRING) {
- continue;
- }
+ if (vp->vp_type != PW_TYPE_STRING) continue;
da = fr_dict_attr_by_num(NULL, 12394, number);
- if (!da) {
- continue;
- }
+ if (!da) continue;
vp->da = da;
PyTuple_SET_ITEM(pp, 0, attribute);
- switch (vp->da->type) {
+ switch (vp->vp_type) {
case PW_TYPE_STRING:
value = PyUnicode_FromStringAndSize(vp->vp_strvalue, vp->vp_length);
break;
/*
* Catch the case of broken dictionaries.
*/
- if (vp->da->type != PW_TYPE_STRING) return RLM_MODULE_NOOP;
+ if (vp->vp_type != PW_TYPE_STRING) return RLM_MODULE_NOOP;
/*
* The string is too short.
PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv)
{
value_box_t in;
- PW_TYPE src_type = 0;
memset(&in, 0, sizeof(in));
return -1;
}
if (reply->integer < 0) { /* 32bit signed (supported) */
- src_type = PW_TYPE_SIGNED;
+ in.type = PW_TYPE_SIGNED;
in.datum.sinteger = (int32_t) reply->integer;
in.length = sizeof(in.datum.sinteger);
}
else if (reply->integer > UINT32_MAX) { /* 64bit unsigned (supported) */
- src_type = PW_TYPE_INTEGER64;
+ in.type = PW_TYPE_INTEGER64;
in.datum.integer64 = (uint64_t) reply->integer;
in.length = sizeof(in.datum.integer64);
}
else if (reply->integer > UINT16_MAX) { /* 32bit unsigned (supported) */
- src_type = PW_TYPE_INTEGER;
+ in.type = PW_TYPE_INTEGER;
in.datum.integer = (uint32_t) reply->integer;
in.length = sizeof(in.datum.integer);
}
else if (reply->integer > UINT8_MAX) { /* 16bit unsigned (supported) */
- src_type = PW_TYPE_SHORT;
+ in.type = PW_TYPE_SHORT;
in.datum.ushort = (uint16_t) reply->integer;
in.length = sizeof(in.datum.ushort);
}
else { /* 8bit unsigned (supported) */
- src_type = PW_TYPE_BYTE;
+ in.type = PW_TYPE_BYTE;
in.datum.byte = (uint8_t) reply->integer;
in.length = sizeof(in.datum.byte);
}
break;
case REDIS_REPLY_STRING:
- src_type = PW_TYPE_STRING;
+ in.type = PW_TYPE_STRING;
in.datum.ptr = reply->str;
in.length = reply->len;
break;
rad_assert(0);
}
- if (src_type == dst_type) {
- if (value_box_copy(ctx, out, src_type, &in) < 0) return -1;
- } else {
- if (value_box_cast(ctx, out, dst_type, dst_enumv, src_type, NULL, &in) < 0) return -1;
- }
+ if (value_box_cast(ctx, out, dst_type, dst_enumv, &in) < 0) return -1;
+
return 0;
}
}
/* This will only fail only memory allocation errors */
- if (tmpl_afrom_value_box(map, &map->rhs, &vpt,
- map->lhs->tmpl_da->type, map->lhs->tmpl_da, true) < 0) {
- goto error;
- }
+ if (tmpl_afrom_value_box(map, &map->rhs, &vpt, true) < 0) goto error;
}
break;
rad_assert(map->lhs->type == TMPL_TYPE_ATTR);
rad_assert(map->rhs->type == TMPL_TYPE_DATA);
- key_len = tmpl_snprint(key_buf, sizeof(key_buf), map->lhs, map->lhs->tmpl_da);
+ key_len = tmpl_snprint(key_buf, sizeof(key_buf), map->lhs);
if (is_truncated(key_len, sizeof(key_buf))) {
fr_strerror_printf("Key too long. Must be < " STRINGIFY(sizeof(key_buf)) " "
"bytes, got %zu bytes", key_len);
switch (map->rhs->tmpl_value_box_type) {
case PW_TYPE_STRING:
case PW_TYPE_OCTETS:
- out[2] = map->rhs->tmpl_value_box_datum.datum.ptr;
+ out[2] = map->rhs->tmpl_value_box_datum.ptr;
out_len[2] = map->rhs->tmpl_value_box_length;
break;
char value[256];
size_t len;
- len = value_box_snprint(value, sizeof(value), map->rhs->tmpl_value_box_type, map->lhs->tmpl_da,
- &map->rhs->tmpl_value_box_datum, '\0');
+ len = value_box_snprint(value, sizeof(value), &map->rhs->tmpl_value_box, '\0');
new = talloc_bstrndup(pool, value, len);
if (!new) {
talloc_free(key);
void fr_redis_reply_print(log_lvl_t lvl, redisReply *reply, REQUEST *request, int idx);
int fr_redis_reply_to_value_box(TALLOC_CTX *ctx, value_box_t *out, redisReply *reply,
- PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv);
+ PW_TYPE dst_type, fr_dict_attr_t const *dst_enumv);
int fr_redis_reply_to_map(TALLOC_CTX *ctx, vp_map_t **out,
REQUEST *request, redisReply *key, redisReply *op, redisReply *value);
memset(&tmp, 0, sizeof(tmp));
tmp.datum.integer = ntohl((uint32_t)reply->element[1]->integer);
- tmp.length = sizeof(ip_map.rhs->tmpl_value_box_datum.datum.integer);
+ tmp.length = sizeof(ip_map.rhs->tmpl_value_box_datum.integer);
+ tmp.type = PW_TYPE_INTEGER;
- if (value_box_cast(NULL, &ip_map.rhs->tmpl_value_box_datum, PW_TYPE_IPV4_ADDR,
- NULL, PW_TYPE_INTEGER, NULL, &tmp)) {
+ if (value_box_cast(NULL, &ip_map.rhs->tmpl_value_box, PW_TYPE_IPV4_ADDR,
+ NULL, &tmp)) {
REDEBUG("Failed converting integer to IPv4 address: %s", fr_strerror());
ret = IPPOOL_RCODE_FAIL;
goto finish;
}
} else {
- ip_map.rhs->tmpl_value_box_datum.datum.integer = ntohl((uint32_t)reply->element[1]->integer);
- ip_map.rhs->tmpl_value_box_length = sizeof(ip_map.rhs->tmpl_value_box_datum.datum.integer);
+ ip_map.rhs->tmpl_value_box_datum.integer = ntohl((uint32_t)reply->element[1]->integer);
+ ip_map.rhs->tmpl_value_box_length = sizeof(ip_map.rhs->tmpl_value_box_datum.integer);
ip_map.rhs->tmpl_value_box_type = PW_TYPE_INTEGER;
}
}
goto do_ip_map;
case REDIS_REPLY_STRING:
- ip_map.rhs->tmpl_value_box_datum.datum.strvalue = reply->element[1]->str;
+ ip_map.rhs->tmpl_value_box_datum.strvalue = reply->element[1]->str;
ip_map.rhs->tmpl_value_box_length = reply->element[1]->len;
ip_map.rhs->tmpl_value_box_type = PW_TYPE_STRING;
.rhs = &range_rhs
};
- range_map.rhs->tmpl_value_box_datum.datum.strvalue = reply->element[2]->str;
+ range_map.rhs->tmpl_value_box_datum.strvalue = reply->element[2]->str;
range_map.rhs->tmpl_value_box_length = reply->element[2]->len;
range_map.rhs->tmpl_value_box_type = PW_TYPE_STRING;
if (map_to_request(request, &range_map, map_to_vp, NULL) < 0) {
goto finish;
}
- expiry_map.rhs->tmpl_value_box_datum.datum.integer = reply->element[3]->integer;
- expiry_map.rhs->tmpl_value_box_length = sizeof(expiry_map.rhs->tmpl_value_box_datum.datum.integer);
+ expiry_map.rhs->tmpl_value_box_datum.integer = reply->element[3]->integer;
+ expiry_map.rhs->tmpl_value_box_length = sizeof(expiry_map.rhs->tmpl_value_box_datum.integer);
expiry_map.rhs->tmpl_value_box_type = PW_TYPE_INTEGER;
if (map_to_request(request, &expiry_map, map_to_vp, NULL) < 0) {
ret = IPPOOL_RCODE_FAIL;
* Add range ID to request
*/
case REDIS_REPLY_STRING:
- range_map.rhs->tmpl_value_box_datum.datum.strvalue = reply->element[1]->str;
+ range_map.rhs->tmpl_value_box_datum.strvalue = reply->element[1]->str;
range_map.rhs->tmpl_value_box_length = reply->element[1]->len;
range_map.rhs->tmpl_value_box_type = PW_TYPE_STRING;
if (map_to_request(request, &range_map, map_to_vp, NULL) < 0) {
.rhs = &expiry_rhs
};
- expiry_map.rhs->tmpl_value_box_datum.datum.integer = expires;
- expiry_map.rhs->tmpl_value_box_length = sizeof(expiry_map.rhs->tmpl_value_box_datum.datum.integer);
+ expiry_map.rhs->tmpl_value_box_datum.integer = expires;
+ expiry_map.rhs->tmpl_value_box_length = sizeof(expiry_map.rhs->tmpl_value_box_datum.integer);
expiry_map.rhs->tmpl_value_box_type = PW_TYPE_INTEGER;
if (map_to_request(request, &expiry_map, map_to_vp, NULL) < 0) {
ret = IPPOOL_RCODE_FAIL;
};
ip_rhs.tmpl_value_box_length = strlen(ip_str);
- ip_rhs.tmpl_value_box_datum.datum.strvalue = ip_str;
+ ip_rhs.tmpl_value_box_datum.strvalue = ip_str;
ip_rhs.tmpl_value_box_type = PW_TYPE_STRING;
if (map_to_request(request, &ip_map, map_to_vp, NULL) < 0) return RLM_MODULE_FAIL;
VALUE_PAIR *vp;
- PW_TYPE type;
value_box_t src;
if (fr_json_object_is_type(leaf, json_type_null)) {
switch (json_object_get_type(leaf)) {
case json_type_int:
if (flags->do_xlat) RWDEBUG("Ignoring do_xlat on 'int', attribute \"%s\"", da->name);
- type = PW_TYPE_SIGNED;
src.datum.sinteger = json_object_get_int(leaf);
+ src.type = PW_TYPE_SIGNED;
break;
case json_type_double:
if (flags->do_xlat) RWDEBUG("Ignoring do_xlat on 'double', attribute \"%s\"", da->name);
- type = PW_TYPE_DECIMAL;
src.datum.decimal = json_object_get_double(leaf);
+ src.type = PW_TYPE_DECIMAL;
break;
case json_type_string:
- type = PW_TYPE_STRING;
value = json_object_get_string(leaf);
if (flags->do_xlat) {
if (xlat_aeval(request, &expanded, request, value, NULL, NULL) < 0) return NULL;
src.datum.strvalue = value;
src.length = json_object_get_string_len(leaf);
}
+ src.type = PW_TYPE_STRING;
break;
*
* "I knew you liked JSON so I put JSON in your JSON!"
*/
- type = PW_TYPE_STRING;
src.datum.strvalue = json_object_get_string(leaf);
if (!src.datum.strvalue) {
RWDEBUG("Failed getting string value for attribute \"%s\", skipping...", da->name);
return NULL;
}
+ src.type = PW_TYPE_STRING;
src.length = strlen(src.datum.strvalue);
}
- ret = value_box_cast(vp, &vp->data, vp->da->type, vp->da, type, NULL, &src);
+ ret = value_box_cast(vp, &vp->data, da->type, da, &src);
talloc_free(expanded);
if (ret < 0) {
RWDEBUG("Failed parsing value for attribute \"%s\" (skipping): %s", da->name, fr_strerror());
* current request.
*/
RADIUS_LIST_AND_CTX(ctx, list, request, REQUEST_CURRENT, PAIR_LIST_REQUEST);
- if (!list || (fr_pair_update_by_num(ctx, list, 0, PW_REST_HTTP_STATUS_CODE,
- TAG_ANY, PW_TYPE_INTEGER, &value) < 0)) {
+ if (!list || (fr_pair_update_by_num(ctx, list, 0, PW_REST_HTTP_STATUS_CODE, TAG_ANY, &value) < 0)) {
REDEBUG("Failed updating &REST-HTTP-Status-Code");
return -1;
}
static int rlm_test_cmp(UNUSED void *instance, REQUEST *request, UNUSED VALUE_PAIR *thing, VALUE_PAIR *check,
UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs)
{
- rad_assert(check->da->type == PW_TYPE_STRING);
+ rad_assert(check->vp_type == PW_TYPE_STRING);
RINFO("test-Paircmp called with \"%s\"", check->vp_strvalue);
if (*data_name == '&') {
if (radius_get_vp(&vp, request, data_name) < 0) goto nothing;
- if ((vp->da->type != PW_TYPE_OCTETS) &&
- (vp->da->type != PW_TYPE_STRING)) {
+ if ((vp->vp_type != PW_TYPE_OCTETS) &&
+ (vp->vp_type != PW_TYPE_STRING)) {
REDEBUG("unpack requires the input attribute to be 'string' or 'octets'");
goto nothing;
}
for (vp = fr_pair_cursor_init(&cursor, &request->packet->vps);
vp;
vp = fr_pair_cursor_next(&cursor)) {
- if (vp->da->type != PW_TYPE_STRING) continue;
+ if (vp->vp_type != PW_TYPE_STRING) continue;
for (i = 0; i < vp->vp_length; i += len) {
len = fr_utf8_char(&vp->vp_octets[i], -1);