break;
default:
- no_vector:
fr_strerror_const("No authentication vector passed for packet decode");
return -1;
}
.subtype_table = subtype_table,
.subtype_table_len = NUM_ELEMENTS(subtype_table),
.attr_valid = attr_valid,
+ .decode = fr_radius_decode_foreign,
+ .encode = fr_radius_encode_foreign,
};
return 2 + ret;
}
+ssize_t fr_radius_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len)
+{
+ ssize_t slen;
+ uint8_t const *attr, *end;
+
+ fr_radius_ctx_t common_ctx = {};
+ fr_radius_decode_ctx_t decode_ctx = {
+ .common = &common_ctx,
+ .tmp_ctx = talloc(ctx, uint8_t),
+ .end = data + data_len,
+ };
+
+ attr = data;
+ end = decode_ctx.end;
+
+ while (attr < end) {
+ slen = fr_radius_decode_pair(ctx, out, attr, (end - attr), &decode_ctx);
+ if (slen < 0) {
+ talloc_free(decode_ctx.tmp_ctx);
+ return slen - (attr - data);
+ }
+
+ /*
+ * If slen is larger than the room in the packet,
+ * all kinds of bad things happen.
+ */
+ if (!fr_cond_assert(slen <= (end - attr))) {
+ talloc_free(decode_ctx.tmp_ctx);
+ return -slen - (attr - data);
+ }
+
+ attr += slen;
+ talloc_free_children(decode_ctx.tmp_ctx);
+ }
+
+ talloc_free(decode_ctx.tmp_ctx);
+ return data_len;
+}
+
+
static int _test_ctx_free(fr_radius_decode_ctx_t *ctx)
{
TALLOC_FREE(ctx->tags);
return fr_dbuff_set(dbuff, &work_dbuff);
}
-static ssize_t encode_tags(fr_dbuff_t *dbuff, fr_pair_list_t const *vps, void *encode_ctx)
+static ssize_t encode_pairs(fr_dbuff_t *dbuff, fr_pair_list_t const *vps, void *encode_ctx)
{
ssize_t slen;
fr_pair_t const *vp;
fr_assert(packet_ctx->tag < 0x20);
// recurse to encode the children of this attribute
- slen = encode_tags(&work_dbuff, &vp->vp_group, encode_ctx);
+ slen = encode_pairs(&work_dbuff, &vp->vp_group, encode_ctx);
packet_ctx->tag = 0;
if (slen < 0) return slen;
return fr_dbuff_set(dbuff, &work_dbuff);
}
+ssize_t fr_radius_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t *list)
+{
+ fr_radius_ctx_t common_ctx = {};
+ fr_radius_encode_ctx_t encode_ctx = {
+ .common = &common_ctx,
+ };
+
+ /*
+ * Just in case we need random numbers.
+ */
+ encode_ctx.rand_ctx.a = fr_rand();
+ encode_ctx.rand_ctx.b = fr_rand();
+
+ /*
+ * Encode the pairs.
+ */
+ return encode_pairs(dbuff, list, &encode_ctx);
+}
+
+
static int _test_ctx_free(UNUSED fr_radius_encode_ctx_t *ctx)
{
fr_radius_free();
*/
ssize_t fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx);
+ssize_t fr_radius_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t *list) CC_HINT(nonnull);
+
/*
* protocols/radius/decode.c
*/
ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *list,
uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx) CC_HINT(nonnull);
+
+ssize_t fr_radius_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out,
+ uint8_t const *data, size_t data_len) CC_HINT(nonnull);