osmith has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmocore/+/28237 )
Change subject: tlv_parser: add tlv_parse_order
......................................................................
tlv_parser: add tlv_parse_order
Add a function to retrieve the TLV order of an existing message, so a
new message with the same order can be generated. I'm using this in
osmo-bsc-nat I3caa15666f2dde9ee02182a89edc5daa70e8c3fc.
Related: SYS#5560
Change-Id: I3caa15666f2dde9ee02182a89edc5daa70e8c3fc
---
M include/osmocom/gsm/tlv.h
M src/gsm/libosmogsm.map
M src/gsm/tlv_parser.c
M tests/tlv/tlv_test.c
M tests/tlv/tlv_test.ok
5 files changed, 52 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/37/28237/1
diff --git a/include/osmocom/gsm/tlv.h b/include/osmocom/gsm/tlv.h
index 7e6dfb5..4c638eb 100644
--- a/include/osmocom/gsm/tlv.h
+++ b/include/osmocom/gsm/tlv.h
@@ -534,6 +534,8 @@
int tlv_parse2(struct tlv_parsed *dec, int dec_multiples,
const struct tlv_definition *def, const uint8_t *buf, int buf_len,
uint8_t lv_tag, uint8_t lv_tag2);
+int tlv_parse_order(uint8_t *tag_order, unsigned int tag_order_len,
+ const struct tlv_definition *def, const uint8_t *buf, int buf_len);
/* take a master (src) tlv def and fill up all empty slots in 'dst' */
void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src);
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index b971ca0..7bdb930 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -592,6 +592,7 @@
tlv_dump;
tlv_parse;
tlv_parse2;
+tlv_parse_order;
tlv_parse_one;
tlv_encode;
tlv_encode_ordered;
diff --git a/src/gsm/tlv_parser.c b/src/gsm/tlv_parser.c
index c5aac97..8c188c5 100644
--- a/src/gsm/tlv_parser.c
+++ b/src/gsm/tlv_parser.c
@@ -433,6 +433,42 @@
return num_parsed;
}
+/*! Parse the order of tags used in a buffer of TLV encoded IEs.
+ * \param[out] tag_order array of tags determining the IE encoding order
+ * \param[in] tag_order_len length of tag_order
+ * \param[in] def structure defining the valid TLV tags / configurations
+ * \param[in] buf the input data buffer to be parsed
+ * \param[in] buf_len length of the input data buffer
+ * \returns number of TLV entries parsed; negative in case of error
+ */
+int tlv_parse_order(uint8_t *tag_order, unsigned int tag_order_len, const struct
tlv_definition *def,
+ const uint8_t *buf, int buf_len)
+{
+ int ofs = 0;
+ int num_parsed = 0;
+
+ while (ofs < buf_len) {
+ int rv;
+ uint8_t tag;
+ const uint8_t *val;
+ uint16_t len;
+
+ rv = tlv_parse_one(&tag, &len, &val, def, &buf[ofs], buf_len - ofs);
+ if (rv < 0)
+ return rv;
+
+ if (num_parsed >= tag_order_len)
+ return -1;
+
+ tag_order[num_parsed] = tag;
+
+ ofs += rv;
+ num_parsed++;
+ }
+
+ return num_parsed;
+}
+
/*! take a master (src) tlv_definition and fill up all empty slots in 'dst'
* \param dst TLV parser definition that is to be patched
* \param[in] src TLV parser definition whose content is patched into \a dst */
diff --git a/tests/tlv/tlv_test.c b/tests/tlv/tlv_test.c
index fdd15ab..84e115b 100644
--- a/tests/tlv/tlv_test.c
+++ b/tests/tlv/tlv_test.c
@@ -297,6 +297,7 @@
0x40, 0x42,
};
const uint8_t ie_order[] = { 0x2c, 0x40, 0x17 };
+ uint8_t ie_order_dec[3];
const uint8_t enc_ies_reordered[] = {
0x2c, 0x04,
0x40, 0x42,
@@ -329,6 +330,17 @@
OSMO_ASSERT(rc == ARRAY_SIZE(enc_ies));
OSMO_ASSERT(!memcmp(msgb_data(msg), enc_ies_reordered, ARRAY_SIZE(enc_ies_reordered)));
+ printf("Testing TLV IE order parsing\n");
+
+ /* parse order: array too short */
+ rc = tlv_parse_order(ie_order_dec, 2, gsm0808_att_tlvdef(), enc_ies_reordered,
ARRAY_SIZE(enc_ies));
+ OSMO_ASSERT(rc == -1);
+
+ /* parse order */
+ rc = tlv_parse_order(ie_order_dec, ARRAY_SIZE(ie_order_dec), gsm0808_att_tlvdef(),
enc_ies_reordered, ARRAY_SIZE(enc_ies));
+ OSMO_ASSERT(rc == 3);
+ OSMO_ASSERT(!memcmp(ie_order_dec, ie_order, ARRAY_SIZE(ie_order)));
+
msgb_free(msg);
}
diff --git a/tests/tlv/tlv_test.ok b/tests/tlv/tlv_test.ok
index e24b889..ed96339 100644
--- a/tests/tlv/tlv_test.ok
+++ b/tests/tlv/tlv_test.ok
@@ -1,6 +1,7 @@
Test shift functions
Testing TLV encoder by decoding + re-encoding binary
Testing TLV encoder with IE ordering
+Testing TLV IE order parsing
Testing TLV_TYPE_T decoder for out-of-bounds
Testing TLV_TYPE_TV decoder for out-of-bounds
Testing TLV_TYPE_FIXED decoder for out-of-bounds
--
To view, visit
https://gerrit.osmocom.org/c/libosmocore/+/28237
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I3caa15666f2dde9ee02182a89edc5daa70e8c3fc
Gerrit-Change-Number: 28237
Gerrit-PatchSet: 1
Gerrit-Owner: osmith <osmith(a)sysmocom.de>
Gerrit-MessageType: newchange