summaryrefslogtreecommitdiff
path: root/src/libimcv/ietf
diff options
context:
space:
mode:
Diffstat (limited to 'src/libimcv/ietf')
-rw-r--r--src/libimcv/ietf/ietf_attr.c11
-rw-r--r--src/libimcv/ietf/ietf_attr.h24
-rw-r--r--src/libimcv/ietf/ietf_attr_pa_tnc_error.c13
-rw-r--r--src/libimcv/ietf/ietf_attr_pa_tnc_error.h16
-rw-r--r--src/libimcv/ietf/swima/ietf_swima_attr_req.c4
-rw-r--r--src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c130
-rw-r--r--src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c66
7 files changed, 133 insertions, 131 deletions
diff --git a/src/libimcv/ietf/ietf_attr.c b/src/libimcv/ietf/ietf_attr.c
index 44e0ef24f..b1bcd9214 100644
--- a/src/libimcv/ietf/ietf_attr.c
+++ b/src/libimcv/ietf/ietf_attr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2017 Andreas Steffen
+ * Copyright (C) 2011-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -30,9 +30,7 @@
#include "ietf/swima/ietf_swima_attr_sw_ev.h"
#include "generic/generic_attr_bool.h"
-
-ENUM_BEGIN(ietf_attr_names, IETF_ATTR_TESTING,
- IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED,
+ENUM(ietf_attr_names, IETF_ATTR_TESTING, IETF_ATTR_SRC_METADATA_RESP,
"Testing",
"Attribute Request",
"Product Information",
@@ -46,10 +44,6 @@ ENUM_BEGIN(ietf_attr_names, IETF_ATTR_TESTING,
"Remediation Instructions",
"Forwarding Enabled",
"Factory Default Password Enabled",
-);
-ENUM_NEXT(ietf_attr_names, IETF_ATTR_SWIMA_REQUEST,
- IETF_ATTR_SRC_METADATA_RESP,
- IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED,
"SWIMA Request",
"SW Identifier Inventory",
"SW Identifier Events",
@@ -60,7 +54,6 @@ ENUM_NEXT(ietf_attr_names, IETF_ATTR_SWIMA_REQUEST,
"SW Source Metadata Request",
"SW Source Metadata Response",
);
-ENUM_END(ietf_attr_names, IETF_ATTR_SRC_METADATA_RESP);
/**
* See header
diff --git a/src/libimcv/ietf/ietf_attr.h b/src/libimcv/ietf/ietf_attr.h
index cbf4a49a2..0f802fd45 100644
--- a/src/libimcv/ietf/ietf_attr.h
+++ b/src/libimcv/ietf/ietf_attr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2017 Andreas Steffen
+ * Copyright (C) 2011-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@ typedef enum ietf_attr_t ietf_attr_t;
*/
enum ietf_attr_t {
- /* RFC 5792 */
+ /* RFC 5792 PA-TNC */
IETF_ATTR_TESTING = 0,
IETF_ATTR_ATTRIBUTE_REQUEST = 1,
IETF_ATTR_PRODUCT_INFORMATION = 2,
@@ -47,16 +47,16 @@ enum ietf_attr_t {
IETF_ATTR_FORWARDING_ENABLED = 11,
IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED = 12,
- /* draft-ietf-sacm-nea-swid-patnc */
- IETF_ATTR_SWIMA_REQUEST = 17,
- IETF_ATTR_SW_ID_INVENTORY = 18,
- IETF_ATTR_SW_ID_EVENTS = 19,
- IETF_ATTR_SW_INVENTORY = 20,
- IETF_ATTR_SW_EVENTS = 21,
- IETF_ATTR_SUBSCRIPTION_STATUS_REQ = 22,
- IETF_ATTR_SUBSCRIPTION_STATUS_RESP = 23,
- IETF_ATTR_SRC_METADATA_REQ = 24,
- IETF_ATTR_SRC_METADATA_RESP = 25,
+ /* RFC 8412 SWIMA */
+ IETF_ATTR_SWIMA_REQUEST = 13,
+ IETF_ATTR_SW_ID_INVENTORY = 14,
+ IETF_ATTR_SW_ID_EVENTS = 15,
+ IETF_ATTR_SW_INVENTORY = 16,
+ IETF_ATTR_SW_EVENTS = 17,
+ IETF_ATTR_SUBSCRIPTION_STATUS_REQ = 18,
+ IETF_ATTR_SUBSCRIPTION_STATUS_RESP = 19,
+ IETF_ATTR_SRC_METADATA_REQ = 20,
+ IETF_ATTR_SRC_METADATA_RESP = 21,
IETF_ATTR_RESERVED = 0xffffffff,
};
diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c
index 75f279298..e543c63ea 100644
--- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c
+++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2017 Andreas Steffen
+ * Copyright (C) 2011-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,23 +20,18 @@
#include <bio/bio_reader.h>
#include <utils/debug.h>
-ENUM_BEGIN(pa_tnc_error_code_names, PA_ERROR_RESERVED,
- PA_ERROR_ATTR_TYPE_NOT_SUPPORTED,
+ENUM(pa_tnc_error_code_names, PA_ERROR_RESERVED,
+ PA_ERROR_SWIMA_SUBSCRIPTION_ID_REUSE,
"Reserved",
"Invalid Parameter",
"Version Not Supported",
- "Attribute Type Not Supported"
-);
-ENUM_NEXT(pa_tnc_error_code_names, PA_ERROR_SWIMA,
- PA_ERROR_SWIMA_SUBSCRIPTION_ID_REUSE,
- PA_ERROR_ATTR_TYPE_NOT_SUPPORTED,
+ "Attribute Type Not Supported",
"SWIMA Error",
"SWIMA Subscription Denied",
"SWIMA Response Too Large",
"SWIMA Subscription Fulfillment Error",
"SWIMA Subscription ID Reuse"
);
-ENUM_END(pa_tnc_error_code_names, PA_ERROR_SWIMA_SUBSCRIPTION_ID_REUSE);
typedef struct private_ietf_attr_pa_tnc_error_t private_ietf_attr_pa_tnc_error_t;
diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h
index dd0be72ff..d5cba97b6 100644
--- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h
+++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2017 Andreas Steffen
+ * Copyright (C) 2011-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@ typedef enum pa_tnc_error_code_t pa_tnc_error_code_t;
#include "pa_tnc/pa_tnc_attr.h"
/**
- * IETF Standard PA-TNC Error Codes as defined in section 4.2.8 of RFC 5792
+ * IETF Standard PA-TNC Error Codes
*/
enum pa_tnc_error_code_t {
@@ -39,12 +39,12 @@ enum pa_tnc_error_code_t {
PA_ERROR_ATTR_TYPE_NOT_SUPPORTED = 3,
PA_ERROR_PA_TNC_MSG_ROOF = 3,
- /* draft-ietf-sacm-nea-swid-patnc (SWIMA) */
- PA_ERROR_SWIMA = 32,
- PA_ERROR_SWIMA_SUBSCRIPTION_DENIED = 33,
- PA_ERROR_SWIMA_RESPONSE_TOO_LARGE = 34,
- PA_ERROR_SWIMA_SUBSCRIPTION_FULFILLMENT = 35,
- PA_ERROR_SWIMA_SUBSCRIPTION_ID_REUSE = 36
+ /* RFC 8412 SWIMA */
+ PA_ERROR_SWIMA = 4,
+ PA_ERROR_SWIMA_SUBSCRIPTION_DENIED = 5,
+ PA_ERROR_SWIMA_RESPONSE_TOO_LARGE = 6,
+ PA_ERROR_SWIMA_SUBSCRIPTION_FULFILLMENT = 7,
+ PA_ERROR_SWIMA_SUBSCRIPTION_ID_REUSE = 8
};
/**
diff --git a/src/libimcv/ietf/swima/ietf_swima_attr_req.c b/src/libimcv/ietf/swima/ietf_swima_attr_req.c
index d67497373..12212ec18 100644
--- a/src/libimcv/ietf/swima/ietf_swima_attr_req.c
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_req.c
@@ -26,7 +26,7 @@ typedef struct private_ietf_swima_attr_req_t private_ietf_swima_attr_req_t;
/**
* SW Request
- * see section 5.7 of IETF SW Inventory Message and Attributes for PA-TNC
+ * see section 5.7 of RFC 8412 SWIMA
*
* 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -191,7 +191,7 @@ METHOD(pa_tnc_attr_t, process, status_t,
return FAILED;
}
*offset += 2 + sw_id.len;
-
+
sw_record = swima_record_create(0, sw_id, chunk_empty);
this->targets->add(this->targets, sw_record);
}
diff --git a/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c b/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c
index e315c3dbb..47f499518 100644
--- a/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c
@@ -27,7 +27,7 @@ typedef struct private_ietf_swima_attr_sw_ev_t private_ietf_swima_attr_sw_ev_t;
/**
* Software [Identifier] Events
- * see sections 5.9/5.11 of IETF SW Inventory Message and Attributes for PA-TNC
+ * see sections 5.9/5.11 of RFC 8412 SWIMA
*
* 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -165,16 +165,40 @@ METHOD(pa_tnc_attr_t, set_noskip_flag,void,
this->noskip_flag = noskip;
}
+/**
+ * This function is shared with ietf_swima_attr_sw_inv.c
+ **/
+void ietf_swima_attr_sw_ev_build_sw_record(bio_writer_t *writer,
+ uint8_t action, swima_record_t *sw_record, bool has_record)
+{
+ pen_type_t data_model;
+ chunk_t sw_locator;
+
+ data_model = sw_record->get_data_model(sw_record);
+
+ writer->write_uint32(writer, sw_record->get_record_id(sw_record));
+ writer->write_uint24(writer, data_model.vendor_id);
+ writer->write_uint8 (writer, data_model.type);
+ writer->write_uint8 (writer, sw_record->get_source_id(sw_record));
+ writer->write_uint8 (writer, action);
+ writer->write_data16(writer, sw_record->get_sw_id(sw_record, &sw_locator));
+ writer->write_data16(writer, sw_locator);
+
+ if (has_record)
+ {
+ writer->write_data32(writer, sw_record->get_record(sw_record));
+ }
+}
+
METHOD(pa_tnc_attr_t, build, void,
private_ietf_swima_attr_sw_ev_t *this)
{
bio_writer_t *writer;
swima_event_t *sw_event;
swima_record_t *sw_record;
- chunk_t timestamp, sw_id, sw_locator, record;
- pen_type_t data_model;
- uint32_t eid, record_id, last_eid, last_consulted_eid, eid_epoch;
- uint8_t action, source_id;
+ chunk_t timestamp;
+ uint32_t last_eid, last_consulted_eid, eid_epoch;
+ uint8_t action;
enumerator_t *enumerator;
if (this->value.ptr)
@@ -195,29 +219,14 @@ METHOD(pa_tnc_attr_t, build, void,
enumerator = this->events->create_enumerator(this->events);
while (enumerator->enumerate(enumerator, &sw_event))
{
- eid = sw_event->get_eid(sw_event, &timestamp);
action = sw_event->get_action(sw_event);
sw_record = sw_event->get_sw_record(sw_event);
- record_id = sw_record->get_record_id(sw_record);
- data_model = sw_record->get_data_model(sw_record);
- source_id = sw_record->get_source_id(sw_record);
- sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
- writer->write_uint32(writer, eid);
+ writer->write_uint32(writer, sw_event->get_eid(sw_event, &timestamp));
writer->write_data (writer, timestamp);
- writer->write_uint32(writer, record_id);
- writer->write_uint24(writer, data_model.vendor_id);
- writer->write_uint8 (writer, data_model.type);
- writer->write_uint8 (writer, source_id);
- writer->write_uint8 (writer, action);
- writer->write_data16(writer, sw_id);
- writer->write_data16(writer, sw_locator);
-
- if (this->type.type == IETF_ATTR_SW_EVENTS)
- {
- record = sw_record->get_record(sw_record);
- writer->write_data32(writer, record);
- }
+
+ ietf_swima_attr_sw_ev_build_sw_record(writer, action, sw_record,
+ this->type.type == IETF_ATTR_SW_EVENTS);
}
enumerator->destroy(enumerator);
@@ -227,15 +236,56 @@ METHOD(pa_tnc_attr_t, build, void,
writer->destroy(writer);
}
+/**
+ * This function is shared with ietf_swima_attr_sw_inv.c
+ **/
+bool ietf_swima_attr_sw_ev_process_sw_record(bio_reader_t *reader,
+ uint8_t *action, swima_record_t **sw_record, bool has_record)
+{
+ pen_type_t data_model;
+ swima_record_t *sw_rec;
+ uint32_t data_model_pen, record_id;
+ uint8_t data_model_type, source_id, reserved;
+ chunk_t sw_id, sw_locator, record = chunk_empty;
+
+ if (!reader->read_uint32(reader, &record_id) ||
+ !reader->read_uint24(reader, &data_model_pen) ||
+ !reader->read_uint8 (reader, &data_model_type) ||
+ !reader->read_uint8 (reader, &source_id) ||
+ !reader->read_uint8 (reader, &reserved) ||
+ !reader->read_data16(reader, &sw_id) ||
+ !reader->read_data16(reader, &sw_locator))
+ {
+ return FALSE;
+ }
+
+ if (action)
+ {
+ *action = reserved;
+ }
+
+ if (has_record && !reader->read_data32(reader, &record))
+ {
+ return FALSE;
+ }
+
+ data_model = pen_type_create(data_model_pen, data_model_type);
+ sw_rec = swima_record_create(record_id, sw_id, sw_locator);
+ sw_rec->set_data_model(sw_rec, data_model);
+ sw_rec->set_source_id(sw_rec, source_id);
+ sw_rec->set_record(sw_rec, record);
+ *sw_record = sw_rec;
+
+ return TRUE;
+}
+
METHOD(pa_tnc_attr_t, process, status_t,
private_ietf_swima_attr_sw_ev_t *this, uint32_t *offset)
{
bio_reader_t *reader;
- uint32_t data_model_pen, record_id;
uint32_t eid, eid_epoch, last_eid, last_consulted_eid;
- uint8_t data_model_type, source_id, action;
- pen_type_t data_model;
- chunk_t sw_id, sw_locator, record, timestamp;
+ uint8_t action;
+ chunk_t timestamp;
swima_event_t *sw_event;
swima_record_t *sw_record;
status_t status = NEED_MORE;
@@ -273,38 +323,24 @@ METHOD(pa_tnc_attr_t, process, status_t,
{
if (!reader->read_uint32(reader, &eid) ||
!reader->read_data (reader, SW_EV_TIMESTAMP_SIZE, &timestamp) ||
- !reader->read_uint32(reader, &record_id) ||
- !reader->read_uint24(reader, &data_model_pen) ||
- !reader->read_uint8 (reader, &data_model_type) ||
- !reader->read_uint8 (reader, &source_id) ||
- !reader->read_uint8 (reader, &action) ||
- !reader->read_data16(reader, &sw_id) ||
- !reader->read_data16(reader, &sw_locator))
+ !ietf_swima_attr_sw_ev_process_sw_record(reader, &action, &sw_record,
+ this->type.type == IETF_ATTR_SW_EVENTS))
{
goto end;
}
- record = chunk_empty;
- if (action == 0 || action > SWIMA_EVENT_ACTION_LAST)
+ if (action == SWIMA_EVENT_ACTION_NONE ||
+ action > SWIMA_EVENT_ACTION_LAST)
{
DBG1(DBG_TNC, "invalid event action value for %N/%N", pen_names,
PEN_IETF, ietf_attr_names, this->type.type);
*offset = this->offset;
+ sw_record->destroy(sw_record);
reader->destroy(reader);
return FAILED;
}
- if (this->type.type == IETF_ATTR_SW_EVENTS &&
- !reader->read_data32(reader, &record))
- {
- goto end;
- }
- data_model = pen_type_create(data_model_pen, data_model_type);
- sw_record = swima_record_create(record_id, sw_id, sw_locator);
- sw_record->set_data_model(sw_record, data_model);
- sw_record->set_source_id(sw_record, source_id);
- sw_record->set_record(sw_record, record);
sw_event = swima_event_create(eid, timestamp, action, sw_record);
this->events->add(this->events, sw_event);
this->offset += this->value.len - reader->remaining(reader);
diff --git a/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c b/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c
index ee5b16b92..8035dbb07 100644
--- a/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c
@@ -26,7 +26,7 @@ typedef struct private_ietf_swima_attr_sw_inv_t private_ietf_swima_attr_sw_inv_t
/**
* Software [Identifier] Inventory
- * see sections 5.8/5.10 of IETF SW Inventory Message and Attributes for PA-TNC
+ * see sections 5.8/5.10 of RFC 8412 SWIMA
*
* 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -43,7 +43,9 @@ typedef struct private_ietf_swima_attr_sw_inv_t private_ietf_swima_attr_sw_inv_t
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Data Model Type PEN |Data Model Type|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Source ID Num | Software Identifier Length |Software Id (v)|
+ * | Source ID Num | Reserved | Software Identifier Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Software Identifier (Variable Length) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Software Locator Length | Software Locator (Var. Len) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -148,15 +150,18 @@ METHOD(pa_tnc_attr_t, set_noskip_flag,void,
this->noskip_flag = noskip;
}
+/**
+ * This function is shared with ietf_swima_attr_sw_ev.c
+ **/
+extern void ietf_swima_attr_sw_ev_build_sw_record(bio_writer_t *writer,
+ uint8_t action, swima_record_t *sw_record, bool has_record);
+
METHOD(pa_tnc_attr_t, build, void,
private_ietf_swima_attr_sw_inv_t *this)
{
bio_writer_t *writer;
swima_record_t *sw_record;
- chunk_t sw_id, sw_locator, record;
- pen_type_t data_model;
- uint32_t record_id, last_eid, eid_epoch;
- uint8_t source_id;
+ uint32_t last_eid, eid_epoch;
enumerator_t *enumerator;
if (this->value.ptr)
@@ -175,23 +180,8 @@ METHOD(pa_tnc_attr_t, build, void,
enumerator = this->inventory->create_enumerator(this->inventory);
while (enumerator->enumerate(enumerator, &sw_record))
{
- record_id = sw_record->get_record_id(sw_record);
- data_model = sw_record->get_data_model(sw_record);
- source_id = sw_record->get_source_id(sw_record);
- sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
-
- writer->write_uint32(writer, record_id);
- writer->write_uint24(writer, data_model.vendor_id);
- writer->write_uint8 (writer, data_model.type);
- writer->write_uint8 (writer, source_id);
- writer->write_data16(writer, sw_id);
- writer->write_data16(writer, sw_locator);
-
- if (this->type.type == IETF_ATTR_SW_INVENTORY)
- {
- record = sw_record->get_record(sw_record);
- writer->write_data32(writer, record);
- }
+ ietf_swima_attr_sw_ev_build_sw_record(writer, 0x00, sw_record,
+ this->type.type == IETF_ATTR_SW_INVENTORY);
}
enumerator->destroy(enumerator);
@@ -201,14 +191,17 @@ METHOD(pa_tnc_attr_t, build, void,
writer->destroy(writer);
}
+/**
+ * This function is shared with ietf_swima_attr_sw_ev.c
+ **/
+extern bool ietf_swima_attr_sw_ev_process_sw_record(bio_reader_t *reader,
+ uint8_t *action, swima_record_t **sw_record, bool has_record);
+
METHOD(pa_tnc_attr_t, process, status_t,
private_ietf_swima_attr_sw_inv_t *this, uint32_t *offset)
{
bio_reader_t *reader;
- uint32_t data_model_pen, record_id, last_eid, eid_epoch;
- uint8_t data_model_type, source_id;
- pen_type_t data_model;
- chunk_t sw_id, sw_locator, record;
+ uint32_t last_eid, eid_epoch;
swima_record_t *sw_record;
status_t status = NEED_MORE;
@@ -241,27 +234,12 @@ METHOD(pa_tnc_attr_t, process, status_t,
while (this->record_count)
{
- if (!reader->read_uint32(reader, &record_id) ||
- !reader->read_uint24(reader, &data_model_pen) ||
- !reader->read_uint8 (reader, &data_model_type) ||
- !reader->read_uint8 (reader, &source_id) ||
- !reader->read_data16(reader, &sw_id) ||
- !reader->read_data16(reader, &sw_locator))
+ if (!ietf_swima_attr_sw_ev_process_sw_record(reader, NULL, &sw_record,
+ this->type.type == IETF_ATTR_SW_INVENTORY))
{
goto end;
}
- record = chunk_empty;
- if (this->type.type == IETF_ATTR_SW_INVENTORY &&
- !reader->read_data32(reader, &record))
- {
- goto end;
- }
- data_model = pen_type_create(data_model_pen, data_model_type);
- sw_record = swima_record_create(record_id, sw_id, sw_locator);
- sw_record->set_data_model(sw_record, data_model);
- sw_record->set_source_id(sw_record, source_id);
- sw_record->set_record(sw_record, record);
this->inventory->add(this->inventory, sw_record);
this->offset += this->value.len - reader->remaining(reader);
this->value = reader->peek(reader);