From: Nick Porter Date: Thu, 4 Aug 2022 10:24:06 +0000 (+0100) Subject: Add fr_internal_decode_list_dbuff() to decode an entire list of attributes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a0d91813b446a9136df1398be87dce9fcb9073a1;p=thirdparty%2Ffreeradius-server.git Add fr_internal_decode_list_dbuff() to decode an entire list of attributes --- diff --git a/src/protocols/internal/decode.c b/src/protocols/internal/decode.c index 8cb34bc9b87..dca5766de88 100644 --- a/src/protocols/internal/decode.c +++ b/src/protocols/internal/decode.c @@ -362,6 +362,56 @@ ssize_t fr_internal_decode_pair_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_d return fr_dbuff_set(dbuff, &work_dbuff); } +static fr_dict_attr_t const *attr_protocol_encapsulation; + +/** Retrieve all pairs from the dbuff + * + * @param ctx to create new pairs in + * @param out list to append pairs to + * @param parent attribute within which which to decode + * @param dbuff to parse + * @param decode_ctx to pass to decoder funtion + * @return + * - bytes of dbuff consumed + * - < 0 on error + */ +ssize_t fr_internal_decode_list_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, + fr_dbuff_t *dbuff, void *decode_ctx) +{ + ssize_t ret, len = 0; + fr_pair_t *vp = NULL; + fr_pair_t *child, *grandchild; + + while (fr_dbuff_remaining(dbuff)) { + ret = fr_internal_decode_pair_dbuff(ctx, out, parent, dbuff, decode_ctx); + if (ret < 0) return ret; + len += ret; + } + + if (!attr_protocol_encapsulation) { + attr_protocol_encapsulation = fr_dict_attr_by_name(NULL, fr_dict_root(fr_dict_internal()), "Protocol-Encapsulation"); + } + + /* + * Move any attributes inside Protocol-Encapsulation and it's child protocol + * attributes to the parent list + */ + while ((vp = fr_pair_find_by_da(out, NULL, attr_protocol_encapsulation))) { + while ((child = fr_pair_list_head(&vp->children))) { + fr_pair_remove(&vp->children, child); + while ((grandchild = fr_pair_list_head(&child->children))) { + fr_pair_remove(&child->children, grandchild); + fr_pair_steal_append(ctx, out, grandchild); + } + talloc_free(child); + } + fr_pair_remove(out, vp); + talloc_free(vp); + } + + return len; +} + /* * Test points */ diff --git a/src/protocols/internal/internal.h b/src/protocols/internal/internal.h index 5622f42f37b..c8ecc55faef 100644 --- a/src/protocols/internal/internal.h +++ b/src/protocols/internal/internal.h @@ -50,3 +50,6 @@ ssize_t fr_internal_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_at ssize_t fr_internal_decode_pair_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *dbuff, void *decode_ctx); + +ssize_t fr_internal_decode_list_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, + fr_dbuff_t *dbuff, void *decode_ctx);