* Xlat expansions are not supported. Convert xlat to value box (if possible).
*/
if (vp->type == VT_XLAT) {
- fr_type_t type = vp->da->type;
- if (fr_value_box_from_str(vp, &vp->data, &type, NULL, vp->xlat, -1, '\0', false) < 0) {
+ if (fr_value_box_from_str(vp, &vp->data, vp->da->type, NULL, vp->xlat, -1, '\0', false) < 0) {
fr_perror("dhcpclient");
fr_radius_packet_free(&packet);
if (fp && (fp != stdin)) fclose(fp);
* Xlat expansions are not supported. Convert xlat to value box (if possible).
*/
if (vp->type == VT_XLAT) {
- fr_type_t type = vp->da->type;
- if (fr_value_box_from_str(vp, &vp->data, &type, NULL, vp->xlat, -1, '\0', false) < 0) {
+ if (fr_value_box_from_str(vp, &vp->data, vp->da->type, NULL, vp->xlat, -1, '\0', false) < 0) {
fr_perror("radclient");
goto error;
}
* Xlat expansions are not supported. Convert xlat to value box (if possible).
*/
if (vp->type == VT_XLAT) {
- fr_type_t type = vp->da->type;
- if (fr_value_box_from_str(vp, &vp->data, &type, NULL, vp->xlat, -1, '\0', false) < 0) {
+ if (fr_value_box_from_str(vp, &vp->data, vp->da->type, NULL, vp->xlat, -1, '\0', false) < 0) {
fr_perror("radclient");
goto error;
}
static int cmd_set_profile_status(UNUSED FILE *fp, FILE *fp_err, UNUSED void *ctx, fr_cmd_info_t const *info)
{
fr_value_box_t box;
- fr_type_t type = FR_TYPE_BOOL;
struct ProfilerState state;
- if (fr_value_box_from_str(NULL, &box, &type, NULL, info->argv[0], strlen(info->argv[0]), '\0', false) < 0) {
+ if (fr_value_box_from_str(NULL, &box, FR_TYPE_BOOL, NULL, info->argv[0], strlen(info->argv[0]), '\0', false) < 0) {
fprintf(fp_err, "Failed setting profile status '%s' - %s\n", info->argv[0], fr_strerror());
return -1;
}
* Xlat expansions are not supported. Convert xlat to value box (if possible).
*/
if (vp->type == VT_XLAT) {
- fr_type_t type = vp->da->type;
- if (fr_value_box_from_str(vp, &vp->data, &type, NULL, vp->xlat, -1, '\0', false) < 0) {
+ if (fr_value_box_from_str(vp, &vp->data, vp->da->type, NULL, vp->xlat, -1, '\0', false) < 0) {
fr_perror("radsniff");
return -1;
}
enc_p = cc->buffer_start;
while (p) {
- fr_type_t type = FR_TYPE_STRING;
fr_value_box_t *box = talloc_zero(NULL, fr_value_box_t);
fr_skip_whitespace(p);
- if (fr_value_box_from_str(box, box, &type, NULL, p, -1, '"', false) < 0) {
+ if (fr_value_box_from_str(box, box, FR_TYPE_STRING, NULL, p, -1, '"', false) < 0) {
talloc_free(box);
RETURN_OK_WITH_ERROR();
}
p = in + match_len;
fr_skip_whitespace(p);
- if (fr_value_box_from_str(box, box, &type, NULL, p, -1, '"', false) < 0) {
+ if (fr_value_box_from_str(box, box, type, NULL, p, -1, '"', false) < 0) {
error:
talloc_free(box);
RETURN_OK_WITH_ERROR();
* box as last time.
*/
box2 = talloc_zero(NULL, fr_value_box_t);
- if (fr_value_box_from_str(box2, box2, &type, NULL, data, slen, '"', false) < 0) {
+ if (fr_value_box_from_str(box2, box2, type, NULL, data, slen, '"', false) < 0) {
talloc_free(box2);
talloc_free(box);
RETURN_OK_WITH_ERROR();
/*
* Parse the data to be sure it's well formed.
*/
- if (fr_value_box_from_str(ctx, box, &type,
+ if (fr_value_box_from_str(ctx, box, type,
NULL, name, -1, quote, true) < 0) {
fr_strerror_printf_push("Failed parsing argument '%s'", name);
return -1;
}
ret = fr_value_box_from_str(info->box[argc], info->box[argc],
- &type, NULL,
- word + offset, len - (offset << 1), quote, false);
+ type, NULL,
+ word + offset, len - (offset << 1), quote, false);
if (ret < 0) return -1;
/*
}
ret = fr_value_box_from_str(info->box[info->argc], info->box[info->argc],
- &type, NULL,
- word + offset, len - (offset << 1), quote, false);
+ type, NULL,
+ word + offset, len - (offset << 1), quote, false);
if (ret < 0) return -1;
info->argc++;
*word_p = word = p;
if (!tmpl_is_attr(vpt)) return 0;
switch (tmpl_da(vpt)->type) {
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
break;
default:
fr_dcursor_init(&values, &head);
if (fr_value_box_from_str(fr_dlist_head(&n->mod),
- tmpl_value(fr_map_list_head(&n->mod)->rhs), &type,
+ tmpl_value(fr_map_list_head(&n->mod)->rhs), type,
tmpl_da(mutated->lhs),
mutated->rhs->name, mutated->rhs->len, mutated->rhs->quote, false)) {
RPEDEBUG("Assigning value to \"%s\" failed", tmpl_da(mutated->lhs)->name);
void tmpl_attr_to_raw(tmpl_t *vpt);
-int tmpl_attr_abstract_to_concrete(tmpl_t *vpt, fr_type_t type);
-
int tmpl_attr_unknown_add(tmpl_t *vpt);
int tmpl_attr_unresolved_add(fr_dict_t *dict, tmpl_t *vpt,
*
* @fixme We need a way of signalling xlat not to escape things.
*/
- ret = fr_value_box_from_str(tmp_ctx, &tmp, &src_type, NULL,
+ ret = fr_value_box_from_str(tmp_ctx, &tmp, src_type, NULL,
value.vb_strvalue, value.vb_length, '"', false);
if (ret < 0) goto error;
*
* @fixme We need a way of signalling xlat not to escape things.
*/
- ret = fr_value_box_from_str(tmp_ctx, &tmp, &src_type, NULL,
+ ret = fr_value_box_from_str(tmp_ctx, &tmp, src_type, NULL,
value.vb_strvalue, value.vb_length, '"', false);
if (ret < 0) goto error;
}
MEM(vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, T_BARE_WORD, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in)));
- if (fr_value_box_from_str(vpt, &vpt->data.literal, &type, NULL,
+ if (fr_value_box_from_str(vpt, &vpt->data.literal, type, NULL,
fr_sbuff_start(&our_in), fr_sbuff_used(&our_in), '\0', false) < 0) {
talloc_free(vpt);
goto error;
}
MEM(vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, T_BARE_WORD, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in)));
- if (fr_value_box_from_str(vpt, &vpt->data.literal, &type, NULL,
+ if (fr_value_box_from_str(vpt, &vpt->data.literal, type, NULL,
fr_sbuff_start(&our_in), fr_sbuff_used(&our_in), '\0', false) < 0) {
talloc_free(vpt);
goto error;
fr_strerror_const("Unknown data type");
FR_SBUFF_ERROR_RETURN(&our_in);
}
- if (fr_dict_non_data_types[cast]) {
+ if (fr_type_is_non_leaf(cast)) {
fr_strerror_const("Forbidden data type in cast");
FR_SBUFF_MARKER_ERROR_RETURN(&m);
}
* Only "base" data types are allowed. Structural types
* and horrid WiMAX crap is forbidden.
*/
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
break;
}
* Why do we pass a pointer to a temporary type
* variable? Goddamn WiMAX.
*/
- if (fr_value_box_from_str(vpt, &vpt->data.literal, &type,
+ if (fr_value_box_from_str(vpt, &vpt->data.literal, type,
enumv, unescaped, talloc_array_length(unescaped) - 1,
'\0', false) < 0) return -1;
talloc_free(unescaped);
attr_to_raw(vpt, fr_dlist_tail(&vpt->data.attribute.ar));
}
-/** Convert an abstract da into a concrete one
- *
- * Usually used to fixup combo ip addresses
- */
-int tmpl_attr_abstract_to_concrete(tmpl_t *vpt, fr_type_t type)
-{
- fr_dict_attr_t const *abstract;
- fr_dict_attr_t const *concrete;
- tmpl_attr_t *ref;
-
- tmpl_assert_type(tmpl_is_attr(vpt));
-
- abstract = tmpl_da(vpt);
- if (abstract->type != FR_TYPE_COMBO_IP_ADDR) {
- fr_strerror_printf("Abstract attribute \"%s\" is of incorrect type '%s'", abstract->name,
- fr_table_str_by_value(fr_value_box_type_table, abstract->type, "<INVALID>"));
- return -1;
- }
-
- concrete = fr_dict_attr_by_type(abstract, type);
- if (!concrete) {
- fr_strerror_printf("Can't convert abstract type '%s' to concrete type '%s'",
- fr_table_str_by_value(fr_value_box_type_table, abstract->type, "<INVALID>"),
- fr_table_str_by_value(fr_value_box_type_table, type, "<INVALID>"));
- return -1;
- }
-
- ref = fr_dlist_tail(&vpt->data.attribute.ar);
- ref->da = concrete;
-
- TMPL_ATTR_VERIFY(vpt);
-
- return 0;
-}
-
/** Add an unknown #fr_dict_attr_t specified by a #tmpl_t to the main dictionary
*
* @param vpt to add. ``tmpl_da`` pointer will be updated to point to the
}
da = tmpl_da(vpt);
-
- if ((da->type == FR_TYPE_COMBO_IP_ADDR) && (da->type != tmpl_da(vpt)->type)) {
- da = fr_dict_attr_by_type(tmpl_da(vpt), tmpl_da(vpt)->type);
- if (!da) {
- fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_ATTR "
- "attribute \"%s\" variant (%s) not found in dictionary (%s)",
- file, line, tmpl_da(vpt)->name,
- fr_table_str_by_value(fr_value_box_type_table, tmpl_da(vpt)->type, "<INVALID>"),
- fr_dict_root(dict)->name);
- }
- }
-
if (!tmpl_da(vpt)->flags.is_unknown && !tmpl_da(vpt)->flags.is_raw && (da != tmpl_da(vpt))) {
fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_ATTR "
"dictionary pointer %p \"%s\" (%s) "
* We can only cast to basic data types. Complex ones
* are forbidden.
*/
- if (fr_dict_non_data_types[cast]) {
+ if (fr_type_is_non_leaf(cast)) {
return_P("Forbidden data type in cast");
}
size_t fr_sim_attr_len(fr_pair_t const *vp)
{
switch (vp->vp_type) {
+ case FR_TYPE_STRUCTURAL:
+ fr_assert_fail(NULL);
+ return 0;
+
case FR_TYPE_VARIABLE_SIZE:
return vp->vp_length;
default:
return fr_sim_attr_sizes[vp->vp_type][0];
-
- case FR_TYPE_STRUCTURAL:
- fr_assert_fail(NULL);
- return 0;
}
}
fr_table_str_by_value(fr_value_box_type_table, tmpl_da(map->lhs)->type, "<INVALID>"));
return -1;
}
-
- /*
- * Fixup LHS da if it doesn't match the type
- * of the RHS.
- */
- if (tmpl_da(map->lhs)->type != tmpl_value_type(map->rhs)) {
- if (tmpl_attr_abstract_to_concrete(map->lhs, tmpl_value_type(map->rhs)) < 0) return -1;
- }
} /* else we can't precompile the data */
return 0;
fr_table_str_by_value(fr_value_box_type_table, tmpl_da(map->lhs)->type, "<INVALID>"));
return -1;
}
-
- /*
- * Fixup LHS da if it doesn't match the type
- * of the RHS.
- */
- if (tmpl_da(map->lhs)->type != tmpl_value_type(map->rhs)) {
- if (tmpl_attr_abstract_to_concrete(map->lhs, tmpl_value_type(map->rhs)) < 0) return -1;
- }
} /* else we can't precompile the data */
return 0;
fr_value_box_list_init(&state->box);
MEM(box = fr_value_box_alloc(state->ctx, FR_TYPE_STRING, NULL, true));
- if (fr_value_box_from_str(state->ctx, box, &type, NULL,
+ if (fr_value_box_from_str(state->ctx, box, type, NULL,
fr_sbuff_buff(&state->exec.stdout_buff),
fr_sbuff_used(&state->exec.stdout_buff), 0, true) < 0) {
talloc_free(box);
}
switch (arg->type) {
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
case FR_TYPE_VOID:
break;
if (vendor) RIDEBUG2("vendor : %i (%s)", vendor->pen, vendor->name);
RIDEBUG3("type : %s", fr_table_str_by_value(fr_value_box_type_table, vp->vp_type, "<INVALID>"));
- switch (vp->vp_type) {
- case FR_TYPE_VARIABLE_SIZE:
+ if (fr_box_is_variable_size(&vp->data)) {
RIDEBUG3("length : %zu", vp->vp_length);
- break;
-
- default:
- break;
}
if (!RDEBUG_ENABLED4) continue;
if ((fr_type_t) type->value == vp->vp_type) goto next_type;
switch (type->value) {
- case FR_TYPE_NON_VALUES: /* Skip everything that's not a value */
+ case FR_TYPE_NON_LEAF: /* Skip everything that's not a value */
goto next_type;
default:
fr_value_box_t data;
type = FR_TYPE_STRING;
- if (fr_value_box_from_str(ctx, &data, &type, NULL, child,
+ if (fr_value_box_from_str(ctx, &data, type, NULL, child,
talloc_array_length(child) - 1, '"', false) < 0) {
talloc_free(child);
return NULL;
*
*/
extern bool const fr_dict_attr_allowed_chars[UINT8_MAX + 1];
-extern bool const fr_dict_non_data_types[FR_TYPE_MAX + 1];
/** @name Dictionary structure extensions
*
char const *attr)
CC_HINT(nonnull(2,3));
-fr_dict_attr_t const *fr_dict_attr_by_type(fr_dict_attr_t const *da, fr_type_t type);
-
fr_dict_attr_t const *fr_dict_attr_child_by_da(fr_dict_attr_t const *parent, fr_dict_attr_t const *child) CC_HINT(nonnull);
fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr);
da = fr_dict_attr_unconst(da_const);
type = da->type;
- if (fr_value_box_from_str(fixup, &value, &type, NULL,
+ if (fr_value_box_from_str(fixup, &value, type, NULL,
fixup->value, talloc_array_length(fixup->value) - 1, '\0', false) < 0) {
fr_strerror_printf_push("Invalid VALUE for Attribute '%s' at %s[%d]",
da->name,
return -1;
}
- if (dict_attr_add_to_namespace(dict, fixup->parent, cloned) < 0) return -1;
+ if (dict_attr_add_to_namespace(fixup->parent, cloned) < 0) return -1;
return 0;
}
fr_hash_table_t *vendors_by_name; //!< Lookup vendor by name.
fr_hash_table_t *vendors_by_num; //!< Lookup vendor by PEN.
- fr_hash_table_t *attributes_combo; //!< Lookup variants of polymorphic attributes.
-
fr_dict_attr_t *root; //!< Root attribute of this dictionary.
TALLOC_CTX *pool; //!< Talloc memory pool to reduce allocs.
int dict_vendor_add(fr_dict_t *dict, char const *name, unsigned int num);
-int dict_attr_add_to_namespace(fr_dict_t *dict,
- fr_dict_attr_t const *parent, fr_dict_attr_t *da) CC_HINT(nonnull);
+int dict_attr_add_to_namespace(fr_dict_attr_t const *parent, fr_dict_attr_t *da) CC_HINT(nonnull);
bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent,
UNUSED char const *name, int *attr, fr_type_t type,
break;
}
- {
- fr_type_t type = da->type; /* Might change - Stupid combo IP */
-
- if (fr_value_box_from_str(NULL, &value, &type, NULL, argv[2], -1, '\0', false) < 0) {
- fr_strerror_printf_push("Invalid VALUE for Attribute '%s'", da->name);
- return -1;
- }
+ if (fr_value_box_from_str(NULL, &value, da->type, NULL, argv[2], -1, '\0', false) < 0) {
+ fr_strerror_printf_push("Invalid VALUE for Attribute '%s'", da->name);
+ return -1;
}
if (fr_dict_enum_add_name(da, argv[1], &value, false, true) < 0) {
fr_dict_attr_t const *da;
fr_dict_attr_t const *parent = NULL;
fr_value_box_t value;
- fr_type_t type;
unsigned int attr;
fr_dict_attr_flags_t flags;
char *key_attr = argv[1];
/*
* Parse the value.
*/
- type = parent->type; /* because of combo-IP nonsense */
- if (fr_value_box_from_str(NULL, &value, &type, NULL, argv[2], -1, '\0', false) < 0) {
+ if (fr_value_box_from_str(NULL, &value, parent->type, NULL, argv[2], -1, '\0', false) < 0) {
fr_strerror_printf_push("Invalid value for STRUCT \"%s\"", argv[2]);
return -1;
}
/*
* @todo - auto-number from a parent UNION, instead of overloading the value.
*/
- switch (type) {
+ switch (parent->type) {
case FR_TYPE_UINT8:
attr = value.vb_uint8;
break;
goto error;
}
- if (dict_attr_add_to_namespace(ctx->dict, UNCONST(fr_dict_attr_t *, vsa_da), new) < 0) {
+ if (dict_attr_add_to_namespace(UNCONST(fr_dict_attr_t *, vsa_da), new) < 0) {
talloc_free(new);
goto error;
}
goto error;
}
- if (dict_attr_add_to_namespace(dict, dict->root, n) < 0) {
+ if (dict_attr_add_to_namespace(dict->root, n) < 0) {
fr_strerror_printf_push("Failed inserting '%s' into internal dictionary", type_name);
talloc_free(type_name);
goto error;
* is responsible for converting "Attr-26 = 0x..." to an actual attribute,
* if it so desires.
*/
- if (dict_attr_add_to_namespace(dict, parent, n) < 0) {
+ if (dict_attr_add_to_namespace(parent, n) < 0) {
talloc_free(n);
return NULL;
}
.is_unknown = true,
};
- switch (parent->type) {
- case FR_TYPE_STRUCTURAL_EXCEPT_VSA:
- break;
-
- default:
+ if (!fr_type_is_structural_except_vsa(parent->type)) {
fr_strerror_printf("%s: Cannot allocate unknown tlv attribute (%u) with parent type %s",
__FUNCTION__,
num,
.is_unknown = true,
};
- switch (parent->type) {
- case FR_TYPE_STRUCTURAL_EXCEPT_VSA:
- break;
-
- default:
+ if (!fr_type_is_structural_except_vsa(parent->type)) {
fr_strerror_printf("%s: Cannot allocate unknown octets attribute (%u) with parent type %s",
__FUNCTION__,
num,
['z'] = true
};
-/** Structural data types
- *
- */
-bool const fr_dict_non_data_types[FR_TYPE_MAX + 1] = {
- [FR_TYPE_GROUP] = true,
- [FR_TYPE_STRUCT] = true,
- [FR_TYPE_TLV] = true,
- [FR_TYPE_VENDOR] = true,
- [FR_TYPE_VSA] = true
-};
-
/*
* Create the hash of the name.
*
return strcasecmp(a->name, b->name);
}
-/** Hash a combo attribute
- *
- */
-static uint32_t dict_attr_combo_hash(void const *data)
-{
- uint32_t hash;
- fr_dict_attr_t const *attr = data;
-
- hash = fr_hash(&attr->parent, sizeof(attr->parent)); //-V568
- hash = fr_hash_update(&attr->type, sizeof(attr->type), hash);
- return fr_hash_update(&attr->attr, sizeof(attr->attr), hash);
-}
-
-/** Compare two combo attribute entries
- *
- */
-static int dict_attr_combo_cmp(void const *one, void const *two)
-{
- fr_dict_attr_t const *a = one, *b = two;
- int ret;
-
- ret = (a->parent < b->parent) - (a->parent > b->parent);
- if (ret != 0) return ret;
-
- ret = (a->type < b->type) - (a->type > b->type);
- if (ret != 0) return ret;
-
- return (a->attr > b->attr) - (a->attr < b->attr);
-}
-
/** Wrap name hash function for fr_dict_vendor_t
*
* @param data fr_dict_vendor_t to hash.
if (dict_attr_child_add(dst, copy) < 0) return -1;
- if (dict_attr_add_to_namespace(dict, dst, copy) < 0) return -1;
+ if (dict_attr_add_to_namespace(dst, copy) < 0) return -1;
if (!dict_attr_children(child)) continue;
/** Add an attribute to the name table for an attribute
*
- * @param[in] dict of protocol context we're operating in.
* @param[in] parent containing the namespace to add this attribute to.
* @param[in] da to add to the name lookup tables.
* @return
* - 0 on success.
* - -1 on failure.
*/
-int dict_attr_add_to_namespace(fr_dict_t *dict, fr_dict_attr_t const *parent, fr_dict_attr_t *da)
+int dict_attr_add_to_namespace(fr_dict_attr_t const *parent, fr_dict_attr_t *da)
{
fr_hash_table_t *namespace;
}
}
- /*
- * Insert copies of the attribute into the
- * polymorphic attribute table.
- *
- * This allows an abstract attribute type
- * like combo IP to be resolved to a
- * concrete one later.
- */
- switch (da->type) {
- case FR_TYPE_COMBO_IP_ADDR:
- {
- fr_dict_attr_t *v4, *v6;
-
- fr_assert(dict->attributes_combo);
-
- v4 = dict_attr_acopy(dict->pool, da, NULL);
- if (!v4) goto error;
- v4->type = FR_TYPE_IPV4_ADDR;
-
- v6 = dict_attr_acopy(dict->pool, da, NULL);
- if (!v6) goto error;
- v6->type = FR_TYPE_IPV6_ADDR;
-
- if (!fr_hash_table_replace(dict->attributes_combo, v4)) {
- fr_strerror_const("Failed inserting IPv4 version of combo attribute");
- goto error;
- }
-
- if (!fr_hash_table_replace(dict->attributes_combo, v6)) {
- fr_strerror_const("Failed inserting IPv6 version of combo attribute");
- goto error;
- }
- break;
- }
-
- case FR_TYPE_COMBO_IP_PREFIX:
- {
- fr_dict_attr_t *v4, *v6;
-
- fr_assert(dict->attributes_combo);
-
- v4 = dict_attr_acopy(dict->pool, da, NULL);
- if (!v4) goto error;
- v4->type = FR_TYPE_IPV4_PREFIX;
-
- v6 = dict_attr_acopy(dict->pool, da, NULL);
- if (!v6) goto error;
- v6->type = FR_TYPE_IPV6_PREFIX;
-
- if (!fr_hash_table_replace(dict->attributes_combo, v4)) {
- fr_strerror_const("Failed inserting IPv4 version of combo attribute");
- goto error;
- }
-
- if (!fr_hash_table_replace(dict->attributes_combo, v6)) {
- fr_strerror_const("Failed inserting IPv6 version of combo attribute");
- goto error;
- }
- break;
- }
-
- default:
- break;
- }
-
return 0;
}
old = fr_dict_attr_child_by_num(parent, n->attr);
if (old && (dict_attr_compatible(parent, old, n) < 0)) goto error;
- if (dict_attr_add_to_namespace(dict, parent, n) < 0) {
+ if (dict_attr_add_to_namespace(parent, n) < 0) {
error:
talloc_free(n);
return -1;
return dict_attr_by_name(err, parent, name);
}
-
-/** Lookup a attribute by its its vendor and attribute numbers and data type
- *
- * @note Only works with FR_TYPE_COMBO_IP
- *
- * @param[in] da to look for type variant of.
- * @param[in] type Variant of attribute to lookup.
- * @return
- * - Attribute matching parent/attr/type.
- * - NULL if no matching attribute could be found.
- */
-fr_dict_attr_t const *fr_dict_attr_by_type(fr_dict_attr_t const *da, fr_type_t type)
-{
- return fr_hash_table_find_by_data(dict_by_da(da)->attributes_combo,
- &(fr_dict_attr_t){
- .parent = da->parent,
- .attr = da->attr,
- .type = type
- });
-}
-
/** Check if a child attribute exists in a parent using a pointer (da)
*
* @param[in] parent to check for child in.
* are still there.
*/
talloc_free(dict->vendors_by_name);
- talloc_free(dict->attributes_combo);
if (dict->autoref &&
(fr_hash_table_walk(dict->autoref, _dict_free_autoref, NULL) < 0)) {
goto error;
}
- /*
- * Horrible hacks for combo-IP.
- */
- dict->attributes_combo = fr_hash_table_create(dict, dict_attr_combo_hash, dict_attr_combo_cmp, hash_pool_free);
- if (!dict->attributes_combo) {
- fr_strerror_printf("Failed allocating \"attributes_combo\" table");
- goto error;
- }
-
/*
* Set default type size and length.
*/
break;
case FR_TYPE_IPV6_ADDR:
+ case FR_TYPE_COMBO_IP_ADDR:
flags->length = 16;
break;
+ case FR_TYPE_IPV6_PREFIX:
+ case FR_TYPE_COMBO_IP_PREFIX:
+ flags->length = 17;
+ break;
+
case FR_TYPE_STRUCT:
ALLOW_FLAG(internal);
if (all_flags) {
}
break;
- case FR_TYPE_COMBO_IP_ADDR:
- if (strcasecmp(dict->root->name, "RADIUS") != 0) {
- fr_strerror_const("The 'combo-ip' type can only be used in the RADIUS dictionary.");
- return false;
- }
-
- /*
- * RFC 6929 says that this is a terrible idea.
- */
- for (v = parent; v != NULL; v = v->parent) {
- if (v->type == FR_TYPE_VSA) {
- break;
- }
- }
-
- if (!v) {
- fr_strerror_const("Attributes of type 'combo-ip' can only be used in VSA dictionaries");
- return false;
- }
- break;
-
case FR_TYPE_NULL:
case FR_TYPE_FLOAT64:
- case FR_TYPE_COMBO_IP_PREFIX:
fr_strerror_printf("Attributes of type '%s' cannot be used in dictionaries",
fr_table_str_by_value(fr_value_box_type_table, type, "?Unknown?"));
return false;
* the first member.
*/
if (sibling->flags.length == 0) switch (sibling->type) {
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
break;
default:
*/
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, ssize_t inlen, char quote, bool tainted)
{
- fr_type_t type;
-
if (!value) return -1;
- type = vp->da->type;
-
/*
* This is not yet supported because the rest of the APIs
* to parse pair names, etc. don't yet enforce "inlen".
* haven't yet audited the uses of this function for that
* behavior.
*/
- switch (type) {
+ switch (vp->da->type) {
case FR_TYPE_STRUCTURAL:
fr_strerror_printf("Attributes of type '%s' are not yet supported",
- fr_table_str_by_value(fr_value_box_type_table, type, "<INVALID>"));
+ fr_table_str_by_value(fr_value_box_type_table, vp->da->type, "<INVALID>"));
return -1;
default:
* We presume that the input data is from a double quoted
* string, and needs unescaping
*/
- if (fr_value_box_from_str(vp, &vp->data, &type, vp->da, value, inlen, quote, tainted) < 0) return -1;
-
- /*
- * If we parsed to a different type than the DA associated with
- * the fr_pair_t we now need to fixup the DA.
- *
- * This is for types COMBO_IP. fr_pair_ts have a fixed
- * data type, and not a polymorphic one. So instead of
- * hacking polymorphic crap through the entire server
- * code, we have this hack to make them static.
- */
- if (type != vp->da->type) {
- fr_dict_attr_t const *da;
-
- da = fr_dict_attr_by_type(vp->da, type);
- if (!da) {
- fr_strerror_printf("Cannot find %s variant of attribute \"%s\"",
- fr_table_str_by_value(fr_value_box_type_table, type, "<INVALID>"), vp->da->name);
- return -1;
- }
- vp->da = da;
- vp->data.enumv = da;
- }
+ if (fr_value_box_from_str(vp, &vp->data, vp->da->type, vp->da, value, inlen, quote, tainted) < 0) return -1;
vp->type = VT_DATA;
VP_VERIFY(vp);
char const *str;
fr_dict_enum_t const *enumv = NULL;
- switch (vp->vp_type) {
- case FR_TYPE_NUMERIC:
- break;
-
- default:
+ if (!fr_box_is_numeric(&vp->data)) {
fr_strerror_printf("Pair %s is not numeric", vp->da->name);
return NULL;
}
fr_dict_attr_t const *da;
da = vp->da;
-
- if (da->type == FR_TYPE_COMBO_IP_ADDR) {
- da = fr_dict_attr_by_type(vp->da, vp->da->type);
- if (!da) {
- fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_pair_t attribute %p \"%s\" "
- "variant (%s) not found in global dictionary",
- file, line, vp->da, vp->da->name,
- fr_table_str_by_value(fr_value_box_type_table,
- vp->da->type, "<INVALID>"));
- }
- }
-
if (da != vp->da) {
fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_pair_t "
"dictionary pointer %p \"%s\" (%s) "
FR_PROTO_TRACE("fr_struct_from_network - unknown child type");
goto unknown;
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
break;
}
bool const fr_type_fixed_size[FR_TYPE_MAX + 1] = FR_TYPE_FIXED_SIZE_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
bool const fr_type_variable_size[FR_TYPE_MAX + 1] = FR_TYPE_VARIABLE_SIZE_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
-bool const fr_type_values[FR_TYPE_MAX + 1] = FR_TYPE_VALUES_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
bool const fr_type_quoted[FR_TYPE_MAX + 1] = FR_TYPE_QUOTED_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
bool const fr_type_structural_except_vsa[FR_TYPE_MAX + 1] = FR_TYPE_STRUCTURAL_EXCEPT_VSA_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
bool const fr_type_structural[FR_TYPE_MAX + 1] = FR_TYPE_STRUCTURAL_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
-bool const fr_type_non_values[FR_TYPE_MAX + 1] = FR_TYPE_NON_VALUES_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
+bool const fr_type_leaf[FR_TYPE_MAX + 1] = FR_TYPE_LEAF_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
+bool const fr_type_non_leaf[FR_TYPE_MAX + 1] = FR_TYPE_NON_LEAF_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END);
#define O(_x) [FR_TYPE_ ## _x] = true
* Invalid casts.
*/
switch (dst) {
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
return false;
default:
}
switch (src) {
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
return false;
default:
* Invalid types
*/
switch (a) {
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
return FR_TYPE_NULL;
default:
}
switch (b) {
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
return FR_TYPE_NULL;
default:
/** Types which can fit in an #fr_ipaddr_t
*
+ * - Combo IP addresses
+ * - Combo IP prefixes
* - IPv4 addresses
* - IPv6 addresses
* - IPv4 prefix
* - IPv6 prefix
*/
#define FR_TYPE_IP_DEF(_beg, _mid, _end) \
- _beg(FR_TYPE_IPV4_ADDR) \
+ _beg(FR_TYPE_COMBO_IP_ADDR) \
+ _mid(FR_TYPE_COMBO_IP_PREFIX) \
+ _mid(FR_TYPE_IPV4_ADDR) \
_mid(FR_TYPE_IPV4_PREFIX) \
_mid(FR_TYPE_IPV6_ADDR) \
_end(FR_TYPE_IPV6_PREFIX)
#define FR_TYPE_FIXED_SIZE_DEF(_beg, _mid, _end) \
_beg(FR_TYPE_ETHERNET) \
_mid(FR_TYPE_IFID) \
- FR_TYPE_IP_DEF(_mid, _mid, _mid) \
+ _mid(FR_TYPE_IPV4_ADDR) \
+ _mid(FR_TYPE_IPV4_PREFIX) \
+ _mid(FR_TYPE_IPV6_ADDR) \
+ _mid(FR_TYPE_IPV6_PREFIX) \
FR_TYPE_NUMERIC_DEF(_mid, _mid, _end)
/** Match all variable length types
+ *
+ * @note Whilst combo IP addresses and prefixes may technically be
+ * variable length on the wire, these groupings are referring
+ * to our internal box representation which is fixed size.
*
* - Strings
* - Octets
_beg(FR_TYPE_STRING) \
_end(FR_TYPE_OCTETS)
-/** Types which represent concrete values
- *
- * - Network addresses
- * - Strings
- * - Octets
- * - Numbers
- */
-#define FR_TYPE_VALUES_DEF(_beg, _mid, _end) \
- _beg(FR_TYPE_ETHERNET) \
- _mid(FR_TYPE_IFID) \
- FR_TYPE_IP_DEF(_mid, _mid, _mid) \
- FR_TYPE_VARIABLE_SIZE_DEF(_mid, _mid, _mid) \
- FR_TYPE_NUMERIC_DEF(_mid, _mid, _end)
-
/** Types which should be wrapped in double quotes when printed
*
* - Strings
_beg(FR_TYPE_VSA) \
FR_TYPE_STRUCTURAL_EXCEPT_VSA_DEF(_mid, _mid, _end)
-/** Types which do not represent concrete values
+/** Types which represent concrete values
+ *
+ * - Network addresses
+ * - Strings
+ * - Octets
+ * - Numbers
+ */
+#define FR_TYPE_LEAF_DEF(_beg, _mid, _end) \
+ _beg(FR_TYPE_ETHERNET) \
+ _mid(FR_TYPE_IFID) \
+ FR_TYPE_IP_DEF(_mid, _mid, _mid) \
+ FR_TYPE_VARIABLE_SIZE_DEF(_mid, _mid, _mid) \
+ FR_TYPE_NUMERIC_DEF(_mid, _mid, _end)
+
+/** Types which do not represent leaf values
*
- * - Combo IPs
- * - Combo prefixes
* - Structural
* - Boxes (can represent any type)
* - Void (opaque types)
* - Null (lack of value)
* - Invalid values
*/
-#define FR_TYPE_NON_VALUES_DEF(_beg, _mid, _end) \
- _beg(FR_TYPE_COMBO_IP_ADDR) \
- _mid(FR_TYPE_COMBO_IP_PREFIX) \
- _mid(FR_TYPE_VALUE_BOX) \
+#define FR_TYPE_NON_LEAF_DEF(_beg, _mid, _end) \
+ _beg(FR_TYPE_VALUE_BOX) \
_mid(FR_TYPE_VOID) \
_mid(FR_TYPE_NULL) \
_mid(FR_TYPE_MAX) \
#define FR_TYPE_FIXED_SIZE FR_TYPE_FIXED_SIZE_DEF(CASE_BEG, CASE_MID, CASE_END)
#define FR_TYPE_VARIABLE_SIZE FR_TYPE_VARIABLE_SIZE_DEF(CASE_BEG, CASE_MID, CASE_END)
-#define FR_TYPE_VALUES FR_TYPE_VALUES_DEF(CASE_BEG, CASE_MID, CASE_END)
#define FR_TYPE_QUOTED FR_TYPE_QUOTED_DEF(CASE_BEG, CASE_MID, CASE_END)
#define FR_TYPE_STRUCTURAL_EXCEPT_VSA FR_TYPE_STRUCTURAL_EXCEPT_VSA_DEF(CASE_BEG, CASE_MID, CASE_END)
#define FR_TYPE_STRUCTURAL FR_TYPE_STRUCTURAL_DEF(CASE_BEG, CASE_MID, CASE_END)
-#define FR_TYPE_NON_VALUES FR_TYPE_NON_VALUES_DEF(CASE_BEG, CASE_MID, CASE_END)
+#define FR_TYPE_LEAF FR_TYPE_LEAF_DEF(CASE_BEG, CASE_MID, CASE_END)
+#define FR_TYPE_NON_LEAF FR_TYPE_NON_LEAF_DEF(CASE_BEG, CASE_MID, CASE_END)
/** @} */
/** @name Bool arrays that group types
extern bool const fr_type_fixed_size[FR_TYPE_MAX + 1];
extern bool const fr_type_variable_size[FR_TYPE_MAX + 1];
-extern bool const fr_type_values[FR_TYPE_MAX + 1];
extern bool const fr_type_quoted[FR_TYPE_MAX + 1];
extern bool const fr_type_structural_except_vsa[FR_TYPE_MAX + 1];
extern bool const fr_type_structural[FR_TYPE_MAX + 1];
-extern bool const fr_type_non_values[FR_TYPE_MAX + 1];
+extern bool const fr_type_leaf[FR_TYPE_MAX + 1];
+extern bool const fr_type_non_leaf[FR_TYPE_MAX + 1];
/** @} */
/** @name Type checking macros
#define fr_type_is_ip(_x) (fr_type_ip[_x])
#define fr_type_is_fixed_size(_x) (fr_type_fixed_size[_x])
-#define fr_type_is_variable_size(_x) (fr_variable_size[_x])
-#define fr_type_is_value(_x) (fr_type_values[_x])
+#define fr_type_is_variable_size(_x) (fr_type_variable_size[_x])
#define fr_type_is_quoted(_x) (fr_type_quoted[_x])
#define fr_type_is_structural_except_vsa(_x) (fr_type_structural_except_vsa[_x])
#define fr_type_is_structural(_x) (fr_type_structural[_x])
-#define fr_type_is_non_value(_x) (fr_type_non_values[_x])
+#define fr_type_is_leaf(_x) (fr_type_leaf[_x])
+#define fr_type_is_non_leaf(_x) (fr_type_non_leaf[_x])
/** @} */
bool fr_type_cast(fr_type_t dst, fr_type_t src);
[FR_TYPE_IPV4_PREFIX] = {5, 5},
[FR_TYPE_IPV6_ADDR] = {16, 17},
[FR_TYPE_IPV6_PREFIX] = {17, 18},
+ [FR_TYPE_COMBO_IP_ADDR] = {4, 17},
+ [FR_TYPE_COMBO_IP_PREFIX] = {16, 18},
[FR_TYPE_IFID] = {8, 8},
[FR_TYPE_ETHERNET] = {6, 6},
case FR_TYPE_IPV4_PREFIX:
case FR_TYPE_IPV6_ADDR:
case FR_TYPE_IPV6_PREFIX:
+ case FR_TYPE_COMBO_IP_ADDR:
+ case FR_TYPE_COMBO_IP_PREFIX:
compare = memcmp(&a->vb_ip, &b->vb_ip, sizeof(a->vb_ip));
break;
/*
* These should be handled at some point
*/
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
(void)fr_cond_assert(0); /* unknown type */
return -2;
case FR_TYPE_OCTETS:
case FR_TYPE_STRING:
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
fr_assert_fail(NULL);
return -1; /* shouldn't happen */
}
switch (value->type) {
case FR_TYPE_IPV4_ADDR:
+ ipv4addr:
FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff,
(uint8_t const *)&value->vb_ip.addr.v4.s_addr,
sizeof(value->vb_ip.addr.v4.s_addr));
* Needs special mangling
*/
case FR_TYPE_IPV4_PREFIX:
+ ipv4prefix:
FR_DBUFF_IN_RETURN(&work_dbuff, value->vb_ip.prefix);
FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff,
(uint8_t const *)&value->vb_ip.addr.v4.s_addr,
break;
case FR_TYPE_IPV6_ADDR:
+ ipv6addr:
if (value->vb_ip.scope_id > 0) FR_DBUFF_IN_RETURN(&work_dbuff, value->vb_ip.scope_id);
FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, value->vb_ip.addr.v6.s6_addr, sizeof(value->vb_ip.addr.v6.s6_addr));
break;
case FR_TYPE_IPV6_PREFIX:
+ ipv6prefix:
if (value->vb_ip.scope_id > 0) FR_DBUFF_IN_RETURN(&work_dbuff, value->vb_ip.scope_id);
FR_DBUFF_IN_RETURN(&work_dbuff, value->vb_ip.prefix);
FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, value->vb_ip.addr.v6.s6_addr, sizeof(value->vb_ip.addr.v6.s6_addr));
FR_DBUFF_IN_BYTES_RETURN(&work_dbuff, value->datum.boolean);
break;
+ case FR_TYPE_COMBO_IP_ADDR:
+ switch (value->vb_ip.af) {
+ case AF_INET:
+ goto ipv4addr;
+
+ case AF_INET6:
+ goto ipv6addr;
+
+ default:
+ break;
+ }
+
+ fr_strerror_const("Combo IP value missing af");
+ return 0;
+
+ case FR_TYPE_COMBO_IP_PREFIX:
+ switch (value->vb_ip.af) {
+ case AF_INET:
+ goto ipv4prefix;
+
+ case AF_INET6:
+ goto ipv6prefix;
+
+ default:
+ break;
+ }
+
+ fr_strerror_const("Combo IP value missing af");
+ return 0;
+
/*
* Already in network byte-order
*/
case FR_TYPE_OCTETS:
case FR_TYPE_STRING:
case FR_TYPE_SIZE:
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
goto unsupported;
}
* Already in network byte order
*/
case FR_TYPE_IPV4_ADDR:
+ ipv4addr:
dst->vb_ip = (fr_ipaddr_t){
.af = AF_INET,
.prefix = 32,
break;
case FR_TYPE_IPV4_PREFIX:
+ ipv4prefix:
dst->vb_ip = (fr_ipaddr_t){
.af = AF_INET,
};
break;
case FR_TYPE_IPV6_ADDR:
+ ipv6addr:
dst->vb_ip = (fr_ipaddr_t){
.af = AF_INET6,
.scope_id = 0,
break;
case FR_TYPE_IPV6_PREFIX:
+ ipv6prefix:
dst->vb_ip = (fr_ipaddr_t){
.af = AF_INET6,
.scope_id = 0,
FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *)&dst->vb_ip.addr.v6, &work_dbuff, len - 1);
break;
+ case FR_TYPE_COMBO_IP_ADDR:
+ if ((len >= network_min_size(FR_TYPE_IPV6_ADDR)) &&
+ (len <= network_max_size(FR_TYPE_IPV6_ADDR))) goto ipv6addr; /* scope is optional */
+ else if ((len >= network_min_size(FR_TYPE_IPV4_ADDR)) &&
+ (len <= network_max_size(FR_TYPE_IPV4_ADDR))) goto ipv4addr;
+ fr_strerror_const("Invalid combo ip address value");
+ return 0;
+
+ case FR_TYPE_COMBO_IP_PREFIX:
+ if ((len >= network_min_size(FR_TYPE_IPV6_PREFIX)) &&
+ (len <= network_max_size(FR_TYPE_IPV6_PREFIX))) goto ipv6prefix; /* scope is optional */
+ else if ((len >= network_min_size(FR_TYPE_IPV4_PREFIX)) &&
+ (len <= network_max_size(FR_TYPE_IPV4_PREFIX))) goto ipv4prefix;
+ fr_strerror_const("Invalid combo ip prefix value");
+ return 0;
+
case FR_TYPE_BOOL:
{
uint8_t val = 0;
break; /* Already dealt with */
case FR_TYPE_SIZE:
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
fr_strerror_printf("Cannot decode type \"%s\" - Is not a value",
fr_table_str_by_value(fr_value_box_type_table, type, "<INVALID>"));
break;
fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
fr_value_box_t const *src)
{
- switch (dst_type) {
- case FR_TYPE_FIXED_SIZE:
- break;
-
- default:
- if (!fr_cond_assert(false)) return -1;
- }
+ if (!fr_type_is_fixed_size(dst_type)) if (!fr_cond_assert(false)) return -1;
if (src->vb_length < network_min_size(dst_type)) {
fr_strerror_printf("Invalid cast from %s to %s. Source is length %zd is smaller than "
switch (src->type) {
case FR_TYPE_STRING:
- return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv,
+ return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv,
src->vb_strvalue, src->vb_length, '\0', src->tainted);
default:
switch (src->type) {
case FR_TYPE_STRING:
- return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv,
+ return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv,
src->vb_strvalue, src->vb_length, '\0', src->tainted);
default:
switch (src->type) {
case FR_TYPE_STRING:
- return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv,
+ return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv,
src->vb_strvalue, src->vb_length, '\0', src->tainted);
default:
switch (src->type) {
case FR_TYPE_STRING:
- return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv,
+ return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv,
src->vb_strvalue, src->vb_length, '\0', src->tainted);
default:
switch (src->type) {
case FR_TYPE_STRING:
- return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv,
+ return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv,
src->vb_strvalue, src->vb_length, '\0', src->tainted);
case FR_TYPE_OCTETS:
switch (src->type) {
case FR_TYPE_STRING:
- return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv,
+ return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv,
src->vb_strvalue, src->vb_length, '\0', src->tainted);
case FR_TYPE_OCTETS:
{
switch (src->type) {
case FR_TYPE_STRING:
- return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv,
+ return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv,
src->vb_strvalue, src->vb_length, '\0', src->tainted);
case FR_TYPE_OCTETS:
if (!fr_cond_assert(src != dst)) return -1;
if (!fr_cond_assert(src->type != FR_TYPE_NULL)) return -1;
- if (fr_dict_non_data_types[dst_type]) {
+ if (fr_type_is_non_leaf(dst_type)) {
fr_strerror_printf("Invalid cast from %s to %s. Can only cast simple data types",
fr_table_str_by_value(fr_value_box_type_table, src->type, "<INVALID>"),
fr_table_str_by_value(fr_value_box_type_table, dst_type, "<INVALID>"));
case FR_TYPE_IPV6_PREFIX:
return fr_value_box_cast_to_ipv6prefix(ctx, dst, dst_type, dst_enumv, src);
+ case FR_TYPE_COMBO_IP_ADDR:
+ case FR_TYPE_COMBO_IP_PREFIX:
+ break;
/*
* Need func
*/
case FR_TYPE_IFID:
- case FR_TYPE_COMBO_IP_ADDR:
- case FR_TYPE_COMBO_IP_PREFIX:
break;
case FR_TYPE_ETHERNET:
/*
* Deserialise a fr_value_box_t
*/
- if (src->type == FR_TYPE_STRING) return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv,
+ if (src->type == FR_TYPE_STRING) return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv,
src->vb_strvalue,
src->vb_length, '\0', src->tainted);
*/
int fr_value_unbox_ipaddr(fr_ipaddr_t *dst, fr_value_box_t *src)
{
- switch (src->type) {
- case FR_TYPE_IP:
- break;
-
- default:
+ if (!fr_type_is_ip(src->type)) {
fr_strerror_printf("Unboxing failed. Needed IPv4/6 addr/prefix, had type %s",
fr_table_str_by_value(fr_value_box_type_table, src->type, "?Unknown?"));
return -1;
* - -1 on parse error.
*/
int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst,
- fr_type_t *dst_type, fr_dict_attr_t const *dst_enumv,
+ fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
char const *in, ssize_t inlen, char quote, bool tainted)
{
size_t len;
ssize_t ret;
char buffer[256];
- if (!fr_cond_assert(*dst_type != FR_TYPE_NULL)) return -1;
+ if (!fr_cond_assert(dst_type != FR_TYPE_NULL)) return -1;
len = (inlen < 0) ? strlen(in) : (size_t)inlen;
/*
* Set size for all fixed length attributes.
*/
- ret = network_max_size(*dst_type);
+ ret = network_max_size(dst_type);
/*
* Lookup any names before continuing
* It's a variable ret src->dst_type so we just alloc a new buffer
* of size len and copy.
*/
- switch (*dst_type) {
+ switch (dst_type) {
case FR_TYPE_STRING:
{
char *buff;
case FR_TYPE_MAX:
case FR_TYPE_NULL:
fr_strerror_printf("Invalid dst_type %s",
- fr_table_str_by_value(fr_value_box_type_table, *dst_type, "<INVALID>"));
+ fr_table_str_by_value(fr_value_box_type_table, dst_type, "<INVALID>"));
return -1;
}
in = buffer;
}
- switch (*dst_type) {
+ switch (dst_type) {
case FR_TYPE_IPV4_ADDR:
case FR_TYPE_IPV4_PREFIX:
case FR_TYPE_IPV6_ADDR:
case FR_TYPE_INT16:
case FR_TYPE_INT32:
case FR_TYPE_INT64:
- if (fr_value_box_from_integer_str(dst, *dst_type, in) < 0) return -1;
+ if (fr_value_box_from_integer_str(dst, dst_type, in) < 0) return -1;
break;
case FR_TYPE_SIZE:
* and attribute as the original.
*/
case FR_TYPE_COMBO_IP_ADDR:
- {
if (fr_inet_pton(&dst->vb_ip, in, inlen, AF_UNSPEC, fr_hostname_lookups, true) < 0) return -1;
switch (dst->vb_ip.af) {
case AF_INET:
- *dst_type = FR_TYPE_IPV4_ADDR;
- ret = network_min_size(*dst_type);
+ ret = network_max_size(FR_TYPE_IPV4_ADDR);
break;
case AF_INET6:
- *dst_type = FR_TYPE_IPV6_ADDR;
- ret = network_max_size(*dst_type);
+ ret = network_max_size(FR_TYPE_IPV6_ADDR);
+ break;
+
+ default:
+ fr_strerror_printf("Bad address family %i", dst->vb_ip.af);
+ return -1;
+ }
+ break;
+
+ case FR_TYPE_COMBO_IP_PREFIX:
+ if (fr_inet_pton(&dst->vb_ip, in, inlen, AF_UNSPEC, fr_hostname_lookups, true) < 0) return -1;
+ switch (dst->vb_ip.af) {
+ case AF_INET:
+ ret = network_max_size(FR_TYPE_IPV4_PREFIX);
+ break;
+
+ case AF_INET6:
+ ret = network_max_size(FR_TYPE_IPV6_PREFIX);
break;
default:
fr_strerror_printf("Bad address family %i", dst->vb_ip.af);
return -1;
}
- }
break;
case FR_TYPE_BOOL:
}
break;
- case FR_TYPE_COMBO_IP_PREFIX:
- break;
-
case FR_TYPE_VALUE_BOX:
case FR_TYPE_VARIABLE_SIZE: /* Should have been dealt with above */
case FR_TYPE_STRUCTURAL: /* Listed again to suppress compiler warnings */
case FR_TYPE_VOID:
case FR_TYPE_MAX:
case FR_TYPE_NULL:
- fr_strerror_printf("Unknown attribute dst_type %d", *dst_type);
+ fr_strerror_printf("Unknown attribute dst_type %d", dst_type);
return -1;
}
finish:
dst->vb_length = ret;
- dst->type = *dst_type;
+ dst->type = dst_type;
dst->tainted = tainted;
/*
*/
case FR_TYPE_IPV4_ADDR:
case FR_TYPE_IPV6_ADDR:
+ case FR_TYPE_COMBO_IP_ADDR:
if (!fr_inet_ntop(buf, sizeof(buf), &data->vb_ip)) return 0;
FR_SBUFF_IN_STRCPY_RETURN(&our_out, buf);
break;
case FR_TYPE_IPV4_PREFIX:
case FR_TYPE_IPV6_PREFIX:
+ case FR_TYPE_COMBO_IP_PREFIX:
if (!fr_inet_ntop_prefix(buf, sizeof(buf), &data->vb_ip)) return 0;
FR_SBUFF_IN_STRCPY_RETURN(&our_out, buf);
break;
case FR_TYPE_STRUCT: /* Not a box type */
case FR_TYPE_VSA: /* Not a box type */
case FR_TYPE_VENDOR: /* Not a box type */
- case FR_TYPE_COMBO_IP_ADDR:
- case FR_TYPE_COMBO_IP_PREFIX:
case FR_TYPE_VALUE_BOX:
case FR_TYPE_VOID:
case FR_TYPE_MAX:
* @{
*/
int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst,
- fr_type_t *dst_type, fr_dict_attr_t const *dst_enumv,
+ fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
char const *src, ssize_t src_len, char quote, bool tainted)
- CC_HINT(nonnull(2,3,5));
+ CC_HINT(nonnull(2,5));
/** @} */
/** @name Work with lists of boxed values
talloc_set_type(e, rlm_csv_entry_t);
e->key = talloc_zero(e, fr_value_box_t);
- if (fr_value_box_from_str(e->key, e->key, &type, NULL, p, -1, 0, false) < 0) {
+ if (fr_value_box_from_str(e->key, e->key, type, NULL, p, -1, 0, false) < 0) {
cf_log_err(conf, "Failed parsing key field in file %s line %d - %s", inst->filename, lineno,
fr_strerror());
return false;
* Set the last entry to use 'e'
*/
e->key = talloc_zero(e, fr_value_box_t);
- if (fr_value_box_from_str(e->key, e->key, &type, NULL, p, -1, 0, false) < 0) {
+ if (fr_value_box_from_str(e->key, e->key, type, NULL, p, -1, 0, false) < 0) {
cf_log_err(conf, "Failed parsing key field in file %s line %d - %s", inst->filename, lineno,
fr_strerror());
fail:
fr_value_box_t box;
fr_type_t type = inst->field_types[i];
- if (fr_value_box_from_str(e, &box, &type, NULL, p, -1, 0, false) < 0) {
+ if (fr_value_box_from_str(e, &box, type, NULL, p, -1, 0, false) < 0) {
cf_log_err(conf, "Failed parsing field '%s' in file %s line %d - %s", inst->field_names[i],
inst->filename, lineno, fr_strerror());
goto fail;
if (inst->key) {
inst->key_data_type = tmpl_expanded_type(inst->key);
switch (inst->key_data_type) {
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
break;
case FR_TYPE_NULL:
*/
static int match_subword(rlm_isc_dhcp_tokenizer_t *state, char const *cmd, rlm_isc_dhcp_info_t *info)
{
- int ret, type;
+ int ret;
+ fr_type_t type;
int semicolon = NO_SEMICOLON;
bool multi = false;
char *p;
semicolon = MAYBE_SEMICOLON;
}
- type = fr_table_value_by_str(fr_value_box_type_table, type_name, -1);
- if (type < 0) {
+ type = fr_table_value_by_str(fr_value_box_type_table, type_name, FR_TYPE_NULL);
+ if (type == FR_TYPE_NULL) {
fr_strerror_printf("unknown data type '%.*s'",
(int) (next - cmd), cmd);
return -1; /* internal error */
*/
info->argv[info->argc] = talloc_zero(info, fr_value_box_t);
- ret = fr_value_box_from_str(info, info->argv[info->argc], (fr_type_t *) &type, NULL,
+ ret = fr_value_box_from_str(info, info->argv[info->argc], type, NULL,
state->token, state->token_len, 0, false);
if (ret < 0) return ret;
}
type = FR_TYPE_UINT32;
- ret = fr_value_box_from_str(NULL, &box, &type, NULL,
+ ret = fr_value_box_from_str(NULL, &box, type, NULL,
state->token, state->token_len, 0, false);
if (ret < 0) goto error;
case FR_TYPE_IPV6_ADDR:
case FR_TYPE_IPV4_PREFIX:
case FR_TYPE_IPV6_PREFIX:
+ case FR_TYPE_COMBO_IP_ADDR:
+ case FR_TYPE_COMBO_IP_PREFIX:
case FR_TYPE_IFID:
case FR_TYPE_TIME_DELTA:
{
lua_pushinteger(L, (lua_Integer)vp->vp_size);
break;
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
REDEBUG("Cannot convert %s to Lua type", fr_table_str_by_value(fr_value_box_type_table, vp->vp_type, "<INVALID>"));
return -1;
}
val = mrb_convert_type(mrb, to_cast, MRB_TT_FLOAT, "Float", "to_f");
break;
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
fr_assert(0);
return -1;
}
case FR_TYPE_IPV6_PREFIX:
case FR_TYPE_IPV4_ADDR:
case FR_TYPE_IPV4_PREFIX:
+ case FR_TYPE_COMBO_IP_ADDR:
+ case FR_TYPE_COMBO_IP_PREFIX:
case FR_TYPE_ETHERNET:
{
ssize_t slen;
}
break;
- case FR_TYPE_NON_VALUES:
+ case FR_TYPE_NON_LEAF:
fr_assert(0);
return -1;
}
/*
* Only leaf attributes can be tainted
*/
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
if (vp->vp_tainted) enc_byte |= FR_INTERNAL_FLAG_TAINTED;
break;
fr_dbuff_marker(&value_field, &value_dbuff);
switch (da->type) {
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
slen = fr_value_box_to_network(&value_dbuff, &vp->data);
if (slen < 0) return PAIR_ENCODE_FATAL_ERROR;
FR_PROTO_HEX_DUMP(fr_dbuff_start(&value_dbuff), slen, "value %s",
[FR_TYPE_IPV6_ADDR] = {16, 16},
[FR_TYPE_IPV6_PREFIX] = {2, 18},
[FR_TYPE_COMBO_IP_PREFIX] = {6, 18},
- [FR_TYPE_COMBO_IP_ADDR] = {4, 16},
+ [FR_TYPE_COMBO_IP_ADDR] = {4, 17},
[FR_TYPE_IFID] = {8, 8},
[FR_TYPE_ETHERNET] = {6, 6},
if (vp->da->flags.length) return vp->da->flags.length; /* Variable type with fixed length */
return vp->vp_length;
- default:
- return fr_radius_attr_sizes[vp->vp_type][0];
-
case FR_TYPE_STRUCTURAL:
fr_assert_fail(NULL);
return 0;
+
+ default:
+ return fr_radius_attr_sizes[vp->vp_type][0];
}
}
}
switch (parent->type) {
- case FR_TYPE_VALUES:
- break;
-
- case FR_TYPE_COMBO_IP_PREFIX:
- if (data_len == min) {
- child = fr_dict_attr_by_type(parent, FR_TYPE_IPV4_PREFIX);
- } else if (data_len == max) {
- child = fr_dict_attr_by_type(parent, FR_TYPE_IPV6_PREFIX);
- } else {
- FR_PROTO_TRACE("Combo attribute len %zu incorrect, must be %zu or %zu", data_len, min, max);
- goto raw;
- }
- if (!child) {
- FR_PROTO_TRACE("Missing type variant for combo attribute len %zu", data_len);
- goto raw;
- }
- parent = child; /* re-write it */
- break;
-
- case FR_TYPE_COMBO_IP_ADDR:
- if (data_len == min) {
- child = fr_dict_attr_by_type(parent, FR_TYPE_IPV4_ADDR);
- } else if (data_len == max) {
- child = fr_dict_attr_by_type(parent, FR_TYPE_IPV6_ADDR);
- } else {
- FR_PROTO_TRACE("Combo attribute len %zu incorrect, must be %zu or %zu", data_len, min, max);
- goto raw;
- }
- if (!child) {
- FR_PROTO_TRACE("Missing type variant for combo attribute len %zu", data_len);
- goto raw;
- }
- parent = child; /* re-write it */
+ case FR_TYPE_LEAF:
break;
case FR_TYPE_VSA:
return PAIR_ENCODE_FATAL_ERROR;
}
- switch (da->type) {
- case FR_TYPE_STRUCTURAL:
+ if (fr_type_is_structural(da->type)) {
fr_strerror_printf("%s: Called with structural type %s", __FUNCTION__,
fr_table_str_by_value(fr_value_box_type_table, da_stack->da[depth]->type, "?Unknown?"));
return PAIR_ENCODE_FATAL_ERROR;
-
- default:
- break;
}
/*
return PAIR_ENCODE_FATAL_ERROR;
case FR_TYPE_STRUCT:
- case FR_TYPE_VALUES:
+ case FR_TYPE_LEAF:
if (((fr_dict_vendor_num_by_da(da_stack->da[depth]) == 0) && (da_stack->da[depth]->attr == 0)) ||
(da_stack->da[depth]->attr > 255)) {
fr_strerror_printf("%s: Called with non-standard attribute %u", __FUNCTION__,