Change in libosmocore[master]: Deprecate ipa_ccm_idtag_parse() with ipa_ccm_id_{get, resp}_parse()

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Wed Aug 1 11:31:33 UTC 2018


Harald Welte has uploaded this change for review. ( https://gerrit.osmocom.org/10293


Change subject: Deprecate ipa_ccm_idtag_parse() with ipa_ccm_id_{get,resp}_parse()
......................................................................

Deprecate ipa_ccm_idtag_parse() with ipa_ccm_id_{get,resp}_parse()

In the past, the function ipa_ccm_idtag_parse() was used to parse
the payload of IPA CCM ID RESP packets.  However, the function was
based on a possible misunderstanding of the message encoding, and
callers actually counted the first (upper) length nibble as part
of the header and passed a pointer to the second
(lower) length nibble of the first TLV into this function.  As such,
it was unfixable, and had to be replaced with a new function called
ipa_ccm_id_resp_parse().  At the same time, we also add
ipa_ccm_id_get_parse() to parse the slightly different format of
the IPA CCM ID GET payload.

We can never be 100% sure what is "correct", as our understanding
of the protocol is entirely based on protocol analysis, without any
official documentation available.

This patch also introduces unit test coverage for both of the new
functions.

Change-Id: I1834d90fbcdbfcb05f5b8cfe39bfe9543737ef8f
---
M include/osmocom/gsm/ipa.h
M src/gsm/ipa.c
M src/gsm/libosmogsm.map
M tests/utils/utils_test.c
M tests/utils/utils_test.ok
5 files changed, 151 insertions(+), 6 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/93/10293/1

diff --git a/include/osmocom/gsm/ipa.h b/include/osmocom/gsm/ipa.h
index 7e1d723..ec143d0 100644
--- a/include/osmocom/gsm/ipa.h
+++ b/include/osmocom/gsm/ipa.h
@@ -26,8 +26,14 @@
 /* obtain the human-readable name of an IPA CCM ID TAG */
 const char *ipa_ccm_idtag_name(uint8_t tag);
 
-/* parse a buffer of ID tags into a osmocom TLV style representation */
-int ipa_ccm_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
+int ipa_ccm_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len)
+	OSMO_DEPRECATED("Use ipa_ccm_id_{get,resp}_parse instead");
+
+/* parse payload of IPA CCM ID GET into a osmocom TLV style representation */
+int ipa_ccm_id_get_parse(struct tlv_parsed *dec, const uint8_t *buf, unsigned int len);
+
+/* parse payload of IPA CCM ID RESP into a osmocom TLV style representation */
+int ipa_ccm_id_resp_parse(struct tlv_parsed *dec, const uint8_t *buf, unsigned int len);
 
 /* Is the TAG included in the length field? */
 int ipa_ccm_idtag_parse_off(struct tlv_parsed *dec, unsigned char *buf, int len, const int len_offset);
diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c
index 989e439..3c7c300 100644
--- a/src/gsm/ipa.c
+++ b/src/gsm/ipa.c
@@ -127,6 +127,83 @@
 	return 0;
 }
 
