*/
typedef struct {
fr_dict_attr_t const *root;
+ uint8_t *buffer; //! for coalescing concatenated options
} fr_dhcpv4_ctx_t;
/*
* decode.c
*/
ssize_t fr_dhcpv4_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out,
- uint8_t const *data, size_t len, void *decode_ctx);
+ uint8_t const *data, size_t len, void *decode_ctx) CC_HINT(nonnull);
/*
* encode.c
fr_pair_t *vp;
fr_pair_t *maxms, *mtu, *netaddr;
fr_value_box_t box;
+ fr_dhcpv4_ctx_t *packet_ctx;
fr_pair_list_init(&tmp);
return -1;
}
+ packet_ctx = talloc_zero(ctx, fr_dhcpv4_ctx_t);
+ if (!packet_ctx) return -1;
+
/*
* Decode the header.
*/
error:
talloc_free(vp);
fr_pair_list_free(&tmp);
+ talloc_free(packet_ctx);
return -1;
}
while (p < end) {
if (p[0] == 0) break; /* padding */
- len = fr_dhcpv4_decode_option(ctx, &tmp, p, (end - p), NULL);
+ len = fr_dhcpv4_decode_option(ctx, &tmp, p, (end - p), packet_ctx);
if (len <= 0) {
+ fail:
fr_pair_list_free(&tmp);
+ talloc_free(packet_ctx);
return len;
}
p += len;
if (p[0] == 0) break; /* padding */
len = fr_dhcpv4_decode_option(ctx, &tmp,
- p, end - p, NULL);
- if (len <= 0) {
- fr_pair_list_free(&tmp);
- return len;
- }
+ p, end - p, packet_ctx);
+ if (len <= 0) goto fail;
p += len;
}
fr_pair_delete_by_da(&tmp, attr_dhcp_boot_filename);
if (p[0] == 0) break; /* padding */
len = fr_dhcpv4_decode_option(ctx, &tmp,
- p, end - p, NULL);
- if (len <= 0) {
- fr_pair_list_free(&tmp);
- return len;
- }
+ p, end - p, packet_ctx);
+ if (len <= 0) goto fail;
p += len;
}
fr_pair_delete_by_da(&tmp, attr_dhcp_server_host_name);