You should wait for 2520s
```
-=== +%{pack: &Attribute-Name &Attribute-Name ...}+
+=== +%{pack:%{Attribute-Name}%{Attribute-Name}...}+
-Pack multiple multiple attributes into a binary string. For best
-results, each attribute passed to `pack` should be fixed size. That
-is, not data type `octets` or `string`.
+Pack multiple multiple attributes and/or literals into a binary string.
+For best results, each attribute passed to `pack` should be fixed size.
+That is, not data type `octets` or `string` as the length of those values
+will not be encoded.
See also the `unpack` module, which is the inverse to `pack`.
[source,unlang]
----
update reply {
- &Class := "%{pack:&reply:Framed-IP-Address &NAS-IP-Address}"
+ &Class := "%{pack:%{reply:Framed-IP-Address}%{NAS-IP-Address}}"
}
----
/** Prints the name of the current module processing the request
*
- * For example will expand to "echo" (not "exec") in
+ * For example will expand to "echo" (not "exec") in
@verbatim
exec echo {
...
*
* Example:
@verbatim
-"%{pack:&Attr-Foo &Attr-bar}" == packed hex values of the attributes
+"%{pack:%{Attr-Foo}%{Attr-bar}" == packed hex values of the attributes
@endverbatim
*
* @ingroup xlat_functions
REQUEST *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
fr_value_box_t **in)
{
- fr_value_box_t *vb;
- VALUE_PAIR *vp;
- fr_cursor_t *cursor;
- char *buffer, *p, *next;
+ fr_value_box_t *vb, *in_vb;
+ fr_cursor_t cursor;
if (!*in) {
- REDEBUG("Missing attribute reference");
+ REDEBUG("Missing input boxes");
return XLAT_ACTION_FAIL;
}
- /*
- * Concatenate all input into a list of attribute references.
- */
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
- RPEDEBUG("Failed concatenating input");
- return XLAT_ACTION_FAIL;
- }
-
- buffer = talloc_strdup(ctx, (*in)->vb_strvalue);
+ MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_OCTETS, NULL, false));
/*
- * Allocate the initial box
+ * Loop over the input boxes, packing them together.
*/
- MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_OCTETS, NULL, false));
- for (p = buffer; p != NULL; p = next) {
- next = strchr(p, ' ');
- if (next) {
- while (isspace((int) *next)) {
- *(next++) = '\0';
- }
- }
-
- if (xlat_fmt_to_cursor(NULL, &cursor, NULL, request, p) < 0) {
- fail:
- talloc_free(buffer);
- talloc_free(vb);
- return XLAT_ACTION_FAIL;
- }
+ for (in_vb = fr_cursor_init(&cursor, in);
+ in_vb;
+ in_vb = fr_cursor_next(&cursor)) {
+ fr_value_box_t *cast, box;
- /*
- * Loop over the input attributes, packing them together.
- */
- for (vp = fr_cursor_head(cursor);
- vp;
- vp = fr_cursor_next(cursor)) {
- fr_value_box_t *cast, box;
-
- if (vp->da->type != FR_TYPE_OCTETS) {
- if (fr_value_box_cast(ctx, &box, FR_TYPE_OCTETS, NULL, &vp->data) < 0) goto fail2;
- cast = &box;
- } else {
- cast = &vp->data;
+ if (in_vb->type != FR_TYPE_OCTETS) {
+ if (fr_value_box_cast(ctx, &box, FR_TYPE_OCTETS, NULL, in_vb) < 0) {
+ error:
+ talloc_free(vb);
+ RPEDEBUG("Failed packing value");
+ return XLAT_ACTION_FAIL;
}
+ cast = &box;
+ } else {
+ cast = in_vb;
+ }
- if (vb->datum.length == 0) {
- (void) fr_value_box_memcpy(vb, vb, NULL, cast->vb_octets, cast->datum.length, cast->tainted);
+ if (vb->vb_length == 0) {
+ (void) fr_value_box_memcpy(vb, vb, NULL, cast->vb_octets, cast->vb_length, cast->tainted);
- } else if (fr_value_box_append_mem(vb, cast->vb_octets, cast->datum.length, cast->tainted) < 0) {
- fail2:
- talloc_free(cursor);
- goto fail;
- }
-
- fr_assert(vb->vb_octets != NULL);
+ } else if (fr_value_box_append_mem(vb, cast->vb_octets, cast->vb_length, cast->tainted) < 0) {
+ goto error;
}
- talloc_free(cursor);
+
+ fr_assert(vb->vb_octets != NULL);
}
- talloc_free(buffer);
fr_cursor_append(out, vb);
return XLAT_ACTION_DONE;
}
-
/** Encode attributes as a series of string attribute/value pairs
*
* This is intended to serialize one or more attributes as a comma