]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add fr_internal_decode_list_dbuff() to decode an entire list of attributes
authorNick Porter <nick@portercomputing.co.uk>
Thu, 4 Aug 2022 10:24:06 +0000 (11:24 +0100)
committerNick Porter <nick@portercomputing.co.uk>
Wed, 17 Aug 2022 07:26:39 +0000 (08:26 +0100)
src/protocols/internal/decode.c
src/protocols/internal/internal.h

index 8cb34bc9b875866a6172dd4d490add68fd86bac6..dca5766de886b85b88ade29b864f8cb6b3f13237 100644 (file)
@@ -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
  */
index 5622f42f37b39d8994c7578b38383572a457821e..c8ecc55faef9e943a040e626305e69defa65136d 100644 (file)
@@ -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);