+/*! Parse the payload part of an IPA CCM ID GET, return \ref tlv_parsed format.
+ *  The odd payload format of those messages is structured as follows:
+ *   * 8bit length value (length of payload *and tag*)
+ *   * 8bit tag value
+ *   * optional, variable-length payload
+ *  \param[out] dec Caller-provided/allocated output structure for parsed payload
+ *  \param[in] buf Buffer containing the payload (excluding 1 byte msg_type) of the message
+ *  \param[in] len Length of \a buf in octets
+ *  \returns 0 on success; negative on error */
+int ipa_ccm_id_get_parse(struct tlv_parsed *dec, const uint8_t *buf, unsigned int len)
+{
+	uint8_t t_len;
+	uint8_t t_tag;
+	const uint8_t *cur = buf;
+
+	memset(dec, 0, sizeof(*dec));
+
+	while (len >= 2) {
+		len -= 2;
+		t_len = *cur++;
+		t_tag = *cur++;
+
+		if (t_len > len + 1) {
+			LOGP(DLMI, LOGL_ERROR, "The tag does not fit: %d > %d\n", t_len, len + 1);
+			return -EINVAL;
+		}
+
+		DEBUGPC(DLMI, "%s='%s' ", ipa_ccm_idtag_name(t_tag), cur);
+
+		dec->lv[t_tag].len = t_len-1;
+		dec->lv[t_tag].val = cur;
+
+		cur += t_len-1;
+		len -= t_len-1;
+	}
+	return 0;
+}
+
+/*! Parse the payload part of an IPA CCM ID RESP, return \ref tlv_parsed format.
+ *  The odd payload format of those messages is structured as follows:
+ *   * 16bit length value (length of payload *and tag*)
+ *   * 8bit tag value
+ *   * optional, variable-length payload
+ *  \param[out] dec Caller-provided/allocated output structure for parsed payload
+ *  \param[in] buf Buffer containing the payload (excluding 1 byte msg_type) of the message
+ *  \param[in] len Length of \a buf in octets
+ *  \returns 0 on success; negative on error */
+int ipa_ccm_id_resp_parse(struct tlv_parsed *dec, const uint8_t *buf, unsigned int len)
+{
+	uint8_t t_len;
+	uint8_t t_tag;
+	const uint8_t *cur = buf;
+
+	memset(dec, 0, sizeof(*dec));
+
+	while (len >= 3) {
+		len -= 3;
+		t_len = *cur++ << 8;
+		t_len += *cur++;
+		t_tag = *cur++;
+
+		if (t_len > len + 1) {
+			LOGP(DLMI, LOGL_ERROR, "The tag does not fit: %d > %d\n", t_len, len + 1);
+			return -EINVAL;
+		}
+
+		DEBUGPC(DLMI, "%s='%s' ", ipa_ccm_idtag_name(t_tag), cur);
+
+		dec->lv[t_tag].len = t_len-1;
+		dec->lv[t_tag].val = cur;
+
+		cur += t_len-1;
+		len -= t_len-1;
+	}
+	return 0;
+}
+
 int ipa_parse_unitid(const char *str, struct ipaccess_unit *unit_data)
 {
 	unsigned long ul;
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index f168e5f..a1d342a 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -461,6 +461,8 @@
 ipa_ccm_tlv_to_unitdata;
 ipa_ccm_idtag_name;
 ipa_ccm_idtag_parse;
+ipa_ccm_id_get_parse;
+ipa_ccm_id_resp_parse;
 ipa_ccm_make_id_resp;
 ipa_ccm_make_id_resp_from_req;
 ipa_msg_alloc;
diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c
index eec13ca..2f1e87d 100644
--- a/tests/utils/utils_test.c
+++ b/tests/utils/utils_test.c
@@ -21,6 +21,7 @@
  */
 
 #include <osmocom/gsm/ipa.h>
+#include <osmocom/gsm/protocol/ipaccess.h>
 
 #include <osmocom/core/logging.h>
 #include <osmocom/core/utils.h>
@@ -170,13 +171,65 @@
 	printf("rc = %d\n", rc);
 }
 
