]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add function to get integer, etc. from memory
authorAlan T. DeKok <aland@freeradius.org>
Tue, 13 Jan 2026 21:26:32 +0000 (16:26 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 13 Jan 2026 21:29:04 +0000 (16:29 -0500)
which can then be used by the statistics functions

src/lib/util/value.c
src/lib/util/value.h

index fe81ae305d72536831af67696fccfeb9ee7e40a5..c37c0f763a7bce2dd5a7fa1f55e87d32110a291f 100644 (file)
@@ -2421,6 +2421,77 @@ ssize_t fr_value_box_ipaddr_from_network(fr_value_box_t *dst, fr_type_t type, fr
        return data_len;
 }
 
+/** Decode a #fr_value_box_t from a C type in memory
+ *
+ *  We ignore arrays
+ *
+ * @param[in] ctx      Where to allocate any talloc buffers required.
+ * @param[out] dst     value_box to write the result to.
+ * @param[in] type     to decode data to.
+ * @param[in] enumv    Aliases for values.
+ * @param[in] src      raw pointer to the (possibly unaligned) source
+ * @param[in] len      Length of data to decode.  For fixed length types we only
+ *                     decode complete values.
+ * @return
+ *     - >= 0 The number of bytes consumed.
+ *     - <0 an error occured
+ */
+ssize_t        fr_value_box_from_memory(TALLOC_CTX *ctx,
+                                fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv,
+                                void const *src, size_t len)
+{
+       switch (type) {
+       case FR_TYPE_INTEGER_EXCEPT_BOOL:
+       case FR_TYPE_FLOAT32:
+       case FR_TYPE_FLOAT64:
+               if (len != fr_value_box_field_sizes[type]) {
+                       fr_strerror_printf("Invalid size passed for type %s - expected %zu got %zu",
+                                          fr_type_to_str(type), fr_value_box_field_sizes[type], len);
+                               return -1;
+               }
+
+               fr_value_box_init(dst, type, enumv, false);
+               memcpy(&dst->datum, src, len);
+               break;
+
+       case FR_TYPE_IPV4_ADDR:
+               if (len != sizeof(struct in_addr)) {
+                       fr_strerror_printf("Invalid size passed for type %s - expected %zu got %zu",
+                                          fr_type_to_str(type), sizeof(struct in_addr), len);
+                               return -1;
+               }
+
+               fr_value_box_init(dst, type, enumv, false);
+               memcpy(&dst->vb_ipv4addr, src, len);
+               break;
+
+       case FR_TYPE_IPV6_ADDR:
+               if (len != sizeof(struct in6_addr)) {
+                       fr_strerror_printf("Invalid size passed for type %s - expected %zu got %zu",
+                                          fr_type_to_str(type), sizeof(struct in6_addr), len);
+                       return -1;
+               }
+
+               fr_value_box_init(dst, type, enumv, false);
+               memcpy(&dst->vb_ipv6addr, src, len);
+               break;
+
+       case FR_TYPE_STRING:
+               return fr_value_box_bstrndup(ctx, dst, enumv, src, len, false);
+
+       case FR_TYPE_OCTETS:
+               return fr_value_box_memdup(ctx, dst, enumv, src, len, false);
+
+       default:
+               fr_strerror_printf("Unsupported data type %s",
+                                  fr_type_to_str(type));
+               return -1;
+       }
+
+       return len;
+}
+
+
 /** Get a key from a value box
  *
  * @param[in,out] out - set to a small buffer on input.  If the callback has more data
index 8688d8a66e68d9f02c080b83db41ca59b5be3bfe..3c187f41fb49646d973e622d4137edd1507d77d7 100644 (file)
@@ -1058,6 +1058,11 @@ ssize_t          fr_value_box_ipaddr_from_network(fr_value_box_t *dst, fr_type_t type, f
                                                 int prefix_len, uint8_t const *data, size_t data_len, bool fixed, bool tainted)
                CC_HINT(nonnull(1,5));
 
+ssize_t                fr_value_box_from_memory(TALLOC_CTX *ctx,
+                                        fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv,
+                                        void const *src, size_t len)
+               CC_HINT(nonnull(2,5));
+
 int            fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst,
                                  fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
                                  fr_value_box_t const *src)