laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-iuh/+/26722 )

Change subject: iu_helpers: make new_transp_info_(rtp|gtp) public
......................................................................

iu_helpers: make new_transp_info_(rtp|gtp) public

The functions new_transp_info_rtp and new_transp_info_gtp are needed to
generate the transport layer information struct. The functions are currently
not public since they are only used in ranap_msg_factory.c but to
reqwrite the RANAP RAB AssignmentReqtest / AssignmentResponse messages we
can reuse this code, so lets make them public.

Change-Id: I1e369718de8c4c7db1f1af1e6864562164ada6cf
Related: OS#5152
---
M include/osmocom/ranap/iu_helpers.h
M src/iu_helpers.c
M src/ranap_msg_factory.c
M src/tests/test-helpers.c
M src/tests/test-helpers.ok
5 files changed, 267 insertions(+), 59 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/include/osmocom/ranap/iu_helpers.h 
b/include/osmocom/ranap/iu_helpers.h
index 9d801be..d824646 100644
--- a/include/osmocom/ranap/iu_helpers.h
+++ b/include/osmocom/ranap/iu_helpers.h
@@ -1,13 +1,20 @@
 #pragma once

 #include <stdint.h>
+#include <stdbool.h>
 #include <sys/types.h>

 #include <osmocom/ranap/RANAP_IuTransportAssociation.h>
 #include <osmocom/ranap/RANAP_TransportLayerAddress.h>
+#include <osmocom/ranap/RANAP_TransportLayerInformation.h>
+
+struct osmo_sockaddr;

 int ranap_bcd_decode(char *out, size_t out_len, const uint8_t *in, size_t 
in_len);
 int ranap_imsi_encode(uint8_t *out, size_t out_len, const char *in);
 int ranap_transp_assoc_decode(uint16_t *port, const 
RANAP_IuTransportAssociation_t *transp_assoc);
 int ranap_transp_layer_addr_decode(char *addr, unsigned int addr_len,
                                   const RANAP_TransportLayerAddress_t 
*trasp_layer_addr);
+RANAP_TransportLayerInformation_t *ranap_new_transp_info_rtp(struct 
osmo_sockaddr *addr, bool use_x213_nsap);
+RANAP_TransportLayerInformation_t *ranap_new_transp_info_gtp(struct 
osmo_sockaddr *addr, uint32_t tei,
+                                                            bool 
use_x213_nsap);
diff --git a/src/iu_helpers.c b/src/iu_helpers.c
index bf82fde..392622f 100644
--- a/src/iu_helpers.c
+++ b/src/iu_helpers.c
@@ -24,8 +24,12 @@
 #include <arpa/inet.h>
 #include "asn1helpers.h"
 #include <osmocom/core/utils.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/core/bit16gen.h>
+
 #include <osmocom/ranap/RANAP_IuTransportAssociation.h>
 #include <osmocom/ranap/RANAP_TransportLayerAddress.h>
+#include <osmocom/ranap/RANAP_TransportLayerInformation.h>

 /* decode a BCD-string as used inside ASN.1 encoded Iu interface protocols */
 int ranap_bcd_decode(char *out, size_t out_len, const uint8_t *in, size_t 
in_len)
@@ -121,3 +125,102 @@

        return 0;
 }