-static void test_idtag_parsing(void)
+static void test_ipa_ccm_id_resp_parsing(void)
+{
+	struct tlv_parsed tvp;
+	int rc;
+
+	static const uint8_t id_resp_data[] = {
+		0x00, 0x13,	IPAC_IDTAG_MACADDR,
+			'0','0',':','0','2',':','9','5',':','0','0',':','6','2',':','9','e','\0',
+		0x00, 0x11,	IPAC_IDTAG_IPADDR,
+			'1','9','2','.','1','6','8','.','1','0','0','.','1','9','0','\0',
+		0x00, 0x0a,	IPAC_IDTAG_UNIT,
+			'1','2','3','4','/','0','/','0','\0',
+		0x00, 0x02,	IPAC_IDTAG_LOCATION1,
+			'\0',
+		0x00, 0x0d,	IPAC_IDTAG_LOCATION2,
+			'B','T','S','_','N','B','T','1','3','1','G','\0',
+		0x00, 0x0c,	IPAC_IDTAG_EQUIPVERS,
+			'1','6','5','a','0','2','9','_','5','5','\0',
+		0x00, 0x14,	IPAC_IDTAG_SWVERSION,
+			'1','6','8','d','4','7','2','_','v','2','0','0','b','4','1','1','d','0','\0',
+		0x00, 0x18,	IPAC_IDTAG_UNITNAME,
+			'n','b','t','s','-','0','0','-','0','2','-','9','5','-','0','0','-','6','2','-','9','E','\0',
+		0x00, 0x0a,	IPAC_IDTAG_SERNR,
+			'0','0','1','1','0','7','8','1','\0'
+	};
+
+	printf("\nTesting IPA CCM ID RESP parsing\n");
+
+	rc = ipa_ccm_id_resp_parse(&tvp, (uint8_t *) id_resp_data, sizeof(id_resp_data));
+	OSMO_ASSERT(rc == 0);
+
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_MACADDR));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_MACADDR) == 0x12);
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_IPADDR));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_IPADDR) == 0x10);
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_UNIT));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_UNIT) == 0x09);
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_LOCATION1));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_LOCATION1) == 0x01);
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_LOCATION2));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_LOCATION2) == 0x0c);
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_EQUIPVERS));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_EQUIPVERS) == 0x0b);
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_SWVERSION));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_EQUIPVERS) == 0x0b);
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_SWVERSION) == 0x13);
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_UNITNAME) == 0x17);
+	OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_SERNR));
+	OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_SERNR) == 0x09);
+}
+
+static void test_ipa_ccm_id_get_parsing(void)
 {
 	struct tlv_parsed tvp;
 	int rc;
 
 	/* IPA CCM IDENTITY REQUEST message: 8bit length followed by respective value */
-        static uint8_t id_get_data[] = {
+        static const uint8_t id_get_data[] = {
 		0x01, 0x08,
 		0x01, 0x07,
 		0x01, 0x02,
@@ -189,7 +242,9 @@
 		0x11, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
         };
 
-	rc = ipa_ccm_idtag_parse_off(&tvp, id_get_data, sizeof(id_get_data), 1);
+	printf("\nTesting IPA CCM ID GET parsing\n");
+
+	rc = ipa_ccm_id_get_parse(&tvp, id_get_data, sizeof(id_get_data));
 	OSMO_ASSERT(rc == 0);
 
 	OSMO_ASSERT(TLVP_PRESENT(&tvp, 8));
@@ -568,7 +623,8 @@
 
 	hexdump_test();
 	hexparse_test();
-	test_idtag_parsing();
+	test_ipa_ccm_id_get_parsing();
+	test_ipa_ccm_id_resp_parsing();
 	test_is_hexstr();
 	bcd_test();
 	str_escape_test();
diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok
index b158bf7..abc7317 100644
--- a/tests/utils/utils_test.ok
+++ b/tests/utils/utils_test.ok
@@ -27,6 +27,10 @@
 Hexparse with invalid char
 rc = -1
 
+Testing IPA CCM ID GET parsing
+
+Testing IPA CCM ID RESP parsing
+
 ----- test_is_hexstr
  0: pass str='(null)' min=0 max=10 even=0 expect=valid
  1: pass str='(null)' min=1 max=10 even=0 expect=invalid

-- 
To view, visit https://gerrit.osmocom.org/10293
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1834d90fbcdbfcb05f5b8cfe39bfe9543737ef8f
Gerrit-Change-Number: 10293
Gerrit-PatchSet: 1
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180801/f5b8e779/attachment.htm>


More information about the gerrit-log mailing list