}
-static VALUE_PAIR *fr_pair_from_octets(TALLOC_CTX *ctx, VALUE_PAIR *vp, DICT_ATTR const *da)
-{
- ssize_t len;
- VALUE_PAIR *vp2;
-
- len = data2vp(ctx, NULL, NULL, NULL, da,
- vp->vp_octets, vp->vp_length, vp->vp_length,
- &vp2);
- if (len <= 0) return vp; /* it's really unknown */
-
- if (vp2->da->flags.is_unknown) {
- fr_pair_list_free(&vp2);
- return vp;
- }
-
- /*
- * Didn't parse all of it. Return the "unknown" one.
- *
- * FIXME: it COULD have parsed 2 attributes and
- * then not the third, so returning 2 "knowns"
- * and 1 "unknown" is likely preferable.
- */
- if ((size_t) len < vp->vp_length) {
- fr_pair_list_free(&vp2);
- return vp;
- }
-
- fr_pair_list_free(&vp);
- return vp2;
-}
-
/** Create a valuepair from an ASCII attribute and value
*
* Where the attribute name is in the form:
char const *attribute, char const *value,
FR_TOKEN op)
{
- VALUE_PAIR *vp;
+ VALUE_PAIR *vp, *vp2;
DICT_ATTR const *da;
uint8_t *data;
size_t size;
+ ssize_t len;
+
+ vp = fr_pair_alloc(ctx);
+ if (!vp) return NULL;
- da = dict_unknown_afrom_str(ctx, attribute);
- if (!da) return NULL;
+ da = dict_unknown_afrom_str(vp, attribute);
+ if (!da) {
+ talloc_free(vp);
+ return NULL;
+ }
+
+ /*
+ * No value. Nothing more to do.
+ */
+ if (!value) return vp;
/*
* Unknown attributes MUST be of type 'octets'
*/
- if (value && (strncasecmp(value, "0x", 2) != 0)) {
+ if (strncasecmp(value, "0x", 2) != 0) {
fr_strerror_printf("Unknown attribute \"%s\" requires a hex "
"string, not \"%s\"", attribute, value);
-
- dict_attr_free(&da);
+ talloc_free(vp);
return NULL;
}
/*
- * We've now parsed the attribute properly, Let's create
- * it. This next stop also looks the attribute up in the
- * dictionary, and creates the appropriate type for it.
+ * Convert the hex data to binary.
*/
- vp = fr_pair_afrom_da(ctx, da);
- if (!vp) {
- dict_attr_free(&da);
- return NULL;
- }
-
- vp->op = (op == 0) ? T_OP_EQ : op;
-
- if (!value) return vp;
-
size = strlen(value + 2);
+
vp->vp_length = size >> 1;
- data = talloc_array(vp, uint8_t, vp->vp_length);
+ vp->vp_octets = data = talloc_array(vp, uint8_t, vp->vp_length);
+ vp->type = VT_DATA;
+ vp->op = (op == 0) ? T_OP_EQ : op;
+ vp->da = da;
if (fr_hex2bin(data, vp->vp_length, value + 2, size) != vp->vp_length) {
fr_strerror_printf("Invalid hex string");
return NULL;
}
- vp->vp_octets = data;
- vp->type = VT_DATA;
+ /*
+ * It's still unknown, return it as-is.
+ */
+ da = dict_attrbyvalue(vp->da->attr, vp->da->vendor);
+ if (!da) return vp;
/*
- * We were asked to parse "Attr-26 = 0xabcdef"
+ * It MIGHT be known. See if we can decode the raw data
+ * into a valid attribute.
+ */
+ len = data2vp(ctx, NULL, NULL, NULL, da,
+ vp->vp_octets, vp->vp_length, vp->vp_length,
+ &vp2);
+ if (len <= 0) return vp;
+
+ /*
+ * It's still unknown. Return the original VP.
+ */
+ if (vp2->da->flags.is_unknown) {
+ fr_pair_list_free(&vp2);
+ return vp;
+ }
+
+ /*
+ * Didn't parse all of it. Return the "unknown" one.
*
- * If we have a dictionary entry for it, try to
- * parse it as raw data.
+ * FIXME: it COULD have parsed 2 attributes and
+ * then not the third, so returning 2 "knowns"
+ * and 1 "unknown" is likely preferable.
*/
- da = dict_attrbyvalue(vp->da->attr, vp->da->vendor);
- if (da) {
- return fr_pair_from_octets(ctx, vp, da);
+ if ((size_t) len < vp->vp_length) {
+ fr_pair_list_free(&vp2);
+ return vp;
}
- return vp;
+ fr_pair_list_free(&vp);
+ return vp2;
}