+
+static int new_transp_layer_addr(BIT_STRING_t *out, struct osmo_sockaddr 
*addr, bool use_x213_nsap)
+{
+       uint8_t *buf;
+       unsigned int len;
+       size_t ip_len;
+       uint8_t *ip_addr;
+       uint16_t icp;
+
+       switch (addr->u.sa.sa_family) {
+       case AF_INET:
+               ip_len = sizeof(addr->u.sin.sin_addr.s_addr);
+               ip_addr = (uint8_t *) &addr->u.sin.sin_addr.s_addr;
+               icp = 0x0001; /* See X.213, section A.5.2.1.2.7 */
+               break;
+       case AF_INET6:
+               ip_len = sizeof(addr->u.sin6.sin6_addr.s6_addr);
+               ip_addr = addr->u.sin6.sin6_addr.s6_addr;
+               icp = 0x0000; /* See X.213, section A.5.2.1.2.7 */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (use_x213_nsap) {
+               /* 3 bytes IDP (AFI+ICP) + 17 bytes DSP */
+               len = 3 + 17;
+               buf = CALLOC(len, sizeof(uint8_t));
+
+               /* 1 byte AFI to announce IANA ICP, see also X.213, table A.4 */
+               buf[0] = 0x35;
+
+               /* 2 byte IANA ICP IDI, see also X.213, A.5.2.1.2.7 */
+               osmo_store16be(icp, &buf[1]);
+
+               /* 17 byte DSP, see also X.213, table A.5 and A.5.2.1.2.7 */
+               memcpy(&buf[3], ip_addr, ip_len);
+       } else {
+               len = ip_len;
+               buf = CALLOC(len, sizeof(uint8_t));
+               memcpy(buf, ip_addr, ip_len);
+       }
+       out->buf = buf;
+       out->size = len;
+       out->bits_unused = 0;
+
+       return 0;
+}
+
+RANAP_TransportLayerInformation_t *ranap_new_transp_info_rtp(struct 
osmo_sockaddr *addr, bool use_x213_nsap)
+{
+       RANAP_TransportLayerInformation_t *tli;
+       uint8_t binding_id[4] = { 0 };
+       int rc;
+
+       switch (addr->u.sin.sin_family) {
+       case AF_INET:
+               osmo_store16be(ntohs(addr->u.sin.sin_port), binding_id);
+               break;
+       case AF_INET6:
+               osmo_store16be(ntohs(addr->u.sin6.sin6_port), binding_id);
+               break;
+       default:
+               return NULL;
+       }
+
+       tli = CALLOC(1, sizeof(*tli));
+       rc = new_transp_layer_addr(&tli->transportLayerAddress, addr, 
use_x213_nsap);
+       if (rc < 0) {
+               ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+               return NULL;
+       }
+
+       tli->iuTransportAssociation.present = 
RANAP_IuTransportAssociation_PR_bindingID;
+       OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
+                            (const char *)binding_id, sizeof(binding_id));
+
+       return tli;
+}
+
+RANAP_TransportLayerInformation_t *ranap_new_transp_info_gtp(struct 
osmo_sockaddr *addr, uint32_t tei,
+                                                            bool use_x213_nsap)
+{
+       RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
+       uint32_t binding_buf = htonl(tei);
+       int rc;
+
+       rc = new_transp_layer_addr(&tli->transportLayerAddress, addr, 
use_x213_nsap);
+       if (rc < 0) {
+               ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+               return NULL;
+       }
+
+       tli->iuTransportAssociation.present = 
RANAP_IuTransportAssociation_PR_gTP_TEI;
+       OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.gTP_TEI,
+                            (const char *)&binding_buf, sizeof(binding_buf));
+
+       return tli;
+}
diff --git a/src/ranap_msg_factory.c b/src/ranap_msg_factory.c
index f93a2ab..60dc9e0 100644
--- a/src/ranap_msg_factory.c
+++ b/src/ranap_msg_factory.c
@@ -20,6 +20,7 @@

 #include <osmocom/core/utils.h>
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/socket.h>

 #include "asn1helpers.h"
 #include <osmocom/ranap/iu_helpers.h>
@@ -691,61 +692,6 @@
        return rab;
 }

