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(>p_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 <pmaier(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged