From: Arran Cudbard-Bell Date: Thu, 7 Oct 2021 23:43:23 +0000 (-0500) Subject: Decoder functions should write directly to fr_pair_list_t and not to a cursor X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce5a6be1ceb6e0415d877b0380509a29aa5208e4;p=thirdparty%2Ffreeradius-server.git Decoder functions should write directly to fr_pair_list_t and not to a cursor 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. --- diff --git a/src/bin/dhcpclient.c b/src/bin/dhcpclient.c index 38b04928d07..1209f704670 100644 --- a/src/bin/dhcpclient.c +++ b/src/bin/dhcpclient.c @@ -306,7 +306,7 @@ static fr_radius_packet_t *fr_dhcpv4_recv_raw_loop(int lsockfd, 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; } @@ -740,12 +740,9 @@ int main(int argc, char **argv) * 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); } @@ -759,9 +756,7 @@ int main(int argc, char **argv) } 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; } diff --git a/src/bin/radclient.c b/src/bin/radclient.c index f44bb514e18..941b9b0ed83 100644 --- a/src/bin/radclient.c +++ b/src/bin/radclient.c @@ -1038,8 +1038,8 @@ static int recv_one_packet(fr_time_delta_t wait_time) /* * 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; diff --git a/src/bin/radsniff.c b/src/bin/radsniff.c index 352c9071d23..3513458ed1e 100644 --- a/src/bin/radsniff.c +++ b/src/bin/radsniff.c @@ -1431,7 +1431,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt 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) { @@ -1565,7 +1565,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt 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; diff --git a/src/bin/radsnmp.c b/src/bin/radsnmp.c index 02be4a7d2d0..b17f6790f1c 100644 --- a/src/bin/radsnmp.c +++ b/src/bin/radsnmp.c @@ -827,7 +827,7 @@ static int radsnmp_send_recv(radsnmp_conf_t *conf, int fd) 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; diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index 0a3148bf1b6..b4cfe5ce4e5 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -1260,7 +1260,6 @@ static size_t command_decode_pair(command_result_t *result, command_file_ctx_t * 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; @@ -1313,9 +1312,8 @@ static size_t command_decode_pair(command_result_t *result, command_file_ctx_t * * 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) { diff --git a/src/lib/eap/chbind.c b/src/lib/eap/chbind.c index 1dbcf96e3ff..539fc73bc63 100644 --- a/src/lib/eap/chbind.c +++ b/src/lib/eap/chbind.c @@ -204,15 +204,12 @@ fr_radius_packet_code_t chbind_process(request_t *request, CHBIND_REQ *chbind) /* 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) { /* diff --git a/src/lib/eap_aka_sim/base.h b/src/lib/eap_aka_sim/base.h index 4e59dfc2e8b..b48c662804d 100644 --- a/src/lib/eap_aka_sim/base.h +++ b/src/lib/eap_aka_sim/base.h @@ -253,11 +253,11 @@ extern size_t const fr_aka_sim_attr_sizes[FR_TYPE_MAX + 1][2]; /* * 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 diff --git a/src/lib/eap_aka_sim/decode.c b/src/lib/eap_aka_sim/decode.c index 06e5590b33d..0eabf1c2f03 100644 --- a/src/lib/eap_aka_sim/decode.c +++ b/src/lib/eap_aka_sim/decode.c @@ -58,10 +58,10 @@ RCSID("$Id$") * 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); @@ -295,7 +295,7 @@ static int sim_array_members(size_t *out, size_t len, fr_dict_attr_t const *da) 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) @@ -342,7 +342,7 @@ static ssize_t sim_decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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; @@ -356,7 +356,7 @@ static ssize_t sim_decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, /** 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. @@ -366,7 +366,7 @@ static ssize_t sim_decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, * - 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) @@ -375,11 +375,10 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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 */ @@ -411,7 +410,6 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, /* * 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; @@ -423,7 +421,7 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, error: talloc_free(decr); - fr_pair_list_free(&head); + fr_pair_list_free(&tlv_tmp); return -1; } @@ -498,14 +496,12 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, } 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; @@ -514,7 +510,7 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, /** 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. @@ -524,7 +520,7 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, * - 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) { @@ -683,7 +679,7 @@ static ssize_t sim_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_d * 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: @@ -830,7 +826,7 @@ static ssize_t sim_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_d done: vp->type = VT_DATA; - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); return attr_len; } @@ -838,7 +834,7 @@ done: /** 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 @@ -849,7 +845,7 @@ done: * - 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; @@ -904,9 +900,9 @@ static ssize_t sim_decode_pair_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, f 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; @@ -916,7 +912,7 @@ static ssize_t sim_decode_pair_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, f /** 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 @@ -927,10 +923,10 @@ static ssize_t sim_decode_pair_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, f * - 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 @@ -950,8 +946,8 @@ ssize_t fr_aka_sim_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t * * 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. @@ -960,19 +956,13 @@ ssize_t fr_aka_sim_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t * - 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. @@ -995,11 +985,11 @@ int fr_aka_sim_decode(request_t *request, fr_dcursor_t *decoded, fr_dict_t const * 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; } @@ -1014,13 +1004,13 @@ int fr_aka_sim_decode(request_t *request, fr_dcursor_t *decoded, fr_dict_t const { 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; diff --git a/src/lib/eap_aka_sim/module.c b/src/lib/eap_aka_sim/module.c index 6fff875fb37..48335defedf 100644 --- a/src/lib/eap_aka_sim/module.c +++ b/src/lib/eap_aka_sim/module.c @@ -313,8 +313,8 @@ unlang_action_t eap_aka_sim_process(rlm_rcode_t *p_result, module_ctx_t const *m 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, diff --git a/src/lib/io/pair.h b/src/lib/io/pair.h index 772769892e6..f94ec72d1c3 100644 --- a/src/lib/io/pair.h +++ b/src/lib/io/pair.h @@ -123,7 +123,7 @@ typedef ssize_t (*fr_pair_encode_t)(fr_dbuff_t *out, fr_dcursor_t *cursor, void * 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. @@ -132,9 +132,9 @@ typedef ssize_t (*fr_pair_encode_t)(fr_dbuff_t *out, fr_dcursor_t *cursor, void * - <= 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); diff --git a/src/lib/tls/cache.c b/src/lib/tls/cache.c index ab1f820e3ca..2c5c998e8b1 100644 --- a/src/lib/tls/cache.c +++ b/src/lib/tls/cache.c @@ -169,7 +169,6 @@ static int tls_cache_app_data_get(request_t *request, SSL_SESSION *sess) 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. @@ -180,7 +179,6 @@ static int tls_cache_app_data_get(request_t *request, SSL_SESSION *sess) } 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"); @@ -192,7 +190,7 @@ static int tls_cache_app_data_get(request_t *request, SSL_SESSION *sess) * 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"); diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 134c2bdc609..569629665eb 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -3070,8 +3070,6 @@ static xlat_action_t protocol_decode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, { 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; @@ -3083,21 +3081,14 @@ static xlat_action_t protocol_decode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, } } - 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. diff --git a/src/lib/unlang/xlat_pair.c b/src/lib/unlang/xlat_pair.c index 14c5aa49a24..e9fb2e0e3ed 100644 --- a/src/lib/unlang/xlat_pair.c +++ b/src/lib/unlang/xlat_pair.c @@ -39,20 +39,18 @@ RCSID("$Id$") * - <= 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; @@ -60,9 +58,9 @@ static ssize_t fr_pair_decode_multi(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_dict_ 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; @@ -71,8 +69,7 @@ static ssize_t fr_pair_decode_multi(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_dict_ /* * Add the pairs to the cursor */ - fr_dcursor_head(&cursor); - fr_dcursor_merge(out, &cursor); + fr_pair_list_append(out, &tmp); return data_len; } @@ -90,7 +87,7 @@ static ssize_t fr_pair_decode_multi(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_dict_ * - <= 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) { @@ -98,13 +95,11 @@ int fr_pair_decode_value_box_list(TALLOC_CTX *ctx, fr_dcursor_t *out, 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", @@ -114,16 +109,12 @@ int fr_pair_decode_value_box_list(TALLOC_CTX *ctx, fr_dcursor_t *out, 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. */ } @@ -137,8 +128,7 @@ int fr_pair_decode_value_box_list(TALLOC_CTX *ctx, fr_dcursor_t *out, decoded = fr_pair_list_len(&head); - fr_dcursor_init(&cursor, &head); - fr_dcursor_merge(out, &cursor); + fr_pair_list_append(out, &head); return decoded; } diff --git a/src/lib/util/struct.c b/src/lib/util/struct.c index 96ad46ba2a5..cf17bd8fdb4 100644 --- a/src/lib/util/struct.c +++ b/src/lib/util/struct.c @@ -63,7 +63,7 @@ fr_pair_t *fr_raw_from_network(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, ui /** 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) @@ -71,8 +71,8 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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; @@ -88,8 +88,8 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, * 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); @@ -101,8 +101,8 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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; @@ -203,7 +203,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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++; @@ -228,7 +228,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, * 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; @@ -261,7 +261,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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; @@ -269,7 +269,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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; } @@ -306,7 +306,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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); @@ -315,13 +315,13 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, /* * 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; @@ -378,12 +378,12 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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); @@ -404,12 +404,11 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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); diff --git a/src/lib/util/struct.h b/src/lib/util/struct.h index b8ef0b7469e..5609d1b36ac 100644 --- a/src/lib/util/struct.h +++ b/src/lib/util/struct.h @@ -32,18 +32,18 @@ RCSIDH(struct_h, "$Id$") 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)); diff --git a/src/listen/arp/proto_arp.c b/src/listen/arp/proto_arp.c index f4d03cdcc5e..5995521769a 100644 --- a/src/listen/arp/proto_arp.c +++ b/src/listen/arp/proto_arp.c @@ -75,7 +75,7 @@ static int mod_decode(UNUSED void const *instance, request_t *request, uint8_t * */ 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; } diff --git a/src/listen/dhcpv4/proto_dhcpv4.c b/src/listen/dhcpv4/proto_dhcpv4.c index d8d89e7a62f..fcd9534c112 100644 --- a/src/listen/dhcpv4/proto_dhcpv4.c +++ b/src/listen/dhcpv4/proto_dhcpv4.c @@ -190,7 +190,6 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d 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 @@ -218,8 +217,8 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d * 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; } diff --git a/src/listen/dhcpv6/proto_dhcpv6.c b/src/listen/dhcpv6/proto_dhcpv6.c index 4ad0c526ad5..eca98054e1a 100644 --- a/src/listen/dhcpv6/proto_dhcpv6.c +++ b/src/listen/dhcpv6/proto_dhcpv6.c @@ -190,7 +190,6 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d 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 @@ -218,8 +217,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d * 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; } diff --git a/src/listen/dns/proto_dns.c b/src/listen/dns/proto_dns.c index c6d6c8fb0b7..3d5f83687e8 100644 --- a/src/listen/dns/proto_dns.c +++ b/src/listen/dns/proto_dns.c @@ -171,8 +171,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d 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 @@ -186,7 +185,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d client = address->radclient; /* - * @todo - + * @todo - */ request->packet->code = packet->opcode; request->packet->id = (data[0] << 8) | data[1]; @@ -208,8 +207,8 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d * 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; diff --git a/src/listen/radius/proto_radius.c b/src/listen/radius/proto_radius.c index 497c438a880..82385354414 100644 --- a/src/listen/radius/proto_radius.c +++ b/src/listen/radius/proto_radius.c @@ -197,7 +197,6 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d 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); @@ -226,10 +225,9 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d * 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; } @@ -294,7 +292,7 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d 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; diff --git a/src/listen/tacacs/proto_tacacs.c b/src/listen/tacacs/proto_tacacs.c index 7f6c08894f7..43c775b4e86 100644 --- a/src/listen/tacacs/proto_tacacs.c +++ b/src/listen/tacacs/proto_tacacs.c @@ -173,7 +173,6 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d 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"); @@ -225,10 +224,9 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d * 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; } diff --git a/src/listen/vmps/proto_vmps.c b/src/listen/vmps/proto_vmps.c index 2a2524587a7..3ed4f8fa6e3 100644 --- a/src/listen/vmps/proto_vmps.c +++ b/src/listen/vmps/proto_vmps.c @@ -179,7 +179,6 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d 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); @@ -210,8 +209,8 @@ static int mod_decode(void const *instance, request_t *request, uint8_t *const d * 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; } diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index 8047696f4d6..b14dda0a203 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -1186,7 +1186,6 @@ static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *res 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 */ @@ -1241,9 +1240,8 @@ static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *res * 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; diff --git a/src/protocols/arp/arp.h b/src/protocols/arp/arp.h index e6bcd30e7ec..7651dffbd54 100644 --- a/src/protocols/arp/arp.h +++ b/src/protocols/arp/arp.h @@ -40,7 +40,7 @@ int fr_arp_init(void); 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]); diff --git a/src/protocols/arp/base.c b/src/protocols/arp/base.c index 38e1bb7691e..a4c90f06bb8 100644 --- a/src/protocols/arp/base.c +++ b/src/protocols/arp/base.c @@ -174,7 +174,7 @@ ssize_t fr_arp_encode(fr_dbuff_t *dbuff, uint8_t const *original, fr_pair_list_t 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); @@ -222,10 +222,9 @@ ssize_t fr_arp_encode(fr_dbuff_t *dbuff, uint8_t const *original, fr_pair_list_t /** 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); @@ -259,9 +258,7 @@ ssize_t fr_arp_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t 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); } @@ -343,9 +340,10 @@ fr_test_point_proto_encode_t arp_tp_encode_proto = { .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; diff --git a/src/protocols/dhcpv4/decode.c b/src/protocols/dhcpv4/decode.c index 2c36b947190..1cdcf6376d9 100644 --- a/src/protocols/dhcpv4/decode.c +++ b/src/protocols/dhcpv4/decode.c @@ -36,10 +36,10 @@ #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 @@ -73,7 +73,7 @@ static int fr_dhcpv4_array_members(size_t *out, size_t len, fr_dict_attr_t const /* * 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; @@ -137,7 +137,7 @@ static ssize_t decode_value_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_d /* 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; @@ -193,12 +193,12 @@ static ssize_t decode_value_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_d 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; @@ -220,7 +220,7 @@ static ssize_t decode_raw(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t fr_table_str_by_value(fr_value_box_type_table, parent->type, ""), parent->name, fr_table_str_by_value(fr_value_box_type_table, child->type, ""), 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; @@ -256,16 +256,16 @@ static ssize_t decode_raw(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t /** 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; @@ -281,7 +281,7 @@ static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t 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; } @@ -311,7 +311,7 @@ static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t * 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; @@ -341,7 +341,7 @@ static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t fr_table_str_by_value(fr_value_box_type_table, parent->type, ""), parent->name, fr_table_str_by_value(fr_value_box_type_table, child->type, ""), 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; @@ -355,7 +355,7 @@ static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr_t 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 */ @@ -369,7 +369,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, /* * 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 @@ -385,7 +385,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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; } @@ -395,7 +395,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, */ 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; @@ -428,7 +428,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, * ~ ... ~ 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; @@ -451,7 +451,7 @@ next: * 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 */ @@ -481,14 +481,14 @@ next: 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; @@ -503,13 +503,13 @@ next: /** 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; @@ -552,9 +552,9 @@ ssize_t fr_dhcpv4_decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_table_str_by_value(fr_value_box_type_table, parent->type, ""), parent->name, fr_table_str_by_value(fr_value_box_type_table, da->type, ""), 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; @@ -586,17 +586,14 @@ static int decode_test_ctx(void **out, TALLOC_CTX *ctx) } -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; } diff --git a/src/protocols/dhcpv4/dhcpv4.h b/src/protocols/dhcpv4/dhcpv4.h index 1b9f963e14a..7bedbe4caba 100644 --- a/src/protocols/dhcpv4/dhcpv4.h +++ b/src/protocols/dhcpv4/dhcpv4.h @@ -161,7 +161,7 @@ void fr_dhcpv4_print_hex(FILE *fp, uint8_t const *packet, size_t packet_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); /* @@ -174,7 +174,8 @@ ssize_t fr_dhcpv4_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void * */ 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); diff --git a/src/protocols/dhcpv4/packet.c b/src/protocols/dhcpv4/packet.c index a6642608125..8bef0fc23ea 100644 --- a/src/protocols/dhcpv4/packet.c +++ b/src/protocols/dhcpv4/packet.c @@ -102,19 +102,17 @@ uint8_t const *fr_dhcpv4_packet_get_option(dhcp_packet_t const *packet, size_t p 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", @@ -133,8 +131,7 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d 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; } @@ -193,15 +190,9 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d 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... @@ -219,17 +210,16 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d 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; } @@ -239,7 +229,7 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d * 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) { /* @@ -251,16 +241,15 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d 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) { /* @@ -271,16 +260,15 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d 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); } } } @@ -298,14 +286,14 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d /* * 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. @@ -332,12 +320,12 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d /* * 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) { @@ -365,14 +353,14 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d 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"); @@ -394,7 +382,7 @@ int fr_dhcpv4_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_d * 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; } diff --git a/src/protocols/dhcpv6/base.c b/src/protocols/dhcpv6/base.c index 3588887a321..6b1908eb470 100644 --- a/src/protocols/dhcpv6/base.c +++ b/src/protocols/dhcpv6/base.c @@ -648,12 +648,15 @@ bool fr_dhcpv6_verify(uint8_t const *packet, size_t packet_len, fr_dhcpv6_decode /** 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] */ @@ -665,7 +668,7 @@ ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_l 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: @@ -684,7 +687,7 @@ ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_l &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; @@ -692,7 +695,7 @@ ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_l &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; @@ -701,7 +704,7 @@ ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_l goto fail; } - fr_dcursor_append(cursor, vp); + fr_pair_append(&tmp, vp); p = packet + DHCPV6_RELAY_HDR_LEN; goto decode_options; @@ -716,9 +719,8 @@ ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_l 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; } /* @@ -727,7 +729,7 @@ ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_l (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; @@ -740,28 +742,24 @@ decode_options: * 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. diff --git a/src/protocols/dhcpv6/decode.c b/src/protocols/dhcpv6/decode.c index 88b8460b42c..08bbcd0a43e 100644 --- a/src/protocols/dhcpv6/decode.c +++ b/src/protocols/dhcpv6/decode.c @@ -39,22 +39,22 @@ #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) { @@ -96,24 +96,24 @@ static ssize_t decode_raw(TALLOC_CTX *ctx, fr_dcursor_t *cursor, UNUSED fr_dict_ 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) { @@ -121,16 +121,16 @@ static ssize_t decode_value_trampoline(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr * @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) { @@ -147,7 +147,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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); }; @@ -233,17 +233,12 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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; @@ -255,15 +250,12 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con * 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); @@ -279,12 +271,12 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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) { @@ -309,12 +301,12 @@ static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con * 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); @@ -339,7 +331,7 @@ static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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; } @@ -350,7 +342,7 @@ static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con } 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; } @@ -358,7 +350,7 @@ static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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) { @@ -396,7 +388,7 @@ static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_ 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; @@ -422,7 +414,7 @@ static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_ } vp->type = VT_DATA; - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); } return labels_len; @@ -432,7 +424,7 @@ static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_ /** 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) { @@ -449,11 +441,11 @@ static ssize_t decode_tlvs(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t cons 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; } @@ -465,7 +457,7 @@ static ssize_t decode_tlvs(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t cons } -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) { @@ -482,7 +474,7 @@ static ssize_t decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const /* * 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); @@ -506,10 +498,10 @@ static ssize_t decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const 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) { @@ -553,21 +545,19 @@ static ssize_t decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co */ 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; /* @@ -579,16 +569,16 @@ static ssize_t decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co 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; @@ -605,7 +595,7 @@ static ssize_t decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co * | 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"); @@ -617,7 +607,7 @@ ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t * 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); } /* @@ -647,18 +637,14 @@ static int decode_test_ctx(void **out, TALLOC_CTX *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); } diff --git a/src/protocols/dhcpv6/dhcpv6.h b/src/protocols/dhcpv6/dhcpv6.h index 92ada6524cb..d8f59a5d9af 100644 --- a/src/protocols/dhcpv6/dhcpv6.h +++ b/src/protocols/dhcpv6/dhcpv6.h @@ -158,8 +158,7 @@ bool fr_dhcpv6_verify(uint8_t const *packet, size_t packet_len, fr_dhcpv6_decod 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); @@ -175,5 +174,5 @@ ssize_t fr_dhcpv6_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void * /* * 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); diff --git a/src/protocols/dns/decode.c b/src/protocols/dns/decode.c index 4e0d5ecac3f..459d56ca624 100644 --- a/src/protocols/dns/decode.c +++ b/src/protocols/dns/decode.c @@ -39,7 +39,7 @@ #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) { @@ -81,40 +81,40 @@ static ssize_t decode_raw(TALLOC_CTX *ctx, fr_dcursor_t *cursor, UNUSED fr_dict_ 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) { @@ -131,7 +131,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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); }; @@ -198,7 +198,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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; @@ -208,7 +208,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con #if 0 { - fr_dcursor_t child_cursor; + fr_pair_list_t child_cursor; fr_pair_list_t head; fr_pair_list_init(&head); @@ -223,8 +223,8 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con * 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; @@ -249,12 +249,12 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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) { @@ -280,12 +280,12 @@ static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con * 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); @@ -311,7 +311,7 @@ static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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; } @@ -322,7 +322,7 @@ static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con } 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; } @@ -330,8 +330,7 @@ static ssize_t decode_array(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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) { @@ -401,14 +400,14 @@ static ssize_t decode_dns_labels(TALLOC_CTX *ctx, fr_dcursor_t *cursor, UNUSED f } 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) { @@ -427,7 +426,7 @@ static ssize_t decode_record(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr 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; @@ -440,7 +439,7 @@ static ssize_t decode_record(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_attr /** 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; @@ -456,7 +455,7 @@ ssize_t fr_dns_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, /* * 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()); @@ -468,7 +467,7 @@ ssize_t fr_dns_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, 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; @@ -476,7 +475,7 @@ ssize_t fr_dns_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, 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); @@ -484,7 +483,7 @@ ssize_t fr_dns_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, 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); @@ -492,7 +491,7 @@ ssize_t fr_dns_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, 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); @@ -507,13 +506,13 @@ ssize_t fr_dns_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, /** 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; @@ -539,7 +538,7 @@ static ssize_t fr_dns_decode_rr(TALLOC_CTX *ctx, fr_dcursor_t *cursor, 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; @@ -572,9 +571,8 @@ static int decode_test_ctx(void **out, TALLOC_CTX *ctx) 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 */ @@ -594,9 +592,6 @@ static ssize_t fr_dns_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_ } #endif - fr_pair_list_init(list); - fr_dcursor_init(&cursor, list); - packet_ctx->packet = data; packet_ctx->packet_len = data_len; @@ -616,7 +611,7 @@ static ssize_t fr_dns_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_ 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); } /* diff --git a/src/protocols/dns/dns.h b/src/protocols/dns/dns.h index 502b07121a9..0e2ca23b535 100644 --- a/src/protocols/dns/dns.h +++ b/src/protocols/dns/dns.h @@ -115,7 +115,8 @@ bool fr_dns_packet_ok(uint8_t const *packet, size_t packet_len, bool query); 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); diff --git a/src/protocols/internal/decode.c b/src/protocols/internal/decode.c index ab1c1ba6d97..7733cfda41d 100644 --- a/src/protocols/internal/decode.c +++ b/src/protocols/internal/decode.c @@ -151,7 +151,7 @@ static ssize_t internal_decode_group(TALLOC_CTX *ctx, fr_pair_list_t *head, fr_d 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; @@ -314,7 +314,7 @@ static ssize_t internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *head, fr_di 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; @@ -324,12 +324,12 @@ static ssize_t internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *head, fr_di 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; @@ -338,7 +338,7 @@ static ssize_t internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *head, fr_di * 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; } @@ -348,27 +348,28 @@ static ssize_t internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *head, fr_di /** 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); } diff --git a/src/protocols/internal/internal.h b/src/protocols/internal/internal.h index e58be34929d..2d8e7e91960 100644 --- a/src/protocols/internal/internal.h +++ b/src/protocols/internal/internal.h @@ -43,8 +43,8 @@ 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); diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index 327707b1672..6f87c41a81c 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -1023,8 +1023,9 @@ ssize_t fr_radius_encode_dbuff(fr_dbuff_t *dbuff, uint8_t const *original, /** 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; @@ -1043,7 +1044,7 @@ ssize_t fr_radius_decode(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_l * 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); diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index 3d87d621f46..2806c6755d4 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -345,7 +345,7 @@ int fr_radius_decode_tlv_ok(uint8_t const *data, size_t length, size_t dv_type, /** 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) { @@ -407,7 +407,7 @@ static ssize_t decode_concat(TALLOC_CTX *ctx, fr_dcursor_t *cursor, p += ptr[1] - 2; ptr += ptr[1]; } - fr_dcursor_append(cursor, vp); + fr_pair_append(list, vp); return ptr - data; } @@ -417,7 +417,7 @@ static ssize_t decode_concat(TALLOC_CTX *ctx, fr_dcursor_t *cursor, * 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) { @@ -512,7 +512,7 @@ static ssize_t decode_nas_filter_rule(TALLOC_CTX *ctx, fr_dcursor_t *cursor, talloc_free(vp); return -1; } - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); } /* @@ -529,14 +529,14 @@ static ssize_t decode_nas_filter_rule(TALLOC_CTX *ctx, fr_dcursor_t *cursor, /** 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; @@ -555,10 +555,10 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co 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; @@ -573,7 +573,7 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co * 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; @@ -593,15 +593,15 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co } 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; } @@ -610,7 +610,7 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t co * * "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) @@ -689,7 +689,7 @@ static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dic 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); @@ -711,7 +711,7 @@ static ssize_t decode_vsa_internal(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dic * * 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) @@ -734,7 +734,7 @@ static ssize_t decode_extended(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t * 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; @@ -791,7 +791,7 @@ static ssize_t decode_extended(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t 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; @@ -803,7 +803,7 @@ static ssize_t decode_extended(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t * * @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) @@ -843,7 +843,7 @@ static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con * 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; @@ -961,7 +961,7 @@ static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con 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; @@ -973,7 +973,7 @@ static ssize_t decode_wimax(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con /** 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) @@ -985,7 +985,7 @@ static ssize_t CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *curso 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); @@ -1056,7 +1056,7 @@ static ssize_t CC_HINT(nonnull) decode_vsa(TALLOC_CTX *ctx, fr_dcursor_t *curso * 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; } @@ -1078,18 +1078,18 @@ create_attrs: 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; } @@ -1098,9 +1098,7 @@ create_attrs: 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 @@ -1119,22 +1117,22 @@ create_attrs: * 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); } @@ -1153,7 +1151,7 @@ static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t const * - 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) @@ -1266,9 +1264,8 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di 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); } } @@ -1389,7 +1386,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di * 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; @@ -1454,7 +1451,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di * 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; @@ -1468,7 +1465,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di * 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; } @@ -1497,7 +1494,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di * 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; @@ -1517,7 +1514,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di * 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 */ @@ -1549,11 +1546,11 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di * "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; @@ -1566,7 +1563,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di * 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; @@ -1701,20 +1698,20 @@ done: 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; @@ -1759,7 +1756,7 @@ ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t c 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; @@ -1770,12 +1767,12 @@ ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t c */ 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); } /* @@ -1784,7 +1781,7 @@ ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t c * 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; @@ -1822,22 +1819,19 @@ static int decode_test_ctx(void **out, TALLOC_CTX *ctx) 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 */ @@ -1847,7 +1841,7 @@ static ssize_t fr_radius_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uin 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) { @@ -1855,13 +1849,12 @@ static ssize_t fr_radius_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *list, uin 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); } /* diff --git a/src/protocols/radius/packet.c b/src/protocols/radius/packet.c index a029fe2c392..6504189dfb8 100644 --- a/src/protocols/radius/packet.c +++ b/src/protocols/radius/packet.c @@ -103,8 +103,9 @@ ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_pair_list_t *list /** 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 @@ -115,22 +116,19 @@ ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_pair_list_t *list * - 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 @@ -180,9 +178,8 @@ int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_pair_list_t *list, 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. @@ -194,11 +191,11 @@ int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_pair_list_t *list, * 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; } @@ -207,26 +204,21 @@ int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_pair_list_t *list, */ 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; } @@ -235,10 +227,7 @@ int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_pair_list_t *list, 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 diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index 96f8b39975c..4dc45bddfda 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -128,8 +128,9 @@ ssize_t fr_radius_encode(uint8_t *packet, size_t packet_len, uint8_t const *ori 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); @@ -141,10 +142,10 @@ void fr_radius_free(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)); @@ -206,15 +207,15 @@ ssize_t fr_radius_decode_password(char *encpw, size_t len, char const *secret, 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); diff --git a/src/protocols/tacacs/decode.c b/src/protocols/tacacs/decode.c index 4d0c4997c3b..c067a8c0d58 100644 --- a/src/protocols/tacacs/decode.c +++ b/src/protocols/tacacs/decode.c @@ -55,16 +55,16 @@ 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) @@ -73,7 +73,7 @@ /** * 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; @@ -174,7 +174,7 @@ static int tacacs_decode_args(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_att goto next; } - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); next: p += arg_list[i]; @@ -187,7 +187,7 @@ static int tacacs_decode_args(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_att /** * 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; @@ -217,7 +217,7 @@ static int tacacs_decode_field(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_at *field_data = p; } - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); return 0; } @@ -225,7 +225,8 @@ static int tacacs_decode_field(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_at /** * 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; @@ -301,7 +302,7 @@ ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, uint8_t const *buffer, size_t buffer_l /* * 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; } @@ -574,7 +575,7 @@ ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, uint8_t const *buffer, size_t buffer_l /* * 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)) { @@ -625,7 +626,7 @@ ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, uint8_t const *buffer, size_t buffer_l /* * 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 { @@ -688,7 +689,7 @@ ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, uint8_t const *buffer, size_t buffer_l /* * 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)) { @@ -738,15 +739,12 @@ ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, uint8_t const *buffer, size_t buffer_l /* * 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) diff --git a/src/protocols/tacacs/tacacs.h b/src/protocols/tacacs/tacacs.h index 7fc00ac0178..dbb6caa0641 100644 --- a/src/protocols/tacacs/tacacs.h +++ b/src/protocols/tacacs/tacacs.h @@ -303,7 +303,8 @@ typedef struct { 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); diff --git a/src/protocols/tftp/tftp.c b/src/protocols/tftp/tftp.c index d0c65b8c8a7..f07774b539e 100644 --- a/src/protocols/tftp/tftp.c +++ b/src/protocols/tftp/tftp.c @@ -73,7 +73,7 @@ RCSID("$Id$") * 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; @@ -96,7 +96,7 @@ int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu if (!vp) goto error; vp->vp_uint16 = opcode; - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); p += 2; switch (opcode) { @@ -131,7 +131,7 @@ int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu 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 */; /* */ @@ -156,7 +156,7 @@ int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu goto error; } - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); p += 1 /* \0 */; if (p >= end) goto done; @@ -186,7 +186,7 @@ int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu } vp->vp_uint16 = (uint16_t)blksize; - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); } break; @@ -206,7 +206,7 @@ int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu vp->vp_uint16 = fr_net_to_uint16(p); - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); /* * From that point... @@ -227,7 +227,7 @@ int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu if (!vp) goto error; fr_pair_value_memdup(vp, p, (end - p), true); - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); break; @@ -248,7 +248,7 @@ int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu vp->vp_uint16 = fr_net_to_uint16(p); - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); p += 2; /* */ q = memchr(p, '\0', (end - p)); @@ -258,7 +258,7 @@ int fr_tftp_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu 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; @@ -442,14 +442,10 @@ typedef struct { /* * 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) diff --git a/src/protocols/tftp/tftp.h b/src/protocols/tftp/tftp.h index b9df00aff2e..6dc68487851 100644 --- a/src/protocols/tftp/tftp.h +++ b/src/protocols/tftp/tftp.h @@ -80,7 +80,8 @@ extern "C" { #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 */ diff --git a/src/protocols/vmps/vmps.c b/src/protocols/vmps/vmps.c index 69348f5fc56..81e12d3bc6d 100644 --- a/src/protocols/vmps/vmps.c +++ b/src/protocols/vmps/vmps.c @@ -146,7 +146,7 @@ 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) { uint8_t const *ptr, *end; int attr; @@ -165,14 +165,14 @@ int fr_vmps_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu 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; @@ -181,7 +181,7 @@ int fr_vmps_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu 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; @@ -233,7 +233,7 @@ int fr_vmps_decode(TALLOC_CTX *ctx, uint8_t const *data, size_t data_len, fr_dcu ptr += attr_len; vp->vp_tainted = true; DEBUG2("&%pP", vp); - fr_dcursor_append(cursor, vp); + fr_pair_append(out, vp); } /* @@ -537,14 +537,10 @@ void fr_vmps_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len) /* * 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) diff --git a/src/protocols/vmps/vmps.h b/src/protocols/vmps/vmps.h index 025398cd63e..9628dd1e8cb 100644 --- a/src/protocols/vmps/vmps.h +++ b/src/protocols/vmps/vmps.h @@ -36,7 +36,7 @@ extern "C" { 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);