-static void new_transp_layer_addr(BIT_STRING_t *out, uint32_t ip, bool 
use_x213_nsap)
-{
-       uint8_t *buf;
-       unsigned int len;
-       uint32_t ip_h = ntohl(ip);
-
-       if (use_x213_nsap) {
-               len = 160/8;
-               buf = CALLOC(len, sizeof(uint8_t));
-               buf[0] = 0x35;  /* AFI For IANA ICP */
-               buf[1] = 0x00;  /* See A.5.2.1.2.7 of X.213 */
-               buf[2] = 0x01;
-               memcpy(&buf[3], &ip_h, sizeof(ip_h));
-       } else {
-               len = sizeof(ip_h);
-               buf = CALLOC(len, sizeof(uint8_t));
-               memcpy(buf, &ip_h, sizeof(ip_h));
-       }
-       out->buf = buf;
-       out->size = len;
-       out->bits_unused = 0;
-}
-
-static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, 
uint16_t port,
-                                                             bool 
use_x213_nsap)
-{
-       RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
-       uint8_t binding_id[4];
-
-       binding_id[0] = port >> 8;
-       binding_id[1] = port & 0xff;
-       binding_id[2] = binding_id[3] = 0;
-
-       new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap);
-       tli->iuTransportAssociation.present = 
RANAP_IuTransportAssociation_PR_bindingID;
-       OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
-                               (const char *) binding_id, sizeof(binding_id));
-
-       return tli;
-}
-
-static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, 
uint32_t tei,
-                                                             bool 
use_x213_nsap)
-{
-       RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
-       uint32_t binding_buf = htonl(tei);
-
-       new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap);
-       tli->iuTransportAssociation.present = 
RANAP_IuTransportAssociation_PR_gTP_TEI;
-       OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.gTP_TEI,
-                            (const char *) &binding_buf, sizeof(binding_buf));
-
-       return tli;
-}
-
 static RANAP_UserPlaneInformation_t *new_upi(long mode, uint8_t mode_versions)
 {
        RANAP_UserPlaneInformation_t *upi = CALLOC(1, sizeof(*upi));
@@ -786,6 +732,7 @@
        RANAP_RAB_AssignmentRequest_t out;
        struct msgb *msg;
        int rc;
+       struct osmo_sockaddr rtp_addr;

        memset(&ies, 0, sizeof(ies));
        memset(&out, 0, sizeof(out));
@@ -800,8 +747,11 @@
        first.nAS_SynchronisationIndicator = new_rab_nas_sync_ind(60);
        first.rAB_Parameters = new_rab_par_voice(6700, 12200);
        first.userPlaneInformation = 
new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */
-       first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port,
-                                                             use_x213_nsap);
+
+       rtp_addr.u.sin.sin_family = AF_INET;
+       rtp_addr.u.sin.sin_port = htons(rtp_port);
+       rtp_addr.u.sin.sin_addr.s_addr = htonl(rtp_ip);
+       first.transportLayerInformation = ranap_new_transp_info_rtp(&rtp_addr, 
use_x213_nsap);

        /* put together the 'Second' part */
        RANAP_RAB_SetupOrModifyItemSecond_t second;
@@ -855,6 +805,7 @@
        RANAP_DataVolumeReportingIndication_t *dat_vol_ind;
        struct msgb *msg;
        int rc;
+       struct osmo_sockaddr gtp_addr;

        memset(&ies, 0, sizeof(ies));
        memset(&out, 0, sizeof(out));
@@ -870,8 +821,10 @@

        first.rAB_Parameters = new_rab_par_data(1600000, 800000);
        first.userPlaneInformation = 
new_upi(RANAP_UserPlaneMode_transparent_mode, 1);
-       first.transportLayerInformation = new_transp_info_gtp(gtp_ip, gtp_tei,
-                                                             use_x213_nsap);
+
+       gtp_addr.u.sin.sin_family = AF_INET;
+       gtp_addr.u.sin.sin_addr.s_addr = htonl(gtp_ip);
+       first.transportLayerInformation = ranap_new_transp_info_gtp(&gtp_addr, 
gtp_tei, use_x213_nsap);

        /* put together the 'Second' part */
        RANAP_RAB_SetupOrModifyItemSecond_t second;
diff --git a/src/tests/test-helpers.c b/src/tests/test-helpers.c
index 5c617e5..96540dc 100644
--- a/src/tests/test-helpers.c
+++ b/src/tests/test-helpers.c
@@ -28,6 +28,7 @@
 #define ASSERT(x)      assert(x)

 #include <osmocom/core/utils.h>
+#include <osmocom/core/socket.h>
 #include <osmocom/gsm/gsm48.h>

 #include <osmocom/ranap/RANAP_LAI.h>
