The cursors are mostly legacy since we moved to dlists, and for efficient lookups we cannot modify pair lists using dcursors as we need to keep the attr tree in sync.
if (fr_debug_lvl > 1) fr_dhcpv4_print_hex(stdout, reply->data, reply->data_len);
fr_dcursor_init(&cursor, &reply_vps);
- if (fr_dhcpv4_decode(reply, reply->data, reply->data_len, &cursor, &reply->code) < 0) {
+ if (fr_dhcpv4_decode(reply, &reply_vps, reply->data, reply->data_len, &reply->code) < 0) {
ERROR("Failed decoding reply");
return NULL;
}
* Decode to produce fr_pair_ts from the default field
*/
if (fr_debug_lvl) {
- fr_dcursor_t cursor;
- fr_dcursor_init(&cursor, &packet_vps);
-
if (fr_debug_lvl > 1) fr_dhcpv4_print_hex(stdout, packet->data, packet->data_len);
- fr_dhcpv4_decode(packet, packet->data, packet->data_len, &cursor, &packet->code);
+ fr_dhcpv4_decode(packet, &reply_vps, packet->data, packet->data_len, &packet->code);
dhcp_packet_debug(packet, &packet_vps, false);
}
}
if (reply) {
- fr_dcursor_t cursor;
- fr_dcursor_init(&cursor, &reply_vps);
- if (fr_dhcpv4_decode(reply, reply->data, reply->data_len, &cursor, &reply->code) < 0) {
+ if (fr_dhcpv4_decode(reply, &reply_vps, reply->data, reply->data_len, &reply->code) < 0) {
ERROR("Failed decoding packet");
ret = -1;
}
/*
* If this fails, we're out of memory.
*/
- if (fr_radius_packet_decode(request->reply, &request->reply_pairs,
- request->packet, RADIUS_MAX_ATTRIBUTES, false, secret) != 0) {
+ if (fr_radius_packet_decode(request, &request->reply_pairs,
+ request->reply, request->packet, RADIUS_MAX_ATTRIBUTES, false, secret) != 0) {
REDEBUG("Reply decode failed");
stats.lost++;
goto packet_done;
FILE *log_fp = fr_log_fp;
fr_log_fp = NULL;
- ret = fr_radius_packet_decode(packet, &decoded, original ? original->expect : NULL,
+ ret = fr_radius_packet_decode(packet, &decoded, packet, original ? original->expect : NULL,
RADIUS_MAX_ATTRIBUTES, false, conf->radius_secret);
fr_log_fp = log_fp;
if (ret != 0) {
FILE *log_fp = fr_log_fp;
fr_log_fp = NULL;
- ret = fr_radius_packet_decode(packet, &decoded, NULL,
+ ret = fr_radius_packet_decode(packet, &decoded, packet, NULL,
RADIUS_MAX_ATTRIBUTES, false, conf->radius_secret);
fr_log_fp = log_fp;
talloc_free(packet);
continue;
}
- if (fr_radius_packet_decode(reply, &reply_vps, packet,
+ if (fr_radius_packet_decode(reply, &reply_vps, reply, packet,
RADIUS_MAX_ATTRIBUTES, false, conf->secret) < 0) {
fr_perror("Failed decoding reply");
goto recv_error;
char *data, size_t data_used, char *in, size_t inlen)
{
fr_test_point_pair_decode_t *tp = NULL;
- fr_dcursor_t cursor;
void *decode_ctx = NULL;
char *p, *end;
uint8_t *to_dec;
* Run the input data through the test
* point to produce fr_pair_ts.
*/
- fr_dcursor_init(&cursor, &head);
while (to_dec < to_dec_end) {
- slen = tp->func(cc->tmp_ctx, &cursor, cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict,
+ slen = tp->func(cc->tmp_ctx, &head, cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict,
(uint8_t *)to_dec, (to_dec_end - to_dec), decode_ctx);
cc->last_ret = slen;
if (slen <= 0) {
/* Add the channel binding attributes to the fake packet */
data_len = chbind_get_data(chbind->request, CHBIND_NSID_RADIUS, &attr_data);
if (data_len) {
- fr_dcursor_t cursor;
-
fr_assert(data_len <= talloc_array_length((uint8_t const *) chbind->request));
- fr_dcursor_init(&cursor, &fake->request_pairs);
while (data_len > 0) {
ssize_t attr_len;
- attr_len = fr_radius_decode_pair(fake->request_ctx, &cursor, dict_radius,
+ attr_len = fr_radius_decode_pair(fake->request_ctx, &fake->request_pairs, dict_radius,
attr_data, data_len, &packet_ctx);
if (attr_len <= 0) {
/*
/*
* decode.c
*/
-ssize_t fr_aka_sim_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_aka_sim_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, void *decode_ctx);
-int fr_aka_sim_decode(request_t *request, fr_dcursor_t *decoded, fr_dict_t const *dict,
- uint8_t const *data, size_t data_len, fr_aka_sim_ctx_t *ctx);
+int fr_aka_sim_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
+ uint8_t const *data, size_t data_len, fr_aka_sim_ctx_t *decode_ctx);
/*
* encode.c
* of 32 bits, and includes the Type/Length fields.
*/
-static ssize_t sim_decode_pair_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent,
+static ssize_t sim_decode_pair_internal(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
uint8_t const *data, size_t data_len, void *decode_ctx);
-static ssize_t sim_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent,
+static ssize_t sim_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
uint8_t const *data, size_t const attr_len, size_t const data_len,
void *decode_ctx);
return len / element_len;
}
-static ssize_t sim_decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+static ssize_t sim_decode_array(TALLOC_CTX *ctx, fr_pair_list_t *out,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const attr_len, UNUSED size_t data_len,
void *decode_ctx)
if (elements < 0) return elements;
for (i = 0; i < elements; i++) {
- ret = sim_decode_pair_value(ctx, cursor, parent, p, element_len, end - p, decode_ctx);
+ ret = sim_decode_pair_value(ctx, out, parent, p, element_len, end - p, decode_ctx);
if (ret < 0) return ret;
p += ret;
/** Break apart a TLV attribute into individual attributes
*
* @param[in] ctx to allocate new attributes in.
- * @param[in] cursor to add new attributes to.
+ * @param[in] out to add new attributes to.
* @param[in] parent the current attribute TLV attribute we're processing.
* @param[in] data to parse. Points to the data field of the attribute.
* @param[in] attr_len length of the TLV attribute.
* - Length on success.
* - < 0 on malformed attribute.
*/
-static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const attr_len, size_t data_len,
void *decode_ctx)
uint8_t *decr = NULL;
ssize_t decr_len;
fr_dict_attr_t const *child;
- fr_pair_list_t head;
- fr_dcursor_t tlv_cursor;
+ fr_pair_list_t tlv_tmp;
ssize_t ret;
- fr_pair_list_init(&head);
+ fr_pair_list_init(&tlv_tmp);
if (data_len < 2) {
fr_strerror_printf("%s: Insufficient data", __FUNCTION__);
return -1; /* minimum attr size */
/*
* Record where we were in the list when packet_ctx function was called
*/
- fr_dcursor_init(&tlv_cursor, &head);
while ((size_t)(end - p) >= sizeof(uint32_t)) {
uint8_t sim_at = p[0];
size_t sim_at_len = ((size_t)p[1]) << 2;
error:
talloc_free(decr);
- fr_pair_list_free(&head);
+ fr_pair_list_free(&tlv_tmp);
return -1;
}
}
FR_PROTO_TRACE("decode context changed %s -> %s", parent->name, child->name);
- ret = sim_decode_pair_value(ctx, &tlv_cursor, child, p + 2, sim_at_len - 2, (end - p) - 2,
+ ret = sim_decode_pair_value(ctx, &tlv_tmp, child, p + 2, sim_at_len - 2, (end - p) - 2,
decode_ctx);
if (ret < 0) goto error;
p += sim_at_len;
}
- fr_dcursor_head(&tlv_cursor);
- fr_dcursor_tail(cursor);
- fr_dcursor_merge(cursor, &tlv_cursor); /* Wind to the end of the new pairs */
+ fr_pair_list_append(out, &tlv_tmp);
talloc_free(decr);
return attr_len;
/** Create any kind of VP from the attribute contents
*
* @param[in] ctx to allocate new attributes in.
- * @param[in] cursor to addd new attributes to.
+ * @param[in] out to addd new attributes to.
* @param[in] parent the current attribute we're processing.
* @param[in] data to parse. Points to the data field of the attribute.
* @param[in] attr_len length of the attribute being parsed.
* - Length on success.
* - -1 on failure.
*/
-static ssize_t sim_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent,
+static ssize_t sim_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
uint8_t const *data, size_t const attr_len, size_t const data_len,
void *decode_ctx)
{
* attribute, OR they've already been grouped
* into a contiguous memory buffer.
*/
- return sim_decode_tlv(ctx, cursor, parent, p, attr_len, data_len, decode_ctx);
+ return sim_decode_tlv(ctx, out, parent, p, attr_len, data_len, decode_ctx);
default:
raw:
done:
vp->type = VT_DATA;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return attr_len;
}
/** Decode SIM/AKA/AKA' attributes
*
* @param[in] ctx to allocate attributes in.
- * @param[in] cursor where to insert the attributes.
+ * @param[in] out where to insert the attributes.
* @param[in] parent of current attribute being decoded.
* @param[in] data data to parse.
* @param[in] data_len length of data. For top level attributes packet_ctx must be the length
* - The number of bytes parsed.
* - -1 on error.
*/
-static ssize_t sim_decode_pair_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent,
+static ssize_t sim_decode_pair_internal(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
uint8_t const *data, size_t data_len, void *decode_ctx)
{
uint8_t sim_at;
FR_PROTO_TRACE("decode context changed %s -> %s", da->parent->name, da->name);
if (da->flags.array) {
- ret = sim_decode_array(ctx, cursor, da, data + 2, sim_at_len - 2, data_len - 2, decode_ctx);
+ ret = sim_decode_array(ctx, out, da, data + 2, sim_at_len - 2, data_len - 2, decode_ctx);
} else {
- ret = sim_decode_pair_value(ctx, cursor, da, data + 2, sim_at_len - 2, data_len - 2, decode_ctx);
+ ret = sim_decode_pair_value(ctx, out, da, data + 2, sim_at_len - 2, data_len - 2, decode_ctx);
}
if (ret < 0) return ret;
/** Decode SIM/AKA/AKA' attributes
*
* @param[in] ctx to allocate attributes in.
- * @param[in] cursor where to insert the attributes.
+ * @param[in] out where to insert the attributes.
* @param[in] dict for looking up attributes.
* @param[in] data data to parse.
* @param[in] data_len length of data. For top level attributes packet_ctx must be the length
* - The number of bytes parsed.
* - -1 on error.
*/
-ssize_t fr_aka_sim_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_aka_sim_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, void *decode_ctx)
{
- return sim_decode_pair_internal(ctx, cursor, fr_dict_root(dict), data, data_len, decode_ctx);
+ return sim_decode_pair_internal(ctx, out, fr_dict_root(dict), data, data_len, decode_ctx);
}
/** Decode SIM/AKA/AKA' specific packet data
*
* The first byte of the data pointer should be the subtype.
*
- * @param[in] request the current request.
- * @param[in] decoded where to write decoded attributes.
+ * @param[in] ctx where to allocate the pairs.
+ * @param[in] out where to write out attributes.
* @param[in] dict for looking up attributes.
* @param[in] data to convert to pairs.
* @param[in] data_len length of data to convert.
* - 0 on success.
* - -1 on failure.
*/
-int fr_aka_sim_decode(request_t *request, fr_dcursor_t *decoded, fr_dict_t const *dict,
- uint8_t const *data, size_t data_len, fr_aka_sim_ctx_t *decode_ctx)
+int fr_aka_sim_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
+ uint8_t const *data, size_t data_len, fr_aka_sim_ctx_t *decode_ctx)
{
ssize_t ret;
uint8_t const *p = data;
uint8_t const *end = p + data_len;
- /*
- * Move the cursor to the end, so we know if
- * any additional attributes were added.
- */
- fr_dcursor_tail(decoded);
-
/*
* We need at least enough data for the subtype
* and reserved bytes.
* in the SIM/AKA/AKA' dict.
*/
while (p < end) {
- ret = fr_aka_sim_decode_pair(request->request_ctx, decoded, dict, p, end - p, decode_ctx);
+ ret = fr_aka_sim_decode_pair(ctx, out, dict, p, end - p, decode_ctx);
if (ret <= 0) {
- RPEDEBUG("Failed decoding AT");
+ fr_strerror_const_push("Failed decoding AT");
error:
- fr_dcursor_free_list(decoded); /* Free any attributes we added */
+ fr_pair_list_free(out); /* Free any attributes we added */
return -1;
}
{
fr_pair_t *vp;
- vp = fr_pair_afrom_child_num(request->request_ctx, fr_dict_root(dict), FR_SUBTYPE);
+ vp = fr_pair_afrom_child_num(ctx, fr_dict_root(dict), FR_SUBTYPE);
if (!vp) {
fr_strerror_const("Failed allocating subtype attribute");
goto error;
}
vp->vp_uint32 = data[0];
- fr_dcursor_append(decoded, vp);
+ fr_pair_append(out, vp);
}
return 0;
decode_ctx.hmac_extra_len = mod_session->response_hmac_extra_len;
decode_ctx.eap_packet = eap_session->this_round->response;
- ret = fr_aka_sim_decode(request,
- &cursor,
+ ret = fr_aka_sim_decode(request->request_ctx,
+ &request->request_pairs,
dict_eap_aka_sim,
eap_session->this_round->response->type.data,
eap_session->this_round->response->type.length,
* If this top level fr_pair_t is a TLV, multiple child attributes may also be decoded.
*
* @param[in] ctx to allocate new pairs in.
- * @param[in] cursor to insert new pairs into.
+ * @param[in] out to insert new pairs into.
* @param[in] dict to use to lookup attributes.
* @param[in] data to decode.
* @param[in] data_len The length of the incoming data.
* - <= 0 on error. May be the offset (as a negative value) where the error occurred.
* - > 0 on success. How many bytes were decoded.
*/
-typedef ssize_t (*fr_pair_decode_t)(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+typedef ssize_t (*fr_pair_decode_t)(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, void *decode_ctx);
-int fr_pair_decode_value_box_list(TALLOC_CTX *ctx, fr_dcursor_t *out,
+int fr_pair_decode_value_box_list(TALLOC_CTX *ctx, fr_pair_list_t *out,
request_t *request, void *decode_ctx, fr_pair_decode_t decode,
fr_value_box_list_t *in);
size_t data_len;
fr_dbuff_t dbuff;
fr_pair_list_t tmp;
- fr_dcursor_t cursor;
/*
* Extract the session-state list from the ticket.
}
fr_pair_list_init(&tmp);
- fr_dcursor_init(&cursor, &tmp);
fr_dbuff_init(&dbuff, data, data_len);
RHEXDUMP4(fr_dbuff_start(&dbuff), fr_dbuff_len(&dbuff), "session application data");
* or disallow session resumption.
*/
while (fr_dbuff_remaining(&dbuff) > 0) {
- if (fr_internal_decode_pair_dbuff(request->session_state_ctx, &cursor,
+ if (fr_internal_decode_pair_dbuff(request->session_state_ctx, &tmp,
request->dict, &dbuff, NULL) < 0) {
fr_pair_list_free(&tmp);
RPEDEBUG("Failed decoding session-state");
{
int decoded;
fr_value_box_t *vb;
- fr_pair_list_t head;
- fr_dcursor_t cursor;
void *decode_ctx = NULL;
fr_test_point_pair_decode_t const *tp_decode;
}
}
- fr_pair_list_init(&head);
- fr_dcursor_init(&cursor, &head);
-
- decoded = fr_pair_decode_value_box_list(request->request_ctx, &cursor, request, decode_ctx, tp_decode->func, in);
+ decoded = fr_pair_decode_value_box_list(request->request_ctx, &request->request_pairs,
+ request, decode_ctx, tp_decode->func, in);
if (decoded <= 0) {
talloc_free(decode_ctx);
RPERROR("Protocol decoding failed");
return XLAT_ACTION_FAIL;
}
- /*
- * Append the decoded options to the request list.
- */
- fr_pair_list_append(&request->request_pairs, &head);
-
/*
* Create a value box to hold the decoded count, and add
* it to the output list.
* - <= 0 on error. May be the offset (as a negative value) where the error occurred.
* - > 0 on success. How many bytes were decoded.
*/
-static ssize_t fr_pair_decode_multi(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_dict_t const *dict,
+static ssize_t fr_pair_decode_multi(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_t decode)
{
uint8_t const *p, *end;
- fr_pair_list_t head;
- fr_dcursor_t cursor;
+ fr_pair_list_t tmp;
/*
* Catch idiocies.
*/
if (data_len == 0) return 0;
- fr_pair_list_init(&head);
- fr_dcursor_init(&cursor, &head);
+ fr_pair_list_init(&tmp);
p = data;
end = data + data_len;
while (p < end) {
ssize_t len;
- len = decode(ctx, &cursor, dict, p, end - p, decode_ctx);
+ len = decode(ctx, &tmp, dict, p, end - p, decode_ctx);
if (len <= 0) {
- fr_pair_list_free(&head);
+ fr_pair_list_free(&tmp);
return len - (p - data);
}
p += len;
/*
* Add the pairs to the cursor
*/
- fr_dcursor_head(&cursor);
- fr_dcursor_merge(out, &cursor);
+ fr_pair_list_append(out, &tmp);
return data_len;
}
* - <= 0 on error. May be the offset (as a negative value) where the error occurred.
* - > 0 on success. How many value boxes were decoded
*/
-int fr_pair_decode_value_box_list(TALLOC_CTX *ctx, fr_dcursor_t *out,
+int fr_pair_decode_value_box_list(TALLOC_CTX *ctx, fr_pair_list_t *out,
request_t *request, void *decode_ctx, fr_pair_decode_t decode,
fr_value_box_list_t *in)
{
fr_value_box_t *vb = NULL;
fr_pair_t *vp = NULL;
fr_pair_list_t head;
- fr_dcursor_t cursor;
fr_pair_list_init(&head);
while ((vb = fr_dlist_next(in, vb))) {
ssize_t len;
- fr_pair_list_t vps;
if (vb->type != FR_TYPE_OCTETS) {
RWDEBUG("Skipping value \"%pV\", expected value of type %s, got type %s",
continue;
}
- fr_pair_list_init(&vps);
- fr_dcursor_init(&cursor, &vps);
-
- len = fr_pair_decode_multi(ctx, &cursor, request->dict,
+ len = fr_pair_decode_multi(ctx, &head, request->dict,
vb->vb_octets, vb->vb_length, decode_ctx, decode);
if (len <= 0) {
fr_pair_list_free(&head);
return -decoded;
}
- fr_pair_list_append(&head, &vps);
decoded++; /* one more VB, but there may be many pairs in the decoded vps. */
}
decoded = fr_pair_list_len(&head);
- fr_dcursor_init(&cursor, &head);
- fr_dcursor_merge(out, &cursor);
+ fr_pair_list_append(out, &head);
return decoded;
}
/** Convert a STRUCT to one or more VPs
*
*/
-ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out,
fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len,
bool nested, void *decode_ctx,
fr_decode_value_t decode_value, fr_decode_value_t decode_tlv)
unsigned int child_num;
uint8_t const *p = data, *end = data + data_len;
fr_dict_attr_t const *child;
- fr_pair_list_t head;
- fr_dcursor_t child_cursor;
+ fr_pair_list_t child_list_head;
+ fr_pair_list_t *child_list;
fr_pair_t *vp, *key_vp, *struct_vp = NULL;
unsigned int offset = 0;
TALLOC_CTX *child_ctx;
* Start a child list.
*/
if (!nested) {
- fr_pair_list_init(&head);
- fr_dcursor_init(&child_cursor, &head);
+ fr_pair_list_init(&child_list_head);
+ child_list = &child_list_head;
child_ctx = ctx;
} else {
fr_assert(parent->type == FR_TYPE_STRUCT);
return -1;
}
- fr_pair_list_init(&head); /* still used elsewhere */
- fr_dcursor_init(&child_cursor, &struct_vp->vp_group);
+ fr_pair_list_init(&child_list_head); /* still used elsewhere */
+ child_list = &struct_vp->vp_group;
child_ctx = struct_vp;
}
child_num = 1;
vp->type = VT_DATA;
vp->vp_tainted = true;
- fr_dcursor_append(&child_cursor, vp);
+ fr_pair_append(child_list, vp);
p += (num_bits >> 3); /* go to the LAST bit, not the byte AFTER the last bit */
offset = num_bits & 0x07;
child_num++;
* Decode EVERYTHING as a TLV.
*/
while (p < end) {
- slen = decode_tlv(child_ctx, &child_cursor, fr_dict_by_da(child), child, p, end - p, decode_ctx);
+ slen = decode_tlv(child_ctx, child_list, fr_dict_by_da(child), child, p, end - p, decode_ctx);
if (slen < 0) {
FR_PROTO_TRACE("failed decoding TLV?");
goto unknown;
if (decode_value) {
ssize_t slen;
- slen = decode_value(child_ctx, &child_cursor, fr_dict_by_da(child), child, p, child_length, decode_ctx);
+ slen = decode_value(child_ctx, child_list, fr_dict_by_da(child), child, p, child_length, decode_ctx);
if (slen < 0) {
FR_PROTO_TRACE("Failed decoding value");
goto unknown;
p += slen; /* not always the same as child->flags.length */
child_num++; /* go to the next child */
- if (fr_dict_attr_is_key_field(child)) key_vp = fr_dcursor_tail(&child_cursor);
+ if (fr_dict_attr_is_key_field(child)) key_vp = fr_pair_list_tail(child_list);
continue;
}
if (nested) {
TALLOC_FREE(struct_vp);
} else {
- fr_pair_list_free(&head);
+ fr_pair_list_free(child_list);
}
vp = fr_raw_from_network(ctx, parent, data, data_len);
/*
* And append this one VP to the output cursor.
*/
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return data_len;
}
vp->type = VT_DATA;
vp->vp_tainted = true;
- fr_dcursor_append(&child_cursor, vp);
+ fr_pair_append(child_list, vp);
if (fr_dict_attr_is_key_field(vp->da)) key_vp = vp;
goto oom;
}
- fr_dcursor_append(&child_cursor, vp);
+ fr_pair_append(child_list, vp);
p = end;
} else {
fr_assert(child->type == FR_TYPE_STRUCT);
- slen = fr_struct_from_network(child_ctx, &child_cursor, child, p, end - p, nested,
+ slen = fr_struct_from_network(child_ctx, child_list, child, p, end - p, nested,
decode_ctx, decode_value, decode_tlv);
if (slen <= 0) {
FR_PROTO_TRACE("substruct %s decoding failed", child->name);
done:
if (!nested) {
- fr_dcursor_head(&child_cursor);
- fr_dcursor_tail(cursor);
- fr_dcursor_merge(cursor, &child_cursor); /* Wind to the end of the new pairs */
+ fr_pair_list_head(child_list);
+ fr_pair_list_append(out, child_list); /* Wind to the end of the new pairs */
} else {
fr_assert(struct_vp != NULL);
- fr_dcursor_append(cursor, struct_vp);
+ fr_pair_append(out, struct_vp);
}
FR_PROTO_TRACE("used %zd bytes", data_len);
extern "C" {
#endif
-typedef ssize_t (*fr_decode_value_t)(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+typedef ssize_t (*fr_decode_value_t)(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx);
-ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out,
fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len,
bool nested, void *decode_ctx,
fr_decode_value_t decode_value, fr_decode_value_t decode_tlv) CC_HINT(nonnull(2,3,4));
typedef ssize_t (*fr_encode_dbuff_t)(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth,
fr_dcursor_t *cursor, void *encode_ctx);
-
+
ssize_t fr_struct_to_network(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth,
fr_dcursor_t *cursor, void *encode_ctx,
fr_encode_dbuff_t encode_value, fr_encode_dbuff_t encode_tlv) CC_HINT(nonnull(1,2,4));
*/
request->dict = dict_arp;
- if (fr_arp_decode(request->request_ctx, data, data_len, &request->request_pairs) < 0) {
+ if (fr_arp_decode(request->request_ctx, &request->request_pairs, data, data_len) < 0) {
RPEDEBUG("Failed decoding packet");
return -1;
}
fr_io_address_t const *address = track->address;
RADCLIENT const *client;
fr_radius_packet_t *packet = request->packet;
- fr_dcursor_t cursor;
/*
* Set the request dictionary so that we can do
* That MUST be set and checked in the underlying
* transport, via a call to fr_dhcpv4_ok().
*/
- fr_dcursor_init(&cursor, &request->request_pairs);
- if (fr_dhcpv4_decode(request->request_ctx, packet->data, packet->data_len, &cursor, &packet->code) < 0) {
+ if (fr_dhcpv4_decode(request->request_ctx, &request->request_pairs,
+ packet->data, packet->data_len, &packet->code) < 0) {
RPEDEBUG("Failed decoding packet");
return -1;
}
fr_io_address_t const *address = track->address;
RADCLIENT const *client;
fr_radius_packet_t *packet = request->packet;
- fr_dcursor_t cursor;
/*
* Set the request dictionary so that we can do
* That MUST be set and checked in the underlying
* transport, via a call to fr_dhcpv6_ok().
*/
- fr_dcursor_init(&cursor, &request->request_pairs);
- if (fr_dhcpv6_decode(request->request_ctx, packet->data, packet->data_len, &cursor) < 0) {
+ if (fr_dhcpv6_decode(request->request_ctx, &request->request_pairs, packet->data, packet->data_len) < 0) {
RPEDEBUG("Failed decoding packet");
return -1;
}
fr_io_address_t const *address = track->address;
RADCLIENT const *client;
fr_dns_packet_t const *packet = (fr_dns_packet_t const *) data;
- fr_dcursor_t cursor;
- fr_dns_ctx_t packet_ctx;
+ fr_dns_ctx_t packet_ctx;
/*
* Set the request dictionary so that we can do
client = address->radclient;
/*
- * @todo -
+ * @todo -
*/
request->packet->code = packet->opcode;
request->packet->id = (data[0] << 8) | data[1];
* That MUST be set and checked in the underlying
* transport, via a call to fr_dns_ok().
*/
- fr_dcursor_init(&cursor, &request->request_pairs);
- if (fr_dns_decode(request->request_ctx, request->packet->data, request->packet->data_len, &cursor, &packet_ctx) < 0) {
+ if (fr_dns_decode(request->request_ctx, &request->request_pairs,
+ request->packet->data, request->packet->data_len, &packet_ctx) < 0) {
talloc_free(packet_ctx.tmp_ctx);
RPEDEBUG("Failed decoding packet");
return -1;
fr_io_track_t const *track = talloc_get_type_abort_const(request->async->packet_ctx, fr_io_track_t);
fr_io_address_t const *address = track->address;
RADCLIENT const *client;
- fr_dcursor_t cursor;
fr_assert(data[0] < FR_RADIUS_CODE_MAX);
* That MUST be set and checked in the underlying
* transport, via a call to fr_radius_ok().
*/
- fr_dcursor_init(&cursor, &request->request_pairs);
- if (fr_radius_decode(request->request_ctx, request->packet->data, request->packet->data_len,
- NULL, client->secret, talloc_array_length(client->secret) - 1,
- &cursor) < 0) {
+ if (fr_radius_decode(request->request_ctx, &request->request_pairs,
+ request->packet->data, request->packet->data_len, NULL,
+ client->secret, talloc_array_length(client->secret) - 1) < 0) {
RPEDEBUG("Failed decoding packet");
return -1;
}
if ((request->packet->code == FR_RADIUS_CODE_ACCESS_REQUEST) &&
fr_pair_find_by_da(&request->request_pairs, attr_state, 0)) {
request->async->sequence = 1;
- }
+ }
if (!inst->io.app_io->decode) return 0;
fr_io_address_t const *address = track->address;
RADCLIENT const *client;
fr_tacacs_packet_t const *pkt = (fr_tacacs_packet_t const *)data;
- fr_dcursor_t cursor;
RHEXDUMP3(data, data_len, "proto_tacacs decode packet");
* That MUST be set and checked in the underlying
* transport, via a call to ???
*/
- fr_dcursor_init(&cursor, &request->request_pairs);
- if (fr_tacacs_decode(request->request_ctx, request->packet->data, request->packet->data_len,
- NULL, client->secret, talloc_array_length(client->secret) - 1,
- &cursor) < 0) {
+ if (fr_tacacs_decode(request->request_ctx, &request->request_pairs,
+ request->packet->data, request->packet->data_len,
+ NULL, client->secret, talloc_array_length(client->secret) - 1) < 0) {
RPEDEBUG("Failed decoding packet");
return -1;
}
fr_io_address_t const *address = track->address;
RADCLIENT const *client;
fr_radius_packet_t *packet = request->packet;
- fr_dcursor_t cursor;
fr_assert(data[0] < FR_VMPS_CODE_MAX);
* That MUST be set and checked in the underlying
* transport, via a call to fr_vmps_ok().
*/
- fr_dcursor_init(&cursor, &request->request_pairs);
- if (fr_vmps_decode(request->request_ctx, packet->data, packet->data_len, &cursor, &packet->code) < 0) {
+ if (fr_vmps_decode(request->request_ctx, &request->request_pairs,
+ packet->data, packet->data_len, &packet->code) < 0) {
RPEDEBUG("Failed decoding packet");
return -1;
}
decode_fail_t reason;
uint8_t code;
uint8_t original[RADIUS_HEADER_LENGTH];
- fr_dcursor_t cursor;
*response_code = 0; /* Initialise to keep the rest of the code happy */
* This only fails if the packet is strangely malformed,
* or if we run out of memory.
*/
- fr_dcursor_init(&cursor, reply);
- if (fr_radius_decode(ctx, data, packet_len, original,
- inst->secret, talloc_array_length(inst->secret) - 1, &cursor) < 0) {
+ if (fr_radius_decode(ctx, reply, data, packet_len, original,
+ inst->secret, talloc_array_length(inst->secret) - 1) < 0) {
REDEBUG("Failed decoding attributes for packet");
fr_pair_list_free(reply);
return DECODE_FAIL_UNKNOWN;
void fr_arp_free(void);
ssize_t fr_arp_encode(fr_dbuff_t *dbuff, uint8_t const *original, fr_pair_list_t *vps);
-ssize_t fr_arp_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, fr_pair_list_t *list);
+ssize_t fr_arp_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len);
int fr_arp_entry_add(int fd, char const *interface, uint8_t ipaddr[static 4], uint8_t macaddr[static 6]);
fr_strerror_const("No ARP attributes in the attribute list");
return -1;
}
-
+
fr_proto_da_stack_build(&da_stack, attr_arp_packet);
FR_PROTO_STACK_PRINT(&da_stack, 0);
/** Decode a raw ARP packet into VPs
*
*/
-ssize_t fr_arp_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, fr_pair_list_t *list)
+ssize_t fr_arp_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len)
{
fr_arp_packet_t const *arp;
- fr_dcursor_t cursor;
if (packet_len < FR_ARP_PACKET_SIZE) {
fr_strerror_printf("Packet is too small (%d) to be ARP", (int) packet_len);
/*
* If the packet is too long, we discard any extra data.
*/
- fr_pair_list_init(list);
- fr_dcursor_init(&cursor, list);
- return fr_struct_from_network(ctx, &cursor, attr_arp_packet, packet, FR_ARP_PACKET_SIZE, false,
+ return fr_struct_from_network(ctx, out, attr_arp_packet, packet, FR_ARP_PACKET_SIZE, false,
NULL, NULL, NULL);
}
.func = fr_arp_encode_proto
};
-static ssize_t fr_arp_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
+static ssize_t fr_arp_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
{
- return fr_arp_decode(ctx, data, data_len, list);
+ return fr_arp_decode(ctx, out, data, data_len);
}
extern fr_test_point_proto_decode_t arp_tp_decode_proto;
#include "dhcpv4.h"
#include "attrs.h"
-static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent,
+static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
uint8_t const *data, size_t data_len);
-static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len);
/** Returns the number of array members for arrays with fixed element sizes
/*
* Decode ONE value into a VP
*/
-static ssize_t decode_value_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *da,
+static ssize_t decode_value_internal(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *da,
uint8_t const *data, size_t data_len)
{
fr_pair_t *vp;
/* Need another VP for the next round */
if (p < end) {
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
vp = fr_pair_afrom_da(ctx, da);
if (!vp) return -1;
finish:
FR_PROTO_TRACE("decoding value complete, adding new pair and returning %zu byte(s)", p - data);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return p - data;
}
-static ssize_t decode_raw(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent, uint8_t attr,
+static ssize_t decode_raw(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t attr,
uint8_t const *data, size_t data_len)
{
ssize_t slen;
fr_table_str_by_value(fr_value_box_type_table, parent->type, "<invalid>"), parent->name,
fr_table_str_by_value(fr_value_box_type_table, child->type, "<invalid>"), child->name);
- slen = decode_value(ctx, cursor, child, data, data_len);
+ slen = decode_value(ctx, out, child, data, data_len);
if (slen < 0) fr_dict_unknown_free(&child);
return slen;
/** Decode DHCP suboptions
*
- * @param[in] ctx context to alloc new attributes in.
- * @param[in,out] cursor Where to write the decoded options.
- * @param[in] parent of sub TLVs.
- * @param[in] data to parse.
- * @param[in] data_len of the data to parse
+ * @param[in] ctx context to alloc new attributes in.
+ * @param[out] out Where to write the decoded options.
+ * @param[in] parent of sub TLVs.
+ * @param[in] data to parse.
+ * @param[in] data_len of the data to parse
* @return
* <= 0 on error
* data_len on success.
*/
-static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent,
+static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
uint8_t const *data, size_t data_len)
{
uint8_t const *p = data;
vp = fr_raw_from_network(ctx, parent, data, data_len);
if (!vp) return -1;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return data_len;
}
* options" option. Return it as random crap.
*/
raw:
- tlv_len = decode_raw(ctx, cursor, parent, p[0], p, end - p);
+ tlv_len = decode_raw(ctx, out, parent, p[0], p, end - p);
if (tlv_len < 0) return tlv_len;
return data_len;
fr_table_str_by_value(fr_value_box_type_table, parent->type, "<invalid>"), parent->name,
fr_table_str_by_value(fr_value_box_type_table, child->type, "<invalid>"), child->name);
- tlv_len = decode_value(ctx, cursor, child, p + 2, p[1]);
+ tlv_len = decode_value(ctx, out, child, p + 2, p[1]);
if (tlv_len < 0) {
fr_dict_unknown_free(&child);
return tlv_len;
return data_len;
}
-static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len)
{
unsigned int values, i; /* How many values we need to decode */
/*
* TLVs can't be coalesced as they're variable length
*/
- if (parent->type == FR_TYPE_TLV) return decode_tlv(ctx, cursor, parent, data, data_len);
+ if (parent->type == FR_TYPE_TLV) return decode_tlv(ctx, out, parent, data, data_len);
/*
* Values with a fixed length may be coalesced into a single option
raw:
vp = fr_raw_from_network(ctx, parent, p, (data + data_len) - p);
if (!vp) return -1;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return data_len;
}
*/
for (i = 0, p = data; i < values; i++) {
fr_assert((p + value_len) <= (data + data_len));
- len = decode_value_internal(ctx, cursor, parent, p, value_len);
+ len = decode_value_internal(ctx, out, parent, p, value_len);
if (len <= 0) return len;
if (len != (ssize_t)value_len) goto raw;
p += len;
* ~ ... ~ V
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ----
*/
-static ssize_t decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent,
+static ssize_t decode_vsa(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len)
{
ssize_t len;
* attributes.
*/
if ((size_t)(end - p) < (sizeof(uint32_t) + 1 + 1)) {
- len = decode_raw(ctx, cursor, parent->parent, parent->attr, p, end - p);
+ len = decode_raw(ctx, out, parent->parent, parent->attr, p, end - p);
if (len < 0) return len;
return data_len + 2; /* decoded the whole thing */
option_len = p[0];
if ((p + 1 + option_len) > end) {
- len = decode_raw(ctx, cursor, vendor, p[1], p, end - p);
+ len = decode_raw(ctx, out, vendor, p[1], p, end - p);
if (len < 0) return len;
return data_len + 2; /* decoded the whole thing */
}
p++;
- len = decode_tlv(ctx, cursor, vendor, p, option_len);
+ len = decode_tlv(ctx, out, vendor, p, option_len);
if (len <= 0) return len;
p += len;
/** Decode DHCP option
*
* @param[in] ctx context to alloc new attributes in.
- * @param[in,out] cursor Where to write the decoded options.
+ * @param[out] out Where to write the decoded options.
* @param[in] dict to lookup attributes in.
* @param[in] data to parse.
* @param[in] data_len of data to parse.
* @param[in] decode_ctx Unused.
*/
-ssize_t fr_dhcpv4_decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+ssize_t fr_dhcpv4_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out,
fr_dict_t const *dict, uint8_t const *data, size_t data_len, UNUSED void *decode_ctx)
{
ssize_t ret;
fr_table_str_by_value(fr_value_box_type_table, parent->type, "<invalid>"), parent->name,
fr_table_str_by_value(fr_value_box_type_table, da->type, "<invalid>"), da->name);
- if (da->type == FR_TYPE_VSA) return decode_vsa(ctx, cursor, da, data + 2, data[1]);
+ if (da->type == FR_TYPE_VSA) return decode_vsa(ctx, out, da, data + 2, data[1]);
- ret = decode_value(ctx, cursor, da, data + 2, data[1]);
+ ret = decode_value(ctx, out, da, data + 2, data[1]);
if (ret < 0) {
fr_dict_unknown_free(&da);
return ret;
}
-static ssize_t fr_dhcpv4_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
+static ssize_t fr_dhcpv4_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
{
unsigned int code;
- fr_dcursor_t cursor;
if (!fr_dhcpv4_ok(data, data_len, NULL, NULL)) return -1;
- fr_pair_list_init(list);
- fr_dcursor_init(&cursor, list);
-
- if (fr_dhcpv4_decode(ctx, data, data_len, &cursor, &code) < 0) return -1;
+ if (fr_dhcpv4_decode(ctx, out, data, data_len, &code) < 0) return -1;
return data_len;
}
/*
* decode.c
*/
-ssize_t fr_dhcpv4_decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_dhcpv4_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t len, void *decode_ctx);
/*
*/
uint8_t const *fr_dhcpv4_packet_get_option(dhcp_packet_t const *packet, size_t packet_size, fr_dict_attr_t const *da);
-int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcursor_t *cursor, unsigned int *code);
+int fr_dhcpv4_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len, unsigned int *code);
int fr_dhcpv4_packet_encode(fr_radius_packet_t *packet, fr_pair_list_t *list);
return NULL;
}
-int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcursor_t *cursor, unsigned int *code)
+int fr_dhcpv4_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, unsigned int *code)
{
size_t i;
uint8_t const *p = data;
uint32_t giaddr;
- fr_pair_list_t head;
+ fr_pair_list_t tmp;
fr_pair_t *vp;
fr_pair_t *maxms, *mtu, *netaddr;
fr_value_box_t box;
- fr_dcursor_t our_cursor;
- fr_pair_list_init(&head);
- fr_dcursor_init(&our_cursor, &head);
+ fr_pair_list_init(&tmp);
if (data[1] > 1) {
fr_strerror_printf("Packet is not Ethernet: %u",
fr_strerror_const_push("Cannot decode packet due to internal error");
error:
talloc_free(vp);
- fr_dcursor_head(&our_cursor);
- fr_dcursor_free_list(&our_cursor);
+ fr_pair_list_free(&tmp);
return -1;
}
if (!vp) continue;
- fr_dcursor_append(&our_cursor, vp);
+ fr_pair_append(&tmp, vp);
}
- /*
- * Loop over the options.
- */
-
- fr_dcursor_head(&our_cursor);
-
/*
* Nothing uses tail after this call, if it does in the future
* it'll need to find the new tail...
while (p < end) {
if (p[0] == 0) break; /* padding */
- len = fr_dhcpv4_decode_option(ctx, &our_cursor, dict_dhcpv4, p, (end - p), NULL);
+ len = fr_dhcpv4_decode_option(ctx, &tmp, dict_dhcpv4, p, (end - p), NULL);
if (len <= 0) {
- fr_dcursor_head(&our_cursor);
- fr_dcursor_free_list(&our_cursor);
+ fr_pair_list_free(&tmp);
return len;
}
p += len;
}
if (code) {
- vp = fr_pair_find_by_da(&head, attr_dhcp_message_type, 0);
+ vp = fr_pair_find_by_da(&tmp, attr_dhcp_message_type, 0);
if (vp) {
*code = vp->vp_uint8;
}
* If option Overload is present in the 'options' field, then fields 'file' and/or 'sname'
* are used to hold more options. They are partitioned and must be interpreted in sequence.
*/
- vp = fr_pair_find_by_da(&head, attr_dhcp_overload, 0);
+ vp = fr_pair_find_by_da(&tmp, attr_dhcp_overload, 0);
if (vp) {
if ((vp->vp_uint8 & 1) == 1) {
/*
while (p < end) {
if (p[0] == 0) break; /* padding */
- len = fr_dhcpv4_decode_option(ctx, &our_cursor, dict_dhcpv4,
+ len = fr_dhcpv4_decode_option(ctx, &tmp, dict_dhcpv4,
p, end - p, NULL);
if (len <= 0) {
- fr_dcursor_head(&our_cursor);
- fr_dcursor_free_list(&our_cursor);
+ fr_pair_list_free(&tmp);
return len;
}
p += len;
}
- fr_pair_delete_by_da(&head, attr_dhcp_boot_filename);
+ fr_pair_delete_by_da(&tmp, attr_dhcp_boot_filename);
}
if ((vp->vp_uint8 & 2) == 2) {
/*
while (p < end) {
if (p[0] == 0) break; /* padding */
- len = fr_dhcpv4_decode_option(ctx, cursor, dict_dhcpv4,
+ len = fr_dhcpv4_decode_option(ctx, &tmp, dict_dhcpv4,
p, end - p, NULL);
if (len <= 0) {
- fr_dcursor_head(&our_cursor);
- fr_dcursor_free_list(&our_cursor);
+ fr_pair_list_free(&tmp);
return len;
}
p += len;
}
- fr_pair_delete_by_da(&head, attr_dhcp_server_host_name);
+ fr_pair_delete_by_da(&tmp, attr_dhcp_server_host_name);
}
}
}
/*
* DHCP Opcode is request
*/
- vp = fr_pair_find_by_da(&head, attr_dhcp_opcode, 0);
+ vp = fr_pair_find_by_da(&tmp, attr_dhcp_opcode, 0);
if (vp && vp->vp_uint8 == 1) {
/*
* Vendor is "MSFT 98"
*/
- vp = fr_pair_find_by_da(&head, attr_dhcp_vendor_class_identifier, 0);
+ vp = fr_pair_find_by_da(&tmp, attr_dhcp_vendor_class_identifier, 0);
if (vp && (vp->vp_length == 7) && (memcmp(vp->vp_strvalue, "MSFT 98", 7) == 0)) {
- vp = fr_pair_find_by_da(&head, attr_dhcp_flags, 0);
+ vp = fr_pair_find_by_da(&tmp, attr_dhcp_flags, 0);
/*
* Reply should be broadcast.
/*
* First look for Relay-Link-Selection
*/
- netaddr = fr_pair_find_by_da(&head, attr_dhcp_relay_link_selection, 0);
+ netaddr = fr_pair_find_by_da(&tmp, attr_dhcp_relay_link_selection, 0);
if (!netaddr) {
/*
* Next try Subnet-Selection-Option
*/
- netaddr = fr_pair_find_by_da(&head, attr_dhcp_subnet_selection_option, 0);
+ netaddr = fr_pair_find_by_da(&tmp, attr_dhcp_subnet_selection_option, 0);
}
if (netaddr) {
fr_value_box_cast(vp, &vp->data, vp->da->type, vp->da, &box);
}
- fr_dcursor_append(&our_cursor, vp);
+ fr_pair_append(&tmp, vp);
/*
* Client can request a LARGER size, but not a smaller
* one. They also cannot request a size larger than MTU.
*/
- maxms = fr_pair_find_by_da(&head, attr_dhcp_dhcp_maximum_msg_size, 0);
- mtu = fr_pair_find_by_da(&head, attr_dhcp_interface_mtu_size, 0);
+ maxms = fr_pair_find_by_da(&tmp, attr_dhcp_dhcp_maximum_msg_size, 0);
+ mtu = fr_pair_find_by_da(&tmp, attr_dhcp_interface_mtu_size, 0);
if (mtu && (mtu->vp_uint16 < DEFAULT_PACKET_SIZE)) {
fr_strerror_const("Client says MTU is smaller than minimum permitted by the specification");
* FIXME: Nuke attributes that aren't used in the normal
* header for discover/requests.
*/
- fr_dcursor_merge(cursor, &our_cursor);
+ fr_pair_list_append(out, &tmp);
return 0;
}
/** Decode a DHCPv6 packet
*
*/
-ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, fr_dcursor_t *cursor)
+ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len)
{
- ssize_t slen;
+ ssize_t slen = -1;
uint8_t const *p, *end;
fr_dhcpv6_decode_ctx_t packet_ctx;
fr_pair_t *vp;
+ fr_pair_list_t tmp;
+
+ fr_pair_list_init(&tmp);
if (packet_len < DHCPV6_HDR_LEN) return 0; /* protect access to packet[0] */
vp->vp_uint32 = packet[0];
vp->type = VT_DATA;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(&tmp, vp);
switch (packet[0]) {
case FR_DHCPV6_RELAY_FORWARD:
&FR_DBUFF_TMP(packet + 1, 1), 1, true) < 0) {
goto fail;
}
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(&tmp, vp);
vp = fr_pair_afrom_da(ctx, attr_relay_link_address);
if (!vp) goto fail;
&FR_DBUFF_TMP(packet + 2, 16), 16, true) < 0) {
goto fail;
}
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(&tmp, vp);
vp = fr_pair_afrom_da(ctx, attr_relay_peer_address);
if (!vp) goto fail;
goto fail;
}
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(&tmp, vp);
p = packet + DHCPV6_RELAY_HDR_LEN;
goto decode_options;
vp = fr_pair_afrom_da(ctx, attr_transaction_id);
if (!vp) {
fail:
- fr_dcursor_head(cursor);
- fr_dcursor_free_list(cursor);
- return -1;
+ fr_pair_list_free(&tmp);
+ return slen;
}
/*
(void) fr_pair_value_memdup(vp, packet + 1, 3, false);
vp->type = VT_DATA;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(&tmp, vp);
p = packet + 4;
* he doesn't, all hell breaks loose.
*/
while (p < end) {
- slen = fr_dhcpv6_decode_option(ctx, cursor, dict_dhcpv6, p, (end - p), &packet_ctx);
+ slen = fr_dhcpv6_decode_option(ctx, &tmp, dict_dhcpv6, p, (end - p), &packet_ctx);
if (slen < 0) {
- fr_dcursor_head(cursor);
- fr_dcursor_free_list(cursor);
talloc_free(packet_ctx.tmp_ctx);
- return slen;
+ goto fail;
}
-
/*
* If slen is larger than the room in the packet,
* all kinds of bad things happen.
*/
if (!fr_cond_assert(slen <= (end - p))) {
- fr_dcursor_head(cursor);
- fr_dcursor_free_list(cursor);
- talloc_free(packet_ctx.tmp_ctx);
- return -1;
- }
+ talloc_free(packet_ctx.tmp_ctx);
+ goto fail;
+ }
p += slen;
talloc_free_children(packet_ctx.tmp_ctx);
}
+ fr_pair_list_append(out, &tmp);
/*
* We've parsed the whole packet, return that.
#include "dhcpv6.h"
#include "attrs.h"
-static ssize_t decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx);
-static ssize_t decode_tlvs(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_tlvs(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx, bool do_raw);
-static ssize_t decode_tlv_trampoline(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_tlv_trampoline(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
- return decode_tlvs(ctx, cursor, dict, parent, data, data_len, decode_ctx, true);
+ return decode_tlvs(ctx, out, dict, parent, data, data_len, decode_ctx, true);
}
-static ssize_t decode_raw(TALLOC_CTX *ctx, fr_dcursor_t *cursor, UNUSED fr_dict_t const *dict,
+static ssize_t decode_raw(TALLOC_CTX *ctx, fr_pair_list_t *out, UNUSED fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
vp->type = VT_DATA;
vp->vp_tainted = true;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return data_len;
}
-static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx);
-static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_array(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx);
-static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx);
/** Handle arrays of DNS lavels for fr_struct_from_network()
*
*/
-static ssize_t decode_value_trampoline(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_value_trampoline(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
* @todo - we might need to limit this to only one DNS label.
*/
if ((parent->type == FR_TYPE_STRING) && !parent->flags.extra && parent->flags.subtype) {
- return decode_dns_labels(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ return decode_dns_labels(ctx, out, dict, parent, data, data_len, decode_ctx);
}
- if (parent->flags.array) return decode_array(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ if (parent->flags.array) return decode_array(ctx, out, dict, parent, data, data_len, decode_ctx);
- return decode_value(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ return decode_value(ctx, out, dict, parent, data, data_len, decode_ctx);
}
-static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
case FR_TYPE_IPV6_PREFIX:
if ((data_len == 0) || (data_len > (1 + sizeof(vp->vp_ipv6addr)))) {
raw:
- return decode_raw(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ return decode_raw(ctx, out, dict, parent, data, data_len, decode_ctx);
};
break;
case FR_TYPE_STRUCT:
- slen = fr_struct_from_network(ctx, cursor, parent, data, data_len, false,
+ slen = fr_struct_from_network(ctx, out, parent, data, data_len, false,
decode_ctx, decode_value_trampoline, decode_tlv_trampoline);
if (slen < 0) return slen;
return data_len;
case FR_TYPE_GROUP:
- {
- fr_dcursor_t child_cursor;
- fr_pair_list_t head;
- fr_pair_list_init(&head);
-
vp = fr_pair_afrom_da(ctx, parent);
if (!vp) return PAIR_DECODE_OOM;
* header, as we're just decoding the values
* here.
*/
- fr_dcursor_init(&child_cursor, &head);
- slen = decode_tlvs(vp, &child_cursor, dict, fr_dict_root(dict_dhcpv6), data, data_len, decode_ctx, false);
+ slen = decode_tlvs(vp, &vp->vp_group, dict, fr_dict_root(dict_dhcpv6), data, data_len, decode_ctx, false);
if (slen < 0) {
talloc_free(vp);
goto raw;
}
- fr_pair_list_append(&vp->vp_group, &head);
break;
- }
default:
vp = fr_pair_afrom_da(ctx, parent);
vp->type = VT_DATA;
vp->vp_tainted = true;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return data_len;
}
-static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_array(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
* decode the last bit as raw data.
*/
if ((size_t) (end - p) < element_len) {
- slen = decode_raw(ctx, cursor, dict, parent, p, end - p , decode_ctx);
+ slen = decode_raw(ctx, out, dict, parent, p, end - p , decode_ctx);
if (slen < 0) return slen;
break;
}
- slen = decode_value(ctx, cursor, dict, parent, p, element_len, decode_ctx);
+ slen = decode_value(ctx, out, dict, parent, p, element_len, decode_ctx);
if (slen < 0) return slen;
if (!fr_cond_assert((size_t) slen == element_len)) return -(p - data);
while (p < end) {
if ((end - p) < 2) {
raw:
- slen = decode_raw(ctx, cursor, dict, parent, p, end - p , decode_ctx);
+ slen = decode_raw(ctx, out, dict, parent, p, end - p , decode_ctx);
if (slen < 0) return slen;
break;
}
}
p += 2;
- slen = decode_value(ctx, cursor, dict, parent, p, element_len, decode_ctx);
+ slen = decode_value(ctx, out, dict, parent, p, element_len, decode_ctx);
if (slen < 0) return slen;
p += slen;
}
return data_len;
}
-static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
slen = fr_dns_labels_network_verify(data, data, data_len, data, NULL);
if (slen < 0) {
raw:
- return decode_raw(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ return decode_raw(ctx, out, dict, parent, data, data_len, decode_ctx);
}
labels_len = slen;
}
vp->type = VT_DATA;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
}
return labels_len;
/** Like decode_option(), but decodes *all* of the options.
*
*/
-static ssize_t decode_tlvs(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_tlvs(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx, bool do_raw)
{
while (p < end) {
ssize_t slen;
- slen = decode_option(ctx, cursor, dict, parent, p, (end - p), decode_ctx);
+ slen = decode_option(ctx, out, dict, parent, p, (end - p), decode_ctx);
if (slen <= 0) {
if (!do_raw) return slen;
- slen = decode_raw(ctx, cursor, dict, parent, p, (end - p), decode_ctx);
+ slen = decode_raw(ctx, out, dict, parent, p, (end - p), decode_ctx);
if (slen <= 0) return slen;
break;
}
}
-static ssize_t decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_vsa(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
/*
* Enterprise code plus at least one option header
*/
- if (data_len < 8) return decode_raw(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ if (data_len < 8) return decode_raw(ctx, out, dict, parent, data, data_len, decode_ctx);
memcpy(&pen, data, sizeof(pen));
pen = htonl(pen);
FR_PROTO_TRACE("decode context %s -> %s", parent->name, da->name);
- return decode_tlvs(ctx, cursor, dict, da, data + 4, data_len - 4, decode_ctx, true);
+ return decode_tlvs(ctx, out, dict, da, data + 4, data_len - 4, decode_ctx, true);
}
-static ssize_t decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
*/
if (da == attr_relay_message) {
fr_pair_t *vp;
- fr_dcursor_t cursor_group;
vp = fr_pair_afrom_da(ctx, attr_relay_message);
if (!vp) return PAIR_DECODE_FATAL_ERROR;
- fr_dcursor_init(&cursor_group, &vp->vp_group);
- slen = fr_dhcpv6_decode(vp, data + 4, len, &cursor_group);
+ slen = fr_dhcpv6_decode(vp, &vp->vp_group, data + 4, len);
if (slen < 0) {
talloc_free(vp);
return slen;
}
- fr_dcursor_insert(cursor, vp);
+ fr_pair_append(out, vp);
} else if ((da->type == FR_TYPE_STRING) && !da->flags.extra && da->flags.subtype) {
- slen = decode_dns_labels(ctx, cursor, dict, da, data + 4, len, decode_ctx);
+ slen = decode_dns_labels(ctx, out, dict, da, data + 4, len, decode_ctx);
if (slen < 0) return slen;
/*
if ((size_t) slen != len) return -(4 + slen);
} else if (da->flags.array) {
- slen = decode_array(ctx, cursor, dict, da, data + 4, len, decode_ctx);
+ slen = decode_array(ctx, out, dict, da, data + 4, len, decode_ctx);
} else if (da->type == FR_TYPE_VSA) {
- slen = decode_vsa(ctx, cursor, dict, da, data + 4, len, decode_ctx);
+ slen = decode_vsa(ctx, out, dict, da, data + 4, len, decode_ctx);
} else if (da->type == FR_TYPE_TLV) {
- slen = decode_tlvs(ctx, cursor, dict, da, data + 4, len, decode_ctx, true);
+ slen = decode_tlvs(ctx, out, dict, da, data + 4, len, decode_ctx, true);
} else {
- slen = decode_value(ctx, cursor, dict, da, data + 4, len, decode_ctx);
+ slen = decode_value(ctx, out, dict, da, data + 4, len, decode_ctx);
}
if (slen < 0) return slen;
* | option-code | option-len |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, void *decode_ctx)
{
FR_PROTO_HEX_DUMP(data, data_len, "fr_dhcpv6_decode_pair");
* All options including VSAs in DHCPv6 MUST follow the
* standard format.
*/
- return decode_option(ctx, cursor, dict, fr_dict_root(dict), data, data_len, decode_ctx);
+ return decode_option(ctx, out, dict, fr_dict_root(dict), data, data_len, decode_ctx);
}
/*
return 0;
}
-static ssize_t fr_dhcpv6_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
+static ssize_t fr_dhcpv6_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
{
size_t packet_len = data_len;
- fr_dcursor_t cursor;
// fr_dhcpv6_decode_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_dhcpv6_decode_ctx_t);
if (!fr_dhcpv6_ok(data, packet_len, 200)) return -1;
- fr_pair_list_init(list);
- fr_dcursor_init(&cursor, list);
-
- return fr_dhcpv6_decode(ctx, data, packet_len, &cursor);
+ return fr_dhcpv6_decode(ctx, out, data, packet_len);
}
ssize_t fr_dhcpv6_encode(fr_dbuff_t *dbuff, uint8_t const *original, size_t length,
int msg_type, fr_pair_list_t *vps);
-ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len,
- fr_dcursor_t *cursor);
+ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len);
void fr_dhcpv6_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len);
/*
* decode.c
*/
-ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, void *decode_ctx);
#include "dns.h"
#include "attrs.h"
-static ssize_t decode_raw(TALLOC_CTX *ctx, fr_dcursor_t *cursor, UNUSED fr_dict_t const *dict,
+static ssize_t decode_raw(TALLOC_CTX *ctx, fr_pair_list_t *out, UNUSED fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
vp->type = VT_DATA;
vp->vp_tainted = true;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return data_len;
}
-static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx);
-static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_array(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx);
-static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx);
/** Handle arrays of DNS labels for fr_struct_from_network()
*
*/
-static ssize_t decode_value_trampoline(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_value_trampoline(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
if ((parent->type == FR_TYPE_STRING) && !parent->flags.extra && parent->flags.subtype) {
FR_PROTO_TRACE("decode DNS labels");
- return decode_dns_labels(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ return decode_dns_labels(ctx, out, dict, parent, data, data_len, decode_ctx);
}
- if (parent->flags.array) return decode_array(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ if (parent->flags.array) return decode_array(ctx, out, dict, parent, data, data_len, decode_ctx);
- return decode_value(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ return decode_value(ctx, out, dict, parent, data, data_len, decode_ctx);
}
-static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
case FR_TYPE_IPV6_PREFIX:
if ((data_len == 0) || (data_len > (1 + sizeof(vp->vp_ipv6addr)))) {
raw:
- return decode_raw(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ return decode_raw(ctx, out, dict, parent, data, data_len, decode_ctx);
};
break;
case FR_TYPE_STRUCT:
- slen = fr_struct_from_network(ctx, cursor, parent, data, data_len, true,
+ slen = fr_struct_from_network(ctx, out, parent, data, data_len, true,
decode_ctx, decode_value_trampoline, NULL);
if (slen < 0) return slen;
return data_len;
#if 0
{
- fr_dcursor_t child_cursor;
+ fr_pair_list_t child_cursor;
fr_pair_list_t head;
fr_pair_list_init(&head);
* header, as we're just decoding the values
* here.
*/
- fr_dcursor_init(&child_cursor, &head);
- slen = decode_tlvs(vp, &child_cursor, dict, fr_dict_root(dict_dns), data, data_len, decode_ctx, false);
+ fr_dcursor_init(&child_out, &head);
+ slen = decode_tlvs(vp, &child_out, dict, fr_dict_root(dict_dns), data, data_len, decode_ctx, false);
if (slen < 0) {
talloc_free(vp);
goto raw;
vp->type = VT_DATA;
vp->vp_tainted = true;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return data_len;
}
-static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_array(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
* decode the last bit as raw data.
*/
if ((size_t) (end - p) < element_len) {
- slen = decode_raw(ctx, cursor, dict, parent, p, end - p , decode_ctx);
+ slen = decode_raw(ctx, out, dict, parent, p, end - p , decode_ctx);
if (slen < 0) return slen;
break;
}
- slen = decode_value(ctx, cursor, dict, parent, p, element_len, decode_ctx);
+ slen = decode_value(ctx, out, dict, parent, p, element_len, decode_ctx);
if (slen < 0) return slen;
if (!fr_cond_assert((size_t) slen == element_len)) return -(p - data);
while (p < end) {
if ((end - p) < 2) {
raw:
- slen = decode_raw(ctx, cursor, dict, parent, p, end - p , decode_ctx);
+ slen = decode_raw(ctx, out, dict, parent, p, end - p , decode_ctx);
if (slen < 0) return slen;
break;
}
}
p += 2;
- slen = decode_value(ctx, cursor, dict, parent, p, element_len, decode_ctx);
+ slen = decode_value(ctx, out, dict, parent, p, element_len, decode_ctx);
if (slen < 0) return slen;
p += slen;
}
return data_len;
}
-
-static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_dcursor_t *cursor, UNUSED fr_dict_t const *dict,
+static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_pair_list_t *out,UNUSED fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const data_len, void *decode_ctx)
{
}
vp->type = VT_DATA;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
}
FR_PROTO_TRACE("decode_dns_labels - %zu", labels_len);
return labels_len;
}
-static ssize_t decode_record(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *attr,
+static ssize_t decode_record(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *attr,
uint8_t const *rr, uint8_t const *end,
fr_dns_ctx_t *packet_ctx, uint8_t const *counter)
{
return -(p - rr);
}
- slen = fr_struct_from_network(ctx, cursor, attr, p, end - p, true,
+ slen = fr_struct_from_network(ctx, out, attr, p, end - p, true,
packet_ctx, decode_value_trampoline, NULL);
if (slen < 0) return slen;
if (!slen) break;
/** Decode a DNS packet
*
*/
-ssize_t fr_dns_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, fr_dcursor_t *cursor, fr_dns_ctx_t *packet_ctx)
+ssize_t fr_dns_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len, fr_dns_ctx_t *packet_ctx)
{
ssize_t slen;
uint8_t const *p, *end;
/*
* Decode the header.
*/
- slen = fr_struct_from_network(ctx, cursor, attr_dns_packet, packet, DNS_HDR_LEN, true,
+ slen = fr_struct_from_network(ctx, out, attr_dns_packet, packet, DNS_HDR_LEN, true,
packet_ctx, decode_value_trampoline, NULL);
if (slen < 0) {
fr_strerror_printf("Failed decoding DNS header - %s", fr_strerror());
end = packet + packet_len;
FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after header");
- slen = decode_record(ctx, cursor, attr_dns_question, p, end, packet_ctx, packet + 4);
+ slen = decode_record(ctx, out, attr_dns_question, p, end, packet_ctx, packet + 4);
if (slen < 0) {
fr_strerror_printf("Failed decoding questions - %s", fr_strerror());
return slen;
p += slen;
FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after %zd bytes of questions", slen);
- slen = decode_record(ctx, cursor, attr_dns_rr, p, end, packet_ctx, packet + 6);
+ slen = decode_record(ctx, out, attr_dns_rr, p, end, packet_ctx, packet + 6);
if (slen < 0) {
fr_strerror_printf("Failed decoding RRs - %s", fr_strerror());
return slen - (p - packet);
p += slen;
FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after %zd bytes of RRs", slen);
- slen = decode_record(ctx, cursor, attr_dns_ns, p, end, packet_ctx, packet + 8);
+ slen = decode_record(ctx, out, attr_dns_ns, p, end, packet_ctx, packet + 8);
if (slen < 0) {
fr_strerror_printf("Failed decoding NS - %s", fr_strerror());
return slen - (p - packet);
p += slen;
FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after %zd bytes of NS", slen);
- slen = decode_record(ctx, cursor, attr_dns_ar, p, end, packet_ctx, packet + 10);
+ slen = decode_record(ctx, out, attr_dns_ar, p, end, packet_ctx, packet + 10);
if (slen < 0) {
fr_strerror_printf("Failed decoding additional records - %s", fr_strerror());
return slen - (p - packet);
/** Decode DNS RR
*
* @param[in] ctx context to alloc new attributes in.
- * @param[in,out] cursor Where to write the decoded options.
+ * @param[in,out] out Where to write the decoded options.
* @param[in] dict to lookup attributes in.
* @param[in] data to parse.
* @param[in] data_len of data to parse.
* @param[in] decode_ctx Unused.
*/
-static ssize_t fr_dns_decode_rr(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+static ssize_t fr_dns_decode_rr(TALLOC_CTX *ctx, fr_pair_list_t *out,
UNUSED fr_dict_t const *dict, uint8_t const *data, size_t data_len, void *decode_ctx)
{
ssize_t slen;
return -1;
}
- slen = fr_struct_from_network(ctx, cursor, attr_dns_rr, data, data_len, true,
+ slen = fr_struct_from_network(ctx, out, attr_dns_rr, data, data_len, true,
decode_ctx, decode_value_trampoline, NULL);
if (slen < 0) return slen;
return 0;
}
-static ssize_t fr_dns_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, void *proto_ctx)
+static ssize_t fr_dns_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx)
{
- fr_dcursor_t cursor;
fr_dns_ctx_t *packet_ctx = proto_ctx;
if (data_len > 65535) return -1; /* packet is too big */
}
#endif
- fr_pair_list_init(list);
- fr_dcursor_init(&cursor, list);
-
packet_ctx->packet = data;
packet_ctx->packet_len = data_len;
fr_assert(packet_ctx->lb != NULL);
}
- return fr_dns_decode(ctx, data, data_len, &cursor, packet_ctx);
+ return fr_dns_decode(ctx, out, data, data_len, packet_ctx);
}
/*
size_t fr_dns_value_len(fr_pair_t const *vp);
-ssize_t fr_dns_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, fr_dcursor_t *cursor, fr_dns_ctx_t *packet_ctx);
+ssize_t fr_dns_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *packet, size_t packet_len, fr_dns_ctx_t *packet_ctx);
ssize_t fr_dns_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, void *encode_ctx);
return fr_dbuff_set(dbuff, &work_dbuff);
}
-static ssize_t internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *head, fr_dict_attr_t const *parent_da,
+static ssize_t internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent_da,
fr_dbuff_t *dbuff, void *decode_ctx)
{
ssize_t slen = 0;
FR_PROTO_TRACE("Decoding %s - %s", da->name,
fr_table_str_by_value(fr_value_box_type_table, da->type, "?Unknown?"));
- slen = internal_decode_pair(ctx, head, parent_da, &work_dbuff, decode_ctx);
+ slen = internal_decode_pair(ctx, out, parent_da, &work_dbuff, decode_ctx);
if (slen <= 0) goto error;
break;
case FR_TYPE_TLV:
if (unlikely(tainted)) goto bad_tainted;
- slen = internal_decode_tlv(ctx, head, da, &work_dbuff, decode_ctx);
+ slen = internal_decode_tlv(ctx, out, da, &work_dbuff, decode_ctx);
if (slen <= 0) goto error;
break;
case FR_TYPE_GROUP:
- slen = internal_decode_group(ctx, head, da, &work_dbuff, decode_ctx);
+ slen = internal_decode_group(ctx, out, da, &work_dbuff, decode_ctx);
if (slen <= 0) goto error;
break;
* It's ok for this function to return 0
* we can have zero length strings.
*/
- slen = internal_decode_pair_value(ctx, head, da, &work_dbuff, tainted, decode_ctx);
+ slen = internal_decode_pair_value(ctx, out, da, &work_dbuff, tainted, decode_ctx);
if (slen < 0) goto error;
}
/** Create a single fr_pair_t and all its nesting
*
*/
-ssize_t fr_internal_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, void *decode_ctx)
{
- return fr_internal_decode_pair_dbuff(ctx, cursor, dict, &FR_DBUFF_TMP(data, data_len), decode_ctx);
+ return fr_internal_decode_pair_dbuff(ctx, list, dict, &FR_DBUFF_TMP(data, data_len), decode_ctx);
}
-ssize_t fr_internal_decode_pair_dbuff(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_internal_decode_pair_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dbuff_t *dbuff, void *decode_ctx)
{
- fr_pair_list_t list;
- fr_dcursor_t tmp_cursor;
+ fr_pair_list_t tmp;
ssize_t slen;
fr_dbuff_t work_dbuff = FR_DBUFF(dbuff);
- fr_pair_list_init(&list);
+ fr_pair_list_init(&tmp);
- slen = internal_decode_pair(ctx, &list, fr_dict_root(dict), &work_dbuff, decode_ctx);
- if (slen <= 0) return slen;
+ slen = internal_decode_pair(ctx, &tmp, fr_dict_root(dict), &work_dbuff, decode_ctx);
+ if (slen <= 0) {
+ fr_pair_list_free(&tmp);
+ return slen;
+ }
- fr_dcursor_init(&tmp_cursor, &list);
- fr_dcursor_merge(cursor, &tmp_cursor);
+ fr_pair_list_append(out, &tmp);
return fr_dbuff_set(dbuff, &work_dbuff);
}
ssize_t fr_internal_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx);
-ssize_t fr_internal_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, void *decode_ctx);
-ssize_t fr_internal_decode_pair_dbuff(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_internal_decode_pair_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dbuff_t *dbuff, void *decode_ctx);
/** Decode a raw RADIUS packet into VPs.
*
*/
-ssize_t fr_radius_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, uint8_t const *original,
- char const *secret, UNUSED size_t secret_len, fr_dcursor_t *cursor)
+ssize_t fr_radius_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *packet, size_t packet_len, uint8_t const *original,
+ char const *secret, UNUSED size_t secret_len)
{
ssize_t slen;
uint8_t const *attr, *end;
* he doesn't, all hell breaks loose.
*/
while (attr < end) {
- slen = fr_radius_decode_pair(ctx, cursor, dict_radius, attr, (end - attr), &packet_ctx);
+ slen = fr_radius_decode_pair(ctx, out, dict_radius, attr, (end - attr), &packet_ctx);
if (slen < 0) {
fail:
talloc_free(packet_ctx.tmp_ctx);
/** Convert a "concatenated" attribute to one long VP
*
*/
-static ssize_t decode_concat(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+static ssize_t decode_concat(TALLOC_CTX *ctx, fr_pair_list_t *list,
fr_dict_attr_t const *parent, uint8_t const *data,
size_t const packet_len)
{
p += ptr[1] - 2;
ptr += ptr[1];
}
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(list, vp);
return ptr - data;
}
* Similar to decode_concat, but contains multiple values instead of
* one.
*/
-static ssize_t decode_nas_filter_rule(TALLOC_CTX *ctx, fr_dcursor_t *cursor,
+static ssize_t decode_nas_filter_rule(TALLOC_CTX *ctx, fr_pair_list_t *out,
fr_dict_attr_t const *parent, uint8_t const *data,
size_t const data_len, fr_radius_ctx_t *packet_ctx)
{
talloc_free(vp);
return -1;
}
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
}
/*
/** Convert TLVs to one or more VPs
*
*/
-ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len,
fr_radius_ctx_t *packet_ctx)
{
uint8_t const *p = data, *end = data + data_len;
fr_dict_attr_t const *child;
fr_pair_list_t head;
- fr_dcursor_t tlv_cursor;
+ fr_pair_list_t tlv_tmp;
fr_pair_t *vp;
bool concat;
if (!vp) return PAIR_DECODE_OOM;
/*
- * We don't have a "pair find in cursor"
+ * We don't have a "pair find in out"
*/
if (flag_concat(&parent->flags)) {
- vp = fr_pair_find_by_da(fr_pair_list_from_dcursor(cursor), parent, 0);
+ vp = fr_pair_find_by_da(out, parent, 0);
concat = (vp != NULL);
} else {
vp = NULL;
* Create a temporary sub-list, so decode errors don't
* affect the main list.
*/
- fr_dcursor_init(&tlv_cursor, &head);
+ fr_pair_list_init(&tlv_tmp);
while (p < end) {
ssize_t tlv_len;
}
FR_PROTO_TRACE("decode context changed %s -> %s", parent->name, child->name);
- tlv_len = fr_radius_decode_pair_value(vp, &tlv_cursor, dict,
+ tlv_len = fr_radius_decode_pair_value(vp, &tlv_tmp, dict,
child, p + 2, p[1] - 2, p[1] - 2,
packet_ctx);
if (tlv_len < 0) goto error;
p += p[1];
}
- fr_pair_list_append(&vp->vp_group, &head);
- if (!concat) fr_dcursor_append(cursor, vp);
+ fr_pair_list_append(&vp->vp_group, &tlv_tmp);
+ if (!concat) fr_pair_append(out, vp);
return data_len;
}
*
* "length" can be LONGER than just this sub-vsa.
*/
-static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t data_len,
fr_radius_ctx_t *packet_ctx, fr_dict_vendor_t const *dv)
if (!da) return -1;
FR_PROTO_TRACE("decode context changed %s -> %s", da->parent->name, da->name);
- my_len = fr_radius_decode_pair_value(ctx, cursor, dict,
+ my_len = fr_radius_decode_pair_value(ctx, out, dict,
da, data + dv->type + dv->length,
attrlen - (dv->type + dv->length), attrlen - (dv->type + dv->length),
packet_ctx);
*
* But for the first fragment, we get passed a pointer to the "extended-attr"
*/
-static ssize_t decode_extended(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_extended(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t attr_len, size_t packet_len,
fr_radius_ctx_t *packet_ctx)
* No continuation, just decode the attributre in place.
*/
if ((data[1] & 0x80) == 0) {
- ret = fr_radius_decode_pair_value(ctx, cursor, dict,
+ ret = fr_radius_decode_pair_value(ctx, out, dict,
parent, data + 2, attr_len - 2, attr_len - 2, packet_ctx);
if (ret < 0) return -1;
return attr_len;
FR_PROTO_HEX_DUMP(head, fraglen, "long-extended fragments");
- ret = fr_radius_decode_pair_value(ctx, cursor, dict,
+ ret = fr_radius_decode_pair_value(ctx, out, dict,
parent, head, fraglen, fraglen, packet_ctx);
talloc_free(head);
if (ret < 0) return ret;
*
* @note Called ONLY for Vendor-Specific
*/
-static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t attr_len, size_t packet_len,
fr_radius_ctx_t *packet_ctx)
* No continuation, just decode the attributre in place.
*/
if ((data[6] & 0x80) == 0) {
- ret = fr_radius_decode_pair_value(ctx, cursor, dict,
+ ret = fr_radius_decode_pair_value(ctx, out, dict,
da, data + 7, data[5] - 3, data[5] - 3, packet_ctx);
if (ret < 0) return ret;
FR_PROTO_HEX_DUMP(head, wimax_len, "Wimax fragments");
- ret = fr_radius_decode_pair_value(ctx, cursor, dict,
+ ret = fr_radius_decode_pair_value(ctx, out, dict,
da, head, wimax_len, wimax_len, packet_ctx);
talloc_free(head);
if (ret < 0) return ret;
/** Convert a top-level VSA to one or more VPs
*
*/
-static ssize_t CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t attr_len, size_t packet_len,
fr_radius_ctx_t *packet_ctx)
fr_pair_list_t head;
fr_dict_vendor_t my_dv;
fr_dict_attr_t const *vendor_da;
- fr_dcursor_t tlv_cursor;
+ fr_pair_list_t tlv_tmp;
fr_pair_list_init(&head);
* WiMAX craziness
*/
if (dv->continuation) {
- ret = decode_wimax(ctx, cursor, dict, vendor_da, data, attr_len, packet_len, packet_ctx);
+ ret = decode_wimax(ctx, out, dict, vendor_da, data, attr_len, packet_len, packet_ctx);
return ret;
}
packet_len -= 4;
total = 4;
- fr_dcursor_init(&tlv_cursor, &head);
+ fr_pair_list_init(&tlv_tmp);
while (attr_len > 0) {
ssize_t vsa_len;
/*
* Vendor attributes can have subattributes (if you hadn't guessed)
*/
- vsa_len = decode_vsa_internal(ctx, &tlv_cursor, dict,
+ vsa_len = decode_vsa_internal(ctx, &tlv_tmp, dict,
vendor_da, data, attr_len, packet_ctx, dv);
if (vsa_len < 0) {
fr_strerror_printf("%s: Internal sanity check %d", __FUNCTION__, __LINE__);
- fr_pair_list_free(&head);
+ fr_pair_list_free(&tlv_tmp);
return -1;
}
packet_len -= vsa_len;
total += vsa_len;
}
- fr_dcursor_head(&tlv_cursor);
- fr_dcursor_tail(cursor);
- fr_dcursor_merge(cursor, &tlv_cursor);
+ fr_pair_list_append(out, &tlv_tmp);
/*
* When the unknown attributes were created by
* packet length. But when we're decoding values inside of a struct,
* we're not using extended attributes.
*/
-static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t data_len, void *decode_ctx)
{
- return fr_radius_decode_pair_value(ctx, cursor, dict, parent, data, data_len, data_len, decode_ctx);
+ return fr_radius_decode_pair_value(ctx, out, dict, parent, data, data_len, data_len, decode_ctx);
}
/** Wrapper called by fr_struct_from_network()
*/
-static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t data_len, void *decode_ctx)
{
FR_PROTO_HEX_DUMP(data, data_len, "%s", __FUNCTION__ );
- return fr_radius_decode_tlv(ctx, cursor, dict, parent, data, data_len, decode_ctx);
+ return fr_radius_decode_tlv(ctx, out, dict, parent, data, data_len, decode_ctx);
}
* - Length on success.
* - -1 on failure.
*/
-ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const attr_len, size_t const packet_len,
fr_radius_ctx_t *packet_ctx)
goto raw;
}
- fr_dcursor_append(cursor, group);
+ fr_pair_append(out, group);
packet_ctx->tags[tag]->parent = group;
- fr_dcursor_init(&packet_ctx->tags[tag]->cursor, &group->vp_group);
}
}
* VSAs can be WiMAX, in which case they don't
* fit into one attribute.
*/
- ret = decode_vsa(ctx, cursor, dict, parent, p, attr_len, packet_len, packet_ctx);
+ ret = decode_vsa(ctx, out, dict, parent, p, attr_len, packet_len, packet_ctx);
if (ret < 0) goto raw;
return ret;
* Everything was found in the dictionary, we can
* now recurse to decode the value.
*/
- ret = fr_radius_decode_pair_value(ctx, cursor, dict,
+ ret = fr_radius_decode_pair_value(ctx, out, dict,
child, p + 5, attr_len - 5, attr_len - 5,
packet_ctx);
if (ret < 0) goto raw;
* attribute, OR they've already been grouped
* into a contiguous memory buffer.
*/
- ret = fr_radius_decode_tlv(ctx, cursor, dict, parent, p, attr_len, packet_ctx);
+ ret = fr_radius_decode_tlv(ctx, out, dict, parent, p, attr_len, packet_ctx);
if (ret < 0) goto raw;
return attr_len;
}
* set. Just decode it.
*/
if (!extra || ((p[1] & 0x80) == 0)) {
- ret = fr_radius_decode_pair_value(ctx, cursor, dict, child,
+ ret = fr_radius_decode_pair_value(ctx, out, dict, child,
p + min, attr_len - min, attr_len - min,
packet_ctx);
if (ret < 0) goto invalid_extended;
* MUST have the "more" bit set. So we
* don't check it again here.
*/
- ret = decode_extended(ctx, cursor, dict, child, data, attr_len, packet_len, packet_ctx);
+ ret = decode_extended(ctx, out, dict, child, data, attr_len, packet_len, packet_ctx);
if (ret >= 0) return ret; /* which may be LONGER than attr_len */
/* Fall through to invalid extended attribute */
* "long" extended. Decode the value.
*/
if (extra) {
- ret = decode_extended(ctx, cursor, dict, child, data, attr_len, packet_len, packet_ctx);
+ ret = decode_extended(ctx, out, dict, child, data, attr_len, packet_len, packet_ctx);
if (ret >= 0) return ret; /* which may be LONGER than attr_len */
}
- ret = fr_radius_decode_pair_value(ctx, cursor, dict, child,
+ ret = fr_radius_decode_pair_value(ctx, out, dict, child,
p + min, attr_len - min, attr_len - min,
packet_ctx);
if (ret < 0) return -1;
* attribute, OR it's already been grouped
* into a contiguous memory buffer.
*/
- ret = fr_struct_from_network(ctx, cursor, parent, p, attr_len, false,
+ ret = fr_struct_from_network(ctx, out, parent, p, attr_len, false,
packet_ctx, decode_value, decode_tlv);
if (ret < 0) goto raw;
return attr_len;
vp->vp_tainted = true;
if (!tag) {
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return attr_len;
}
fr_assert(packet_ctx->tags != NULL);
fr_assert(packet_ctx->tags[tag] != NULL);
- fr_dcursor_append(&packet_ctx->tags[tag]->cursor, vp);
+ fr_pair_append(&packet_ctx->tags[tag]->parent->vp_group, vp);
return attr_len;
}
/** Create a "normal" fr_pair_t from the given data
*
*/
-ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, fr_radius_ctx_t *packet_ctx)
{
ssize_t ret;
vp = fr_pair_afrom_da(ctx, da);
if (!vp) return -1;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
vp->vp_tainted = true; /* not REALLY necessary, but what the heck */
return 2;
*/
if ((da->type == FR_TYPE_OCTETS && flag_concat(&da->flags))) {
FR_PROTO_TRACE("Concat attribute");
- return decode_concat(ctx, cursor, da, data, data_len);
+ return decode_concat(ctx, out, da, data, data_len);
}
if (data[0] == FR_NAS_FILTER_RULE) {
FR_PROTO_TRACE("NAS-Filter-Rule attribute");
- return decode_nas_filter_rule(ctx, cursor, da, data, data_len, packet_ctx);
+ return decode_nas_filter_rule(ctx, out, da, data, data_len, packet_ctx);
}
/*
* attributes may have the "continuation" bit set, and
* will thus be more than one attribute in length.
*/
- ret = fr_radius_decode_pair_value(ctx, cursor, dict,
+ ret = fr_radius_decode_pair_value(ctx, out, dict,
da, data + 2, data[1] - 2, data_len - 2,
packet_ctx);
if (ret < 0) return ret;
return 0;
}
-static ssize_t fr_radius_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, void *proto_ctx)
+static ssize_t fr_radius_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len, void *proto_ctx)
{
- size_t packet_len = data_len;
+ size_t packet_len = data_len;
fr_radius_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_radius_ctx_t);
- decode_fail_t reason;
- fr_dcursor_t cursor;
- fr_pair_t *vp;
- uint8_t original[20];
+ decode_fail_t reason;
+ fr_pair_t *vp;
+ uint8_t original[20];
if (!fr_radius_ok(data, &packet_len, 200, false, &reason)) {
return -1;
}
- fr_pair_list_init(list);
- fr_dcursor_init(&cursor, list);
-
/*
* Decode the header
*/
return -1;
}
vp->vp_uint32 = data[0];
- fr_dcursor_append(&cursor, vp);
+ fr_pair_append(out, vp);
vp = fr_pair_afrom_da(ctx, attr_packet_authentication_vector);
if (!vp) {
return -1;
}
(void) fr_pair_value_memdup(vp, data + 4, 16, true);
- fr_dcursor_append(&cursor, vp);
- (void) fr_dcursor_tail(&cursor);
+ fr_pair_append(out, vp);
memset(original, 0, 4);
memcpy(original + 4, test_ctx->vector, sizeof(test_ctx->vector));
- return fr_radius_decode(ctx, data, packet_len, original,
- test_ctx->secret, talloc_array_length(test_ctx->secret) - 1, &cursor);
+ return fr_radius_decode(ctx, out, data, packet_len, original,
+ test_ctx->secret, talloc_array_length(test_ctx->secret) - 1);
}
/*
/** Calculate/check digest, and decode radius attributes
*
+ * @param[in] ctx to allocate pairs in.
+ * @param[out] out to add pairs to.
* @param[in] packet to decode.
- * @param[in] list to add pairs to.
* @param[in] original packet, if this is a reply.
* @param[in] max_attributes to decode.
* @param[in] tunnel_password_zeros set random elements of the tunnel password
* - 0 on success
* - -1 on decoding error.
*/
-int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_pair_list_t *list,
- fr_radius_packet_t *original,
+int fr_radius_packet_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ fr_radius_packet_t *packet, fr_radius_packet_t *original,
uint32_t max_attributes, bool tunnel_password_zeros, char const *secret)
{
int packet_length;
- uint32_t num_attributes;
uint8_t *ptr;
radius_packet_t *hdr;
- fr_pair_list_t head;
- fr_dcursor_t cursor, out;
+ fr_pair_list_t tmp_list;
fr_radius_ctx_t packet_ctx = {
.secret = secret,
.tunnel_password_zeros = tunnel_password_zeros
};
- fr_pair_list_init(&head);
#ifndef NDEBUG
if (fr_debug_lvl >= L_DBG_LVL_4) fr_radius_packet_log_hex(&default_log, packet);
#endif
hdr = (radius_packet_t *)packet->data;
ptr = hdr->data;
packet_length = packet->data_len - RADIUS_HEADER_LENGTH;
- num_attributes = 0;
- fr_dcursor_init(&cursor, &head);
+ fr_pair_list_init(&tmp_list);
/*
* Loop over the attributes, decoding them into VPs.
* This may return many VPs
*/
fr_assert(ptr != NULL);
- my_len = fr_radius_decode_pair(packet, &cursor, dict_radius, ptr, packet_length, &packet_ctx);
+ my_len = fr_radius_decode_pair(ctx, &tmp_list, dict_radius, ptr, packet_length, &packet_ctx);
if (my_len < 0) {
fail:
talloc_free(packet_ctx.tmp_ctx);
- fr_pair_list_free(&head);
+ fr_pair_list_free(&tmp_list);
return -1;
}
*/
if (my_len == 0) break;
- /*
- * Count the ones which were just added
- */
- while (fr_dcursor_next(&cursor)) num_attributes++;
-
/*
* VSA's may not have been counted properly in
* fr_radius_packet_ok() above, as it is hard to count
* then without using the dictionary. We
* therefore enforce the limits here, too.
*/
- if ((max_attributes > 0) && (num_attributes > max_attributes)) {
+ if ((max_attributes > 0) && (fr_pair_list_len(out) > max_attributes)) {
char host_ipaddr[INET6_ADDRSTRLEN];
fr_strerror_printf("Possible DoS attack from host %s: Too many attributes in request "
- "(received %d, max %d are allowed)",
+ "(received %zu, max %d are allowed)",
inet_ntop(packet->socket.inet.src_ipaddr.af,
&packet->socket.inet.src_ipaddr.addr,
host_ipaddr, sizeof(host_ipaddr)),
- num_attributes, max_attributes);
+ fr_pair_list_len(out), max_attributes);
goto fail;
}
talloc_free_children(packet_ctx.tmp_ctx);
}
- fr_dcursor_init(&out, list);
- fr_dcursor_tail(&out); /* Move insertion point to the end of the list */
- fr_dcursor_head(&cursor);
- fr_dcursor_merge(&out, &cursor);
+ fr_pair_list_append(out, &tmp_list);
/*
* Merge information from the outside world into our
ssize_t fr_radius_encode_dbuff(fr_dbuff_t *dbuff, uint8_t const *original,
char const *secret, UNUSED size_t secret_len, int code, int id, fr_pair_list_t *vps);
-ssize_t fr_radius_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, uint8_t const *original,
- char const *secret, UNUSED size_t secret_len, fr_dcursor_t *cursor) CC_HINT(nonnull(1,2,5,7));
+ssize_t fr_radius_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *packet, size_t packet_len, uint8_t const *original,
+ char const *secret, UNUSED size_t secret_len) CC_HINT(nonnull(1,2,3,6));
int fr_radius_init(void);
ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_pair_list_t *list,
fr_radius_packet_t const *original,
char const *secret) CC_HINT(nonnull (1,2,4));
-int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_pair_list_t *list,
- fr_radius_packet_t *original,
+int fr_radius_packet_decode(TALLOC_CTX *ctx, fr_pair_list_t *list,
+ fr_radius_packet_t *packet, fr_radius_packet_t *original,
uint32_t max_attributes, bool tunnel_password_zeros,
- char const *secret) CC_HINT(nonnull (1,2,6));
+ char const *secret) CC_HINT(nonnull (1,2,3,7));
bool fr_radius_packet_ok(fr_radius_packet_t *packet, uint32_t max_attributes, bool require_ma,
decode_fail_t *reason) CC_HINT(nonnull (1));
ssize_t fr_radius_decode_tunnel_password(uint8_t *encpw, size_t *len, char const *secret,
uint8_t const *vector, bool tunnel_password_zeros);
-ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t const attr_len, size_t const packet_len,
fr_radius_ctx_t *packet_ctx) CC_HINT(nonnull);
-ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_t const *dict,
fr_dict_attr_t const *parent,
uint8_t const *data, size_t data_len,
fr_radius_ctx_t *packet_ctx) CC_HINT(nonnull);
-ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const *dict,
+ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_t const *dict,
uint8_t const *data, size_t data_len, fr_radius_ctx_t *packet_ctx) CC_HINT(nonnull);
vp = fr_pair_afrom_da(ctx, _da); \
if (!vp) goto fail; \
vp->vp_uint8 = _field; \
- fr_dcursor_append(cursor, vp); \
+ fr_pair_append(out, vp); \
} while (0)
#define DECODE_FIELD_STRING8(_da, _field) do { \
- if (tacacs_decode_field(ctx, cursor, _da, &p, \
+ if (tacacs_decode_field(ctx, out, _da, &p, \
_field, end) < 0) goto fail; \
} while (0)
#define DECODE_FIELD_STRING16(_da, _field) do { \
- if (tacacs_decode_field(ctx, cursor, _da, &p, \
+ if (tacacs_decode_field(ctx, out, _da, &p, \
ntohs(_field), end) < 0) goto fail; \
} while (0)
/**
* Decode a TACACS+ 'arg_N' fields.
*/
-static int tacacs_decode_args(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *parent,
+static int tacacs_decode_args(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
uint8_t arg_cnt, uint8_t const *arg_list, uint8_t const **data, uint8_t const *end)
{
uint8_t i;
goto next;
}
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
next:
p += arg_list[i];
/**
* Decode a TACACS+ field.
*/
-static int tacacs_decode_field(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t const *da,
+static int tacacs_decode_field(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *da,
uint8_t const **field_data, uint16_t field_len, uint8_t const *end)
{
uint8_t const *p = *field_data;
*field_data = p;
}
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
return 0;
}
/**
* Decode a TACACS+ packet
*/
-ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, uint8_t const *buffer, size_t buffer_len, UNUSED const uint8_t *original, char const * const secret, size_t secret_len, fr_dcursor_t *cursor)
+ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *buffer, size_t buffer_len,
+ UNUSED const uint8_t *original, char const * const secret, size_t secret_len)
{
fr_tacacs_packet_t const *pkt;
fr_pair_t *vp;
/*
* Call the struct encoder to do the actual work.
*/
- if (fr_struct_from_network(ctx, cursor, attr_tacacs_packet, buffer, buffer_len, false, NULL, NULL, NULL) < 0) {
+ if (fr_struct_from_network(ctx, out, attr_tacacs_packet, buffer, buffer_len, false, NULL, NULL, NULL) < 0) {
fr_strerror_printf("Problems to decode %s using fr_struct_from_network()", attr_tacacs_packet->name);
return -1;
}
/*
* Decode 'arg_N' arguments (horrible format)
*/
- if (tacacs_decode_args(ctx, cursor, attr_tacacs_argument_list,
+ if (tacacs_decode_args(ctx, out, attr_tacacs_argument_list,
pkt->author.req.arg_cnt, BODY(author.req), &p, end) < 0) goto fail;
} else if (packet_is_author_response(pkt)) {
/*
* Decode 'arg_N' arguments (horrible format)
*/
- if (tacacs_decode_args(ctx, cursor, attr_tacacs_argument_list,
+ if (tacacs_decode_args(ctx, out, attr_tacacs_argument_list,
pkt->author.res.arg_cnt, BODY(author.res), &p, end) < 0) goto fail;
} else {
/*
* Decode 'arg_N' arguments (horrible format)
*/
- if (tacacs_decode_args(ctx, cursor, attr_tacacs_argument_list,
+ if (tacacs_decode_args(ctx, out, attr_tacacs_argument_list,
pkt->acct.req.arg_cnt, BODY(acct.req), &p, end) < 0) goto fail;
} else if (packet_is_acct_reply(pkt)) {
/*
* Test points for protocol decode
*/
-static ssize_t fr_tacacs_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, void *proto_ctx)
+static ssize_t fr_tacacs_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx)
{
fr_tacacs_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_tacacs_ctx_t);
- fr_dcursor_t cursor;
- fr_pair_list_init(list);
- fr_dcursor_init(&cursor, list);
-
- return fr_tacacs_decode(ctx, data, data_len, NULL, test_ctx->secret, (talloc_array_length(test_ctx->secret)-1), &cursor);
+ return fr_tacacs_decode(ctx, out, data, data_len, NULL,
+ test_ctx->secret, (talloc_array_length(test_ctx->secret)-1));
}
static int _encode_test_ctx(fr_tacacs_ctx_t *proto_ctx)
ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original, char const *const secret, size_t secret_len, fr_pair_list_t *vps);
/* decode.c */
-ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, uint8_t const *buffer, size_t buffer_len, UNUSED const uint8_t *original, char const * const secret, size_t secret_len, fr_dcursor_t *cursor);
+ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *buffer, size_t buffer_len,
+ UNUSED const uint8_t *original, char const * const secret, size_t secret_len);
/* base.c */
ssize_t fr_tacacs_length(uint8_t const *buffer, size_t buffer_len);
* 2. Host B sends a "DATA" (with block number= 1) to host A with
* source= B's TID, destination= A's TID.
*/
-int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcursor_t *cursor)
+int fr_tftp_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
{
uint8_t const *q, *p, *end;
uint16_t opcode;
if (!vp) goto error;
vp->vp_uint16 = opcode;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
p += 2;
switch (opcode) {
if (!vp) goto error;
fr_pair_value_bstrndup(vp, (char const *)p, (q - p), true);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
p += (q - p) + 1 /* \0 */;
/* <mode> */
goto error;
}
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
p += 1 /* \0 */;
if (p >= end) goto done;
}
vp->vp_uint16 = (uint16_t)blksize;
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
}
break;
vp->vp_uint16 = fr_net_to_uint16(p);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
/*
* From that point...
if (!vp) goto error;
fr_pair_value_memdup(vp, p, (end - p), true);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
break;
vp->vp_uint16 = fr_net_to_uint16(p);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
p += 2; /* <ErrorCode> */
q = memchr(p, '\0', (end - p));
if (!vp) goto error;
fr_pair_value_bstrndup(vp, (char const *)p, (q - p), true);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
break;
/*
* Test points for protocol decode
*/
-static ssize_t fr_tftp_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
+static ssize_t fr_tftp_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
{
- fr_dcursor_t cursor;
-
- fr_pair_list_init(list);
- fr_dcursor_init(&cursor, list);
-
- return fr_tftp_decode(ctx, data, data_len, &cursor);
+ return fr_tftp_decode(ctx, out, data, data_len);
}
static int _decode_test_ctx(UNUSED fr_tftp_ctx_t *proto_ctx)
#define FR_TFTP_MAX_FILESIZE (FR_TFTP_BLOCK_MAX_SIZE * FR_TFTP_BLOCK_MAX_SIZE)
/* tftp.c */
-int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcursor_t *cursor) CC_HINT(nonnull(2,4));
+int fr_tftp_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len) CC_HINT(nonnull(2,3));
ssize_t fr_tftp_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps) CC_HINT(nonnull(1,2));
/* base.c */
}
-int fr_vmps_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcursor_t *cursor, unsigned int *code)
+int fr_vmps_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, unsigned int *code)
{
uint8_t const *ptr, *end;
int attr;
if (code) *code = data[1];
vp->vp_tainted = true;
DEBUG2("&%pP", vp);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
vp = fr_pair_afrom_da(ctx, attr_error_code);
if (!vp) goto oom;
vp->vp_uint32 = data[2];
vp->vp_tainted = true;
DEBUG2("&%pP", vp);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
vp = fr_pair_afrom_da(ctx, attr_sequence_number);
if (!vp) goto oom;
vp->vp_uint32 = ntohl(vp->vp_uint32);
vp->vp_tainted = true;
DEBUG2("&%pP", vp);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
ptr = data + FR_VQP_HDR_LEN;
end = data + data_len;
ptr += attr_len;
vp->vp_tainted = true;
DEBUG2("&%pP", vp);
- fr_dcursor_append(cursor, vp);
+ fr_pair_append(out, vp);
}
/*
/*
* Test points for protocol decode
*/
-static ssize_t fr_vmps_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
+static ssize_t fr_vmps_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len, void *proto_ctx)
{
- fr_dcursor_t cursor;
-
- fr_pair_list_init(list);
- fr_dcursor_init(&cursor, list);
-
- return fr_vmps_decode(ctx, data, data_len, &cursor, NULL);
+ return fr_vmps_decode(ctx, out, data, data_len, proto_ctx);
}
static int _decode_test_ctx(UNUSED fr_vmps_ctx_t *proto_ctx)
bool fr_vmps_ok(uint8_t const *packet, size_t *packet_len);
-int fr_vmps_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcursor_t *cursor, unsigned int *code);
+int fr_vmps_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, unsigned int *code);
ssize_t fr_vmps_packet_size(uint8_t const *data, size_t data_len);