<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/10293">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Deprecate ipa_ccm_idtag_parse() with ipa_ccm_id_{get,resp}_parse()<br><br>In the past, the function ipa_ccm_idtag_parse() was used to parse<br>the payload of IPA CCM ID RESP packets.  However, the function was<br>based on a possible misunderstanding of the message encoding, and<br>callers actually counted the first (upper) length nibble as part<br>of the header and passed a pointer to the second<br>(lower) length nibble of the first TLV into this function.  As such,<br>it was unfixable, and had to be replaced with a new function called<br>ipa_ccm_id_resp_parse().  At the same time, we also add<br>ipa_ccm_id_get_parse() to parse the slightly different format of<br>the IPA CCM ID GET payload.<br><br>We can never be 100% sure what is "correct", as our understanding<br>of the protocol is entirely based on protocol analysis, without any<br>official documentation available.<br><br>This patch also introduces unit test coverage for both of the new<br>functions.<br><br>Change-Id: I1834d90fbcdbfcb05f5b8cfe39bfe9543737ef8f<br>---<br>M include/osmocom/gsm/ipa.h<br>M src/gsm/ipa.c<br>M src/gsm/libosmogsm.map<br>M tests/utils/utils_test.c<br>M tests/utils/utils_test.ok<br>5 files changed, 151 insertions(+), 6 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/93/10293/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gsm/ipa.h b/include/osmocom/gsm/ipa.h</span><br><span>index 7e1d723..ec143d0 100644</span><br><span>--- a/include/osmocom/gsm/ipa.h</span><br><span>+++ b/include/osmocom/gsm/ipa.h</span><br><span>@@ -26,8 +26,14 @@</span><br><span> /* obtain the human-readable name of an IPA CCM ID TAG */</span><br><span> const char *ipa_ccm_idtag_name(uint8_t tag);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* parse a buffer of ID tags into a osmocom TLV style representation */</span><br><span style="color: hsl(0, 100%, 40%);">-int ipa_ccm_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);</span><br><span style="color: hsl(120, 100%, 40%);">+int ipa_ccm_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_DEPRECATED("Use ipa_ccm_id_{get,resp}_parse instead");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* parse payload of IPA CCM ID GET into a osmocom TLV style representation */</span><br><span style="color: hsl(120, 100%, 40%);">+int ipa_ccm_id_get_parse(struct tlv_parsed *dec, const uint8_t *buf, unsigned int len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* parse payload of IPA CCM ID RESP into a osmocom TLV style representation */</span><br><span style="color: hsl(120, 100%, 40%);">+int ipa_ccm_id_resp_parse(struct tlv_parsed *dec, const uint8_t *buf, unsigned int len);</span><br><span> </span><br><span> /* Is the TAG included in the length field? */</span><br><span> int ipa_ccm_idtag_parse_off(struct tlv_parsed *dec, unsigned char *buf, int len, const int len_offset);</span><br><span>diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c</span><br><span>index 989e439..3c7c300 100644</span><br><span>--- a/src/gsm/ipa.c</span><br><span>+++ b/src/gsm/ipa.c</span><br><span>@@ -127,6 +127,83 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Parse the payload part of an IPA CCM ID GET, return \ref tlv_parsed format.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  The odd payload format of those messages is structured as follows:</span><br><span style="color: hsl(120, 100%, 40%);">+ *   * 8bit length value (length of payload *and tag*)</span><br><span style="color: hsl(120, 100%, 40%);">+ *   * 8bit tag value</span><br><span style="color: hsl(120, 100%, 40%);">+ *   * optional, variable-length payload</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] dec Caller-provided/allocated output structure for parsed payload</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf Buffer containing the payload (excluding 1 byte msg_type) of the message</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] len Length of \a buf in octets</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success; negative on error */</span><br><span style="color: hsl(120, 100%, 40%);">+int ipa_ccm_id_get_parse(struct tlv_parsed *dec, const uint8_t *buf, unsigned int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t t_len;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t t_tag;</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t *cur = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   memset(dec, 0, sizeof(*dec));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       while (len >= 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+         len -= 2;</span><br><span style="color: hsl(120, 100%, 40%);">+             t_len = *cur++;</span><br><span style="color: hsl(120, 100%, 40%);">+               t_tag = *cur++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             if (t_len > len + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGP(DLMI, LOGL_ERROR, "The tag does not fit: %d > %d\n", t_len, len + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+                       return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           DEBUGPC(DLMI, "%s='%s' ", ipa_ccm_idtag_name(t_tag), cur);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                dec->lv[t_tag].len = t_len-1;</span><br><span style="color: hsl(120, 100%, 40%);">+              dec->lv[t_tag].val = cur;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                cur += t_len-1;</span><br><span style="color: hsl(120, 100%, 40%);">+               len -= t_len-1;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Parse the payload part of an IPA CCM ID RESP, return \ref tlv_parsed format.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  The odd payload format of those messages is structured as follows:</span><br><span style="color: hsl(120, 100%, 40%);">+ *   * 16bit length value (length of payload *and tag*)</span><br><span style="color: hsl(120, 100%, 40%);">+ *   * 8bit tag value</span><br><span style="color: hsl(120, 100%, 40%);">+ *   * optional, variable-length payload</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] dec Caller-provided/allocated output structure for parsed payload</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf Buffer containing the payload (excluding 1 byte msg_type) of the message</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] len Length of \a buf in octets</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success; negative on error */</span><br><span style="color: hsl(120, 100%, 40%);">+int ipa_ccm_id_resp_parse(struct tlv_parsed *dec, const uint8_t *buf, unsigned int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t t_len;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t t_tag;</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t *cur = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   memset(dec, 0, sizeof(*dec));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       while (len >= 3) {</span><br><span style="color: hsl(120, 100%, 40%);">+         len -= 3;</span><br><span style="color: hsl(120, 100%, 40%);">+             t_len = *cur++ << 8;</span><br><span style="color: hsl(120, 100%, 40%);">+            t_len += *cur++;</span><br><span style="color: hsl(120, 100%, 40%);">+              t_tag = *cur++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             if (t_len > len + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGP(DLMI, LOGL_ERROR, "The tag does not fit: %d > %d\n", t_len, len + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+                       return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           DEBUGPC(DLMI, "%s='%s' ", ipa_ccm_idtag_name(t_tag), cur);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                dec->lv[t_tag].len = t_len-1;</span><br><span style="color: hsl(120, 100%, 40%);">+              dec->lv[t_tag].val = cur;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                cur += t_len-1;</span><br><span style="color: hsl(120, 100%, 40%);">+               len -= t_len-1;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int ipa_parse_unitid(const char *str, struct ipaccess_unit *unit_data)</span><br><span> {</span><br><span>        unsigned long ul;</span><br><span>diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map</span><br><span>index f168e5f..a1d342a 100644</span><br><span>--- a/src/gsm/libosmogsm.map</span><br><span>+++ b/src/gsm/libosmogsm.map</span><br><span>@@ -461,6 +461,8 @@</span><br><span> ipa_ccm_tlv_to_unitdata;</span><br><span> ipa_ccm_idtag_name;</span><br><span> ipa_ccm_idtag_parse;</span><br><span style="color: hsl(120, 100%, 40%);">+ipa_ccm_id_get_parse;</span><br><span style="color: hsl(120, 100%, 40%);">+ipa_ccm_id_resp_parse;</span><br><span> ipa_ccm_make_id_resp;</span><br><span> ipa_ccm_make_id_resp_from_req;</span><br><span> ipa_msg_alloc;</span><br><span>diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c</span><br><span>index eec13ca..2f1e87d 100644</span><br><span>--- a/tests/utils/utils_test.c</span><br><span>+++ b/tests/utils/utils_test.c</span><br><span>@@ -21,6 +21,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <osmocom/gsm/ipa.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/protocol/ipaccess.h></span><br><span> </span><br><span> #include <osmocom/core/logging.h></span><br><span> #include <osmocom/core/utils.h></span><br><span>@@ -170,13 +171,65 @@</span><br><span>      printf("rc = %d\n", rc);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void test_idtag_parsing(void)</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_ipa_ccm_id_resp_parsing(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct tlv_parsed tvp;</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     static const uint8_t id_resp_data[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+               0x00, 0x13,     IPAC_IDTAG_MACADDR,</span><br><span style="color: hsl(120, 100%, 40%);">+                   '0','0',':','0','2',':','9','5',':','0','0',':','6','2',':','9','e','\0',</span><br><span style="color: hsl(120, 100%, 40%);">+             0x00, 0x11,     IPAC_IDTAG_IPADDR,</span><br><span style="color: hsl(120, 100%, 40%);">+                    '1','9','2','.','1','6','8','.','1','0','0','.','1','9','0','\0',</span><br><span style="color: hsl(120, 100%, 40%);">+             0x00, 0x0a,     IPAC_IDTAG_UNIT,</span><br><span style="color: hsl(120, 100%, 40%);">+                      '1','2','3','4','/','0','/','0','\0',</span><br><span style="color: hsl(120, 100%, 40%);">+         0x00, 0x02,     IPAC_IDTAG_LOCATION1,</span><br><span style="color: hsl(120, 100%, 40%);">+                 '\0',</span><br><span style="color: hsl(120, 100%, 40%);">+         0x00, 0x0d,     IPAC_IDTAG_LOCATION2,</span><br><span style="color: hsl(120, 100%, 40%);">+                 'B','T','S','_','N','B','T','1','3','1','G','\0',</span><br><span style="color: hsl(120, 100%, 40%);">+             0x00, 0x0c,     IPAC_IDTAG_EQUIPVERS,</span><br><span style="color: hsl(120, 100%, 40%);">+                 '1','6','5','a','0','2','9','_','5','5','\0',</span><br><span style="color: hsl(120, 100%, 40%);">+         0x00, 0x14,     IPAC_IDTAG_SWVERSION,</span><br><span style="color: hsl(120, 100%, 40%);">+                 '1','6','8','d','4','7','2','_','v','2','0','0','b','4','1','1','d','0','\0',</span><br><span style="color: hsl(120, 100%, 40%);">+         0x00, 0x18,     IPAC_IDTAG_UNITNAME,</span><br><span style="color: hsl(120, 100%, 40%);">+                  'n','b','t','s','-','0','0','-','0','2','-','9','5','-','0','0','-','6','2','-','9','E','\0',</span><br><span style="color: hsl(120, 100%, 40%);">+         0x00, 0x0a,     IPAC_IDTAG_SERNR,</span><br><span style="color: hsl(120, 100%, 40%);">+                     '0','0','1','1','0','7','8','1','\0'</span><br><span style="color: hsl(120, 100%, 40%);">+  };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("\nTesting IPA CCM ID RESP parsing\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = ipa_ccm_id_resp_parse(&tvp, (uint8_t *) id_resp_data, sizeof(id_resp_data));</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(rc == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_MACADDR));</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_MACADDR) == 0x12);</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_IPADDR));</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_IPADDR) == 0x10);</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_UNIT));</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_UNIT) == 0x09);</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_LOCATION1));</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_LOCATION1) == 0x01);</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_LOCATION2));</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_LOCATION2) == 0x0c);</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_EQUIPVERS));</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_EQUIPVERS) == 0x0b);</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_SWVERSION));</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_EQUIPVERS) == 0x0b);</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_SWVERSION) == 0x13);</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME));</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_UNITNAME) == 0x17);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_SERNR));</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_SERNR) == 0x09);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_ipa_ccm_id_get_parsing(void)</span><br><span> {</span><br><span>  struct tlv_parsed tvp;</span><br><span>       int rc;</span><br><span> </span><br><span>  /* IPA CCM IDENTITY REQUEST message: 8bit length followed by respective value */</span><br><span style="color: hsl(0, 100%, 40%);">-        static uint8_t id_get_data[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        static const uint8_t id_get_data[] = {</span><br><span>             0x01, 0x08,</span><br><span>          0x01, 0x07,</span><br><span>          0x01, 0x02,</span><br><span>@@ -189,7 +242,9 @@</span><br><span>            0x11, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00</span><br><span>         };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    rc = ipa_ccm_idtag_parse_off(&tvp, id_get_data, sizeof(id_get_data), 1);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("\nTesting IPA CCM ID GET parsing\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = ipa_ccm_id_get_parse(&tvp, id_get_data, sizeof(id_get_data));</span><br><span>       OSMO_ASSERT(rc == 0);</span><br><span> </span><br><span>    OSMO_ASSERT(TLVP_PRESENT(&tvp, 8));</span><br><span>@@ -568,7 +623,8 @@</span><br><span> </span><br><span>    hexdump_test();</span><br><span>      hexparse_test();</span><br><span style="color: hsl(0, 100%, 40%);">-        test_idtag_parsing();</span><br><span style="color: hsl(120, 100%, 40%);">+ test_ipa_ccm_id_get_parsing();</span><br><span style="color: hsl(120, 100%, 40%);">+        test_ipa_ccm_id_resp_parsing();</span><br><span>      test_is_hexstr();</span><br><span>    bcd_test();</span><br><span>  str_escape_test();</span><br><span>diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok</span><br><span>index b158bf7..abc7317 100644</span><br><span>--- a/tests/utils/utils_test.ok</span><br><span>+++ b/tests/utils/utils_test.ok</span><br><span>@@ -27,6 +27,10 @@</span><br><span> Hexparse with invalid char</span><br><span> rc = -1</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+Testing IPA CCM ID GET parsing</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Testing IPA CCM ID RESP parsing</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> ----- test_is_hexstr</span><br><span>  0: pass str='(null)' min=0 max=10 even=0 expect=valid</span><br><span>  1: pass str='(null)' min=1 max=10 even=0 expect=invalid</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10293">change 10293</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/10293"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I1834d90fbcdbfcb05f5b8cfe39bfe9543737ef8f </div>
<div style="display:none"> Gerrit-Change-Number: 10293 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>