@@ -204,6 +205,120 @@
        OSMO_ASSERT(rc == -1);
 }

+void test_ranap_new_transp_info_rtp(void)
+{
+       RANAP_TransportLayerInformation_t *tli;
+
+       printf("Testing function ranap_new_transp_info_rtp()\n");
+
+       struct osmo_sockaddr addr;
+
+       addr.u.sin.sin_family = AF_INET;
+       addr.u.sin.sin_port = htons(0x1122);
+       inet_pton(AF_INET, "1.2.3.4", &addr.u.sin.sin_addr);
+
+       printf(" ipv4, x213_nsap\n");
+       tli = ranap_new_transp_info_rtp(&addr, true);
+       printf("  transportLayerAddress = %s\n",
+              osmo_hexdump_nospc(tli->transportLayerAddress.buf, 
tli->transportLayerAddress.size));
+       printf("  bindingID = %s\n",
+              
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.bindingID.buf,
+                                 
tli->iuTransportAssociation.choice.bindingID.size));
+       ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+
+       printf(" ipv4\n");
+       tli = ranap_new_transp_info_rtp(&addr, false);
+       printf("  transportLayerAddress = %s\n",
+              osmo_hexdump_nospc(tli->transportLayerAddress.buf, 
tli->transportLayerAddress.size));
+       printf("  bindingID = %s\n",
+              
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.bindingID.buf,
+                                 
tli->iuTransportAssociation.choice.bindingID.size));
+       ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+
+       addr.u.sin.sin_family = AF_INET6;
+       addr.u.sin.sin_port = htons(0x1122);
+       inet_pton(AF_INET6, "f11f:f22f:f33f:f44f:f55f:f66f:f77f:f88f", 
&addr.u.sin6.sin6_addr);
+
+       printf(" ipv6, x213_nsap\n");
+       tli = ranap_new_transp_info_rtp(&addr, true);
+       printf("  transportLayerAddress = %s\n",
+              osmo_hexdump_nospc(tli->transportLayerAddress.buf, 
tli->transportLayerAddress.size));
+       printf("  bindingID = %s\n",
+              
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.bindingID.buf,
+                                 
tli->iuTransportAssociation.choice.bindingID.size));
+       ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+
+       printf(" ipv6\n");
+       tli = ranap_new_transp_info_rtp(&addr, false);
+       printf("  transportLayerAddress = %s\n",
+              osmo_hexdump_nospc(tli->transportLayerAddress.buf, 
tli->transportLayerAddress.size));
+       printf("  bindingID = %s\n",
+              
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.bindingID.buf,
+                                 
tli->iuTransportAssociation.choice.bindingID.size));
+       ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+
+       addr.u.sin.sin_family = AF_X25;
+       printf(" unsupported address family\n");
+       tli = ranap_new_transp_info_rtp(&addr, false);
+       OSMO_ASSERT(tli == NULL);
+}
+
+void test_ranap_new_transp_info_gtp(void)
+{
+       RANAP_TransportLayerInformation_t *tli;
+
+       printf("Testing function ranap_new_transp_info_gtp()\n");
+
+       struct osmo_sockaddr addr;
+
+       addr.u.sin.sin_family = AF_INET;
+       inet_pton(AF_INET, "1.2.3.4", &addr.u.sin.sin_addr);
+
+       printf(" ipv4, x213_nsap\n");
+       tli = ranap_new_transp_info_gtp(&addr, 0x11223344, true);
+       printf("  transportLayerAddress = %s\n",
+              osmo_hexdump_nospc(tli->transportLayerAddress.buf, 
tli->transportLayerAddress.size));
+       printf("  gTP_TEI = %s\n",
+              
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.gTP_TEI.buf,
+                                 
tli->iuTransportAssociation.choice.gTP_TEI.size));
+       ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+
+       printf(" ipv4\n");
+       tli = ranap_new_transp_info_gtp(&addr, 0x11223344, false);
+       printf("  transportLayerAddress = %s\n",
+              osmo_hexdump_nospc(tli->transportLayerAddress.buf, 
tli->transportLayerAddress.size));
+       printf("  gTP_TEI = %s\n",
+              
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.gTP_TEI.buf,
+                                 
tli->iuTransportAssociation.choice.gTP_TEI.size));
+       ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+
+       addr.u.sin.sin_family = AF_INET6;
+       inet_pton(AF_INET6, "f11f:f22f:f33f:f44f:f55f:f66f:f77f:f88f", 
&addr.u.sin6.sin6_addr);
+
+       printf(" ipv6, x213_nsap\n");
+       tli = ranap_new_transp_info_gtp(&addr, 0x11223344, true);
+       printf("  transportLayerAddress = %s\n",
+              osmo_hexdump_nospc(tli->transportLayerAddress.buf, 
tli->transportLayerAddress.size));
+       printf("  gTP_TEI = %s\n",
+              
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.gTP_TEI.buf,
+                                 
tli->iuTransportAssociation.choice.gTP_TEI.size));
+       ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+
+       printf(" ipv6\n");
+       tli = ranap_new_transp_info_gtp(&addr, 0x11223344, false);
+       printf("  transportLayerAddress = %s\n",
+              osmo_hexdump_nospc(tli->transportLayerAddress.buf, 
tli->transportLayerAddress.size));
+       printf("  gTP_TEI = %s\n",
+              
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.gTP_TEI.buf,
+                                 
tli->iuTransportAssociation.choice.gTP_TEI.size));
+       ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
+
+       addr.u.sin.sin_family = AF_X25;
+       printf(" unsupported address family\n");
+       tli = ranap_new_transp_info_gtp(&addr, 0x11223344, false);
+       OSMO_ASSERT(tli == NULL);
+}
+
 int main(int argc, char **argv)
 {
        asn1_xer_print = 0;
@@ -214,6 +329,8 @@
        test_iu_helpers();
        test_asn1_helpers();
        test_ranap_common();
+       test_ranap_new_transp_info_gtp();
+       test_ranap_new_transp_info_rtp();

        test_common_cleanup();
        return 0;
diff --git a/src/tests/test-helpers.ok b/src/tests/test-helpers.ok
index f2e466f..049fbb4 100644
--- a/src/tests/test-helpers.ok
+++ b/src/tests/test-helpers.ok
@@ -23,3 +23,31 @@
  rc == -1
 PLMN-Id [ 21 43 65 ], LAC [ ab ]
  rc == -1
+Testing function ranap_new_transp_info_gtp()
+ ipv4, x213_nsap
+  transportLayerAddress = 3500010102030400000000000000000000000000
+  gTP_TEI = 11223344
+ ipv4
+  transportLayerAddress = 01020304
+  gTP_TEI = 11223344
+ ipv6, x213_nsap
+  transportLayerAddress = 350000f11ff22ff33ff44ff55ff66ff77ff88f00
+  gTP_TEI = 11223344
+ ipv6
+  transportLayerAddress = f11ff22ff33ff44ff55ff66ff77ff88f
+  gTP_TEI = 11223344
+ unsupported address family
+Testing function ranap_new_transp_info_rtp()
+ ipv4, x213_nsap
+  transportLayerAddress = 3500010102030400000000000000000000000000
+  bindingID = 11220000
+ ipv4
+  transportLayerAddress = 01020304
+  bindingID = 11220000
+ ipv6, x213_nsap
+  transportLayerAddress = 350000f11ff22ff33ff44ff55ff66ff77ff88f00
+  bindingID = 11220000
+ ipv6
+  transportLayerAddress = f11ff22ff33ff44ff55ff66ff77ff88f
+  bindingID = 11220000
+ unsupported address family

--
To view, visit https://gerrit.osmocom.org/c/osmo-iuh/+/26722
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-iuh
Gerrit-Branch: master
Gerrit-Change-Id: I1e369718de8c4c7db1f1af1e6864562164ada6cf
Gerrit-Change-Number: 26722
Gerrit-PatchSet: 6
Gerrit-Owner: dexter <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: neels <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-MessageType: merged

Reply via email to