<p>Holger Freyther has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13838">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">xudt: Implement address and data extraction<br><br>The cellmgr-ng unfortunately looks at the data being sent and can't<br>handle the presence of XUDT at all. Add the structure definition<br>and refactor extraction code to work on offsets. Add a unit test.<br><br>Change-Id: I45a7447cc1be432fff34849e0e35abc0410cf153<br>---<br>M include/osmocom/sccp/sccp_types.h<br>M src/sccp.c<br>M tests/sccp/sccp_test.c<br>3 files changed, 142 insertions(+), 14 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/38/13838/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/sccp/sccp_types.h b/include/osmocom/sccp/sccp_types.h</span><br><span>index ab7f74f..18b54f4 100644</span><br><span>--- a/include/osmocom/sccp/sccp_types.h</span><br><span>+++ b/include/osmocom/sccp/sccp_types.h</span><br><span>@@ -422,6 +422,60 @@</span><br><span>         uint8_t                 data[0];</span><br><span> } __attribute__((packed));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Extended unitdata (XUDT) */</span><br><span style="color: hsl(120, 100%, 40%);">+struct sccp_data_ext_unitdata {</span><br><span style="color: hsl(120, 100%, 40%);">+   /* mandatory */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t                 type;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t                 proto_class;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t                 hop_counter;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* variable */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t                 variable_called;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t                 variable_calling;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t                 variable_data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if VARIABLE</span><br><span style="color: hsl(120, 100%, 40%);">+        called party address</span><br><span style="color: hsl(120, 100%, 40%);">+  calling party address</span><br><span style="color: hsl(120, 100%, 40%);">+ data</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if OPTIONAL</span><br><span style="color: hsl(120, 100%, 40%);">+  segmentation</span><br><span style="color: hsl(120, 100%, 40%);">+  importance</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t                 data[0];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__((packed));</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%);">+/* Extended unitdata service (XUDTS) */</span><br><span style="color: hsl(120, 100%, 40%);">+struct  sccp_data_ext_unitdata_service {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* mandantory */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t                 type;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t                 return_cause;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t                 hop_counter;</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%);">+      /* variable */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t                 variable_called;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t                 variable_calling;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t                 variable_data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if VARIABLE</span><br><span style="color: hsl(120, 100%, 40%);">+        called party address</span><br><span style="color: hsl(120, 100%, 40%);">+  calling party address</span><br><span style="color: hsl(120, 100%, 40%);">+ data</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if OPTIONAL</span><br><span style="color: hsl(120, 100%, 40%);">+  segmentation</span><br><span style="color: hsl(120, 100%, 40%);">+  importancd</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t                 data[0];</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__((packed));</span><br><span> </span><br><span> struct sccp_data_it {</span><br><span>    /* mandatory */</span><br><span>diff --git a/src/sccp.c b/src/sccp.c</span><br><span>index ec0f3b7..c14e850 100644</span><br><span>--- a/src/sccp.c</span><br><span>+++ b/src/sccp.c</span><br><span>@@ -406,37 +406,46 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int _sccp_parse_udt(struct msgb *msgb, struct sccp_parse_result *result)</span><br><span style="color: hsl(120, 100%, 40%);">+struct udt_offsets {</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t        header_size;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t        called_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t        calling_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t        data_offset;</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 int _sccp_parse_unitdata(struct msgb *msgb, struct sccp_parse_result *result,</span><br><span style="color: hsl(120, 100%, 40%);">+                              const struct udt_offsets *offs)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    static const uint32_t header_size = sizeof(struct sccp_data_unitdata);</span><br><span style="color: hsl(0, 100%, 40%);">-  static const uint32_t called_offset = offsetof(struct sccp_data_unitdata, variable_called);</span><br><span style="color: hsl(0, 100%, 40%);">-     static const uint32_t calling_offset = offsetof(struct sccp_data_unitdata, variable_calling);</span><br><span style="color: hsl(0, 100%, 40%);">-   static const uint32_t data_offset = offsetof(struct sccp_data_unitdata, variable_data);</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t         variable_called;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t         variable_calling;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t         variable_data;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      struct sccp_data_unitdata *udt = (struct sccp_data_unitdata *)msgb->l2h;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (msgb_l2len(msgb) < header_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+      if (msgb_l2len(msgb) < offs->header_size) {</span><br><span>            LOGP(DSCCP, LOGL_ERROR, "msgb < header_size %u %u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                      msgb_l2len(msgb), header_size);</span><br><span style="color: hsl(120, 100%, 40%);">+                       msgb_l2len(msgb), offs->header_size);</span><br><span>             return -1;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ variable_called = msgb->l2h[offs->called_offset];</span><br><span style="color: hsl(120, 100%, 40%);">+       variable_calling = msgb->l2h[offs->calling_offset];</span><br><span style="color: hsl(120, 100%, 40%);">+     variable_data = msgb->l2h[offs->data_offset];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        /* copy out the calling and called address. Add the off */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (copy_address(&result->called, called_offset + udt->variable_called, msgb) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (copy_address(&result->called, offs->called_offset + variable_called, msgb) != 0)</span><br><span>               return -1;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  if (copy_address(&result->calling, calling_offset + udt->variable_calling, msgb) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+      if (copy_address(&result->calling, offs->calling_offset + variable_calling, msgb) != 0)</span><br><span>            return -1;</span><br><span> </span><br><span>       /* we don't have enough size for the data */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (msgb_l2len(msgb) < data_offset + udt->variable_data + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+  if (msgb_l2len(msgb) < offs->data_offset + variable_data + 1) {</span><br><span>                LOGP(DSCCP, LOGL_ERROR, "msgb < header + offset %u %u %u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       msgb_l2len(msgb), header_size, udt->variable_data);</span><br><span style="color: hsl(120, 100%, 40%);">+                        msgb_l2len(msgb), offs->header_size, variable_data);</span><br><span>              return -1;</span><br><span>   }</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       msgb->l3h = &udt->data[udt->variable_data];</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb->l3h = &msgb->l2h[offs->data_offset + variable_data + 1];</span><br><span>  result->data_len = msgb_l3len(msgb);</span><br><span> </span><br><span>  if (msgb_l3len(msgb) <  msgb->l3h[-1]) {</span><br><span>@@ -448,6 +457,30 @@</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int _sccp_parse_udt(struct msgb *msgb, struct sccp_parse_result *result)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       static const struct udt_offsets offsets = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .header_size = sizeof(struct sccp_data_unitdata),</span><br><span style="color: hsl(120, 100%, 40%);">+             .called_offset = offsetof(struct sccp_data_unitdata, variable_called),</span><br><span style="color: hsl(120, 100%, 40%);">+                .calling_offset = offsetof(struct sccp_data_unitdata, variable_calling),</span><br><span style="color: hsl(120, 100%, 40%);">+              .data_offset = offsetof(struct sccp_data_unitdata, variable_data),</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%);">+  return _sccp_parse_unitdata(msgb, result, &offsets);</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 int _sccp_parse_xudt(struct msgb *msgb, struct sccp_parse_result *result)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    static const struct udt_offsets offsets = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .header_size = sizeof(struct sccp_data_ext_unitdata),</span><br><span style="color: hsl(120, 100%, 40%);">+         .called_offset = offsetof(struct sccp_data_ext_unitdata, variable_called),</span><br><span style="color: hsl(120, 100%, 40%);">+            .calling_offset = offsetof(struct sccp_data_ext_unitdata, variable_calling),</span><br><span style="color: hsl(120, 100%, 40%);">+          .data_offset = offsetof(struct sccp_data_ext_unitdata, variable_data),</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%);">+  return _sccp_parse_unitdata(msgb, result, &offsets);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int _sccp_parse_it(struct msgb *msgb, struct sccp_parse_result *result)</span><br><span> {</span><br><span>         static const uint32_t header_size = sizeof(struct sccp_data_it);</span><br><span>@@ -1457,6 +1490,9 @@</span><br><span>     case SCCP_MSG_TYPE_UDT:</span><br><span>              return _sccp_parse_udt(msg, result);</span><br><span>                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case SCCP_MSG_TYPE_XUDT:</span><br><span style="color: hsl(120, 100%, 40%);">+              return _sccp_parse_xudt(msg, result);</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span>       case SCCP_MSG_TYPE_IT:</span><br><span>               return _sccp_parse_it(msg, result);</span><br><span>          break;</span><br><span>diff --git a/tests/sccp/sccp_test.c b/tests/sccp/sccp_test.c</span><br><span>index ba9ff7a..29f343f 100644</span><br><span>--- a/tests/sccp/sccp_test.c</span><br><span>+++ b/tests/sccp/sccp_test.c</span><br><span>@@ -312,6 +312,32 @@</span><br><span> 0x0f, 0x0c, 0x04, 0x00, 0x00,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static const uint8_t xudt_test_src_gt[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+0x00, 0x11, 0x04, 0x26, 0x18, 0x01, 0x30, 0x08,</span><br><span style="color: hsl(120, 100%, 40%);">+0x01</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 const uint8_t xudt_test_dst_gt[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+0x00, 0x61, 0x04, 0x15, 0x10, 0x80, 0x21, 0x35,</span><br><span style="color: hsl(120, 100%, 40%);">+0x98, 0x55, 0x08</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 const uint8_t xudt_test[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+0x11, 0x81, 0x02, 0x04, 0x11, 0x1C, 0x00, 0x0D,</span><br><span style="color: hsl(120, 100%, 40%);">+0x52, 0x06, 0x00, 0x61, 0x04, 0x15, 0x10, 0x80,</span><br><span style="color: hsl(120, 100%, 40%);">+0x21, 0x35, 0x98, 0x55, 0x08, 0x0B, 0x12, 0x95,</span><br><span style="color: hsl(120, 100%, 40%);">+0x00, 0x11, 0x04, 0x26, 0x18, 0x01, 0x30, 0x08,</span><br><span style="color: hsl(120, 100%, 40%);">+0x01, 0x44, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,</span><br><span style="color: hsl(120, 100%, 40%);">+0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,</span><br><span style="color: hsl(120, 100%, 40%);">+0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,</span><br><span style="color: hsl(120, 100%, 40%);">+0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,</span><br><span style="color: hsl(120, 100%, 40%);">+0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,</span><br><span style="color: hsl(120, 100%, 40%);">+0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,</span><br><span style="color: hsl(120, 100%, 40%);">+0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,</span><br><span style="color: hsl(120, 100%, 40%);">+0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,</span><br><span style="color: hsl(120, 100%, 40%);">+0x3F, 0x40, 0x41, 0x42, 0x43, 0x44</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static const struct sccp_parse_header_result parse_result[] = {</span><br><span>         {</span><br><span>            .msg_type       = SCCP_MSG_TYPE_IT,</span><br><span>@@ -362,6 +388,18 @@</span><br><span>           .src_gti_data   = tcap_global_src_gti,</span><br><span>               .src_gti_len    = 9,</span><br><span>         },</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+             .msg_type       = SCCP_MSG_TYPE_XUDT,</span><br><span style="color: hsl(120, 100%, 40%);">+         .input          = xudt_test,</span><br><span style="color: hsl(120, 100%, 40%);">+          .input_len      = sizeof(xudt_test),</span><br><span style="color: hsl(120, 100%, 40%);">+          .wanted_len     = 68,</span><br><span style="color: hsl(120, 100%, 40%);">+         .dst_ssn        = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+          .dst_gti_data   = xudt_test_dst_gt,</span><br><span style="color: hsl(120, 100%, 40%);">+           .dst_gti_len    = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+         .src_ssn        = 149,</span><br><span style="color: hsl(120, 100%, 40%);">+                .src_gti_data   = xudt_test_src_gt,</span><br><span style="color: hsl(120, 100%, 40%);">+           .src_gti_len    = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+  },</span><br><span> };</span><br><span> </span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13838">change 13838</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/13838"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-sccp </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I45a7447cc1be432fff34849e0e35abc0410cf153 </div>
<div style="display:none"> Gerrit-Change-Number: 13838 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Holger Freyther <holger@freyther.de> </div>