aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2022-01-10 13:54:57 +0100
committerlaforge <laforge@osmocom.org>2022-01-11 13:16:54 +0000
commitc0a0b2562bd65188b6d70d308cc7f595764deb97 (patch)
treeedfe0d309c9bc3f8557b5ee477148dbd9de6887d
parent45631aa04f4ac8861da317e9cd058bc616d6fe0b (diff)
iu_helpers: add function ranap_transp_layer_addr_decode2
Add ranap_transp_layer_addr_decode2 as AF agnostic version of ranap_transp_layer_addr_decode. Change-Id: Ia60e0ab671fc4185815a880377ab88fcf1b30ac9
-rw-r--r--include/osmocom/ranap/iu_helpers.h2
-rw-r--r--src/iu_helpers.c50
-rw-r--r--src/tests/test-helpers.c61
-rw-r--r--src/tests/test-helpers.ok9
4 files changed, 122 insertions, 0 deletions
diff --git a/include/osmocom/ranap/iu_helpers.h b/include/osmocom/ranap/iu_helpers.h
index d824646..bf2a580 100644
--- a/include/osmocom/ranap/iu_helpers.h
+++ b/include/osmocom/ranap/iu_helpers.h
@@ -15,6 +15,8 @@ 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);
+int ranap_transp_layer_addr_decode2(struct osmo_sockaddr *addr, bool *uses_x213_nsap,
+ 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 62f5c22..1591f7d 100644
--- a/src/iu_helpers.c
+++ b/src/iu_helpers.c
@@ -126,6 +126,56 @@ int ranap_transp_layer_addr_decode(char *addr, unsigned int addr_len,
return 0;
}
+/* (same as ranap_transp_layer_addr_decode, but AF agnostic) */
+int ranap_transp_layer_addr_decode2(struct osmo_sockaddr *addr, bool *uses_x213_nsap,
+ const RANAP_TransportLayerAddress_t *trasp_layer_addr)
+{
+ unsigned char *buf;
+ int len;
+ bool x213_nsap = false;
+ uint16_t icp;
+
+ buf = trasp_layer_addr->buf;
+ len = trasp_layer_addr->size;
+
+ memset(addr, 0, sizeof(*addr));
+
+ if (len == 20 && buf[0] == 0x35) {
+ /* For an X.213 NSAP encoded address we expect a buffer of exactly 20 bytes (3 bytes IDP + 17 bytes
+ * DSP). we also expect AFI = 0x35, which means that two byte IDI and an IP address follows. (see also
+ * comments in function new_transp_layer_addr below) */
+ x213_nsap = true;
+ icp = osmo_load16be(&buf[1]);
+ switch (icp) {
+ case 0x0000:
+ addr->u.sa.sa_family = AF_INET6;
+ memcpy(addr->u.sin6.sin6_addr.s6_addr, buf + 3, sizeof(addr->u.sin6.sin6_addr.s6_addr));
+ break;
+ case 0x0001:
+ addr->u.sa.sa_family = AF_INET;
+ memcpy((uint8_t *) &addr->u.sin.sin_addr.s_addr, buf + 3, sizeof(addr->u.sin.sin_addr.s_addr));
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (len == 4) {
+ /* A non X.213 NSAP encoded IPv4 address is 4 bytes long */
+ addr->u.sa.sa_family = AF_INET;
+ memcpy((uint8_t *) &addr->u.sin.sin_addr.s_addr, buf, sizeof(addr->u.sin.sin_addr.s_addr));
+ } else if (len == 16) {
+ /* A non X.213 NSAP encoded IPv6 address is 16 bytes long */
+ addr->u.sa.sa_family = AF_INET6;
+ memcpy(addr->u.sin6.sin6_addr.s6_addr, buf, sizeof(addr->u.sin6.sin6_addr.s6_addr));
+ } else
+ return -EINVAL;
+
+ /* In case the caller is interested in the encoding method that was used */
+ if (uses_x213_nsap)
+ *uses_x213_nsap = x213_nsap;
+
+ return 0;
+}
+
static int new_transp_layer_addr(BIT_STRING_t *out, struct osmo_sockaddr *addr, bool use_x213_nsap)
{
uint8_t *buf;
diff --git a/src/tests/test-helpers.c b/src/tests/test-helpers.c
index 5b5004a..42e8b26 100644
--- a/src/tests/test-helpers.c
+++ b/src/tests/test-helpers.c
@@ -29,6 +29,7 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/socket.h>
+#include <osmocom/core/sockaddr_str.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/ranap/RANAP_LAI.h>
@@ -347,6 +348,65 @@ void test_ranap_transp_layer_addr_decode(void)
OSMO_ASSERT(rc == 0);
}
+void test_ranap_transp_layer_addr_decode2(void)
+{
+ int rc;
+ struct osmo_sockaddr addr;
+ struct osmo_sockaddr_str sockaddr_str;
+ bool uses_x213_nsap;
+ RANAP_TransportLayerAddress_t trasp_layer_addr = { 0 };
+ uint8_t encoded_ipv4_addr_x213_nsap[] = {
+ 0x35, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
+ uint8_t encoded_ipv4_addr[] = { 0x01, 0x02, 0x03, 0x04 };
+ uint8_t encoded_ipv6_addr_x213_nsap[] = {
+ 0x35, 0x00, 0x00, 0xf1, 0x1f, 0xf2, 0x2f, 0xf3,
+ 0x3f, 0xf4, 0x4f, 0xf5, 0x5f, 0xf6, 0x6f, 0xf7,
+ 0x7f, 0xf8, 0x8f, 0x00 };
+ uint8_t encoded_ipv6_addr[] = {
+ 0xf1, 0x1f, 0xf2, 0x2f, 0xf3, 0x3f, 0xf4, 0x4f,
+ 0xf5, 0x5f, 0xf6, 0x6f, 0xf7, 0x7f, 0xf8, 0x8f };
+
+ printf("Testing function ranap_transp_layer_addr_decode2()\n");
+
+ printf(" ipv4, x213_nsap\n");
+ trasp_layer_addr.buf = encoded_ipv4_addr_x213_nsap;
+ trasp_layer_addr.size = sizeof(encoded_ipv4_addr_x213_nsap);
+ rc = ranap_transp_layer_addr_decode2(&addr, &uses_x213_nsap, &trasp_layer_addr);
+ OSMO_ASSERT(rc == 0);
+ memset(&sockaddr_str, 0, sizeof(sockaddr_str));
+ osmo_sockaddr_str_from_sockaddr_in(&sockaddr_str, &addr.u.sin);
+ printf(" addr=%s, af=%d, x213_nsap=%u\n", sockaddr_str.ip, sockaddr_str.af, uses_x213_nsap);
+
+ printf(" ipv4\n");
+ trasp_layer_addr.buf = encoded_ipv4_addr;
+ trasp_layer_addr.size = sizeof(encoded_ipv4_addr);
+ rc = ranap_transp_layer_addr_decode2(&addr, &uses_x213_nsap, &trasp_layer_addr);
+ OSMO_ASSERT(rc == 0);
+ memset(&sockaddr_str, 0, sizeof(sockaddr_str));
+ osmo_sockaddr_str_from_sockaddr_in(&sockaddr_str, &addr.u.sin);
+ printf(" addr=%s, af=%d, x213_nsap=%u\n", sockaddr_str.ip, sockaddr_str.af, uses_x213_nsap);
+
+ printf(" ipv6, x213_nsap\n");
+ trasp_layer_addr.buf = encoded_ipv6_addr_x213_nsap;
+ trasp_layer_addr.size = sizeof(encoded_ipv6_addr_x213_nsap);
+ rc = ranap_transp_layer_addr_decode2(&addr, &uses_x213_nsap, &trasp_layer_addr);
+ OSMO_ASSERT(rc == 0);
+ memset(&sockaddr_str, 0, sizeof(sockaddr_str));
+ osmo_sockaddr_str_from_sockaddr_in6(&sockaddr_str, &addr.u.sin6);
+ printf(" addr=%s, af=%d, x213_nsap=%u\n", sockaddr_str.ip, sockaddr_str.af, uses_x213_nsap);
+
+ printf(" ipv6\n");
+ trasp_layer_addr.buf = encoded_ipv6_addr;
+ trasp_layer_addr.size = sizeof(encoded_ipv6_addr);
+ rc = ranap_transp_layer_addr_decode2(&addr, &uses_x213_nsap, &trasp_layer_addr);
+ OSMO_ASSERT(rc == 0);
+ memset(&sockaddr_str, 0, sizeof(sockaddr_str));
+ osmo_sockaddr_str_from_sockaddr_in6(&sockaddr_str, &addr.u.sin6);
+ printf(" addr=%s, af=%d, x213_nsap=%u\n", sockaddr_str.ip, sockaddr_str.af, uses_x213_nsap);
+}
+
int main(int argc, char **argv)
{
asn1_xer_print = 0;
@@ -360,6 +420,7 @@ int main(int argc, char **argv)
test_ranap_new_transp_info_gtp();
test_ranap_new_transp_info_rtp();
test_ranap_transp_layer_addr_decode();
+ test_ranap_transp_layer_addr_decode2();
test_common_cleanup();
return 0;
diff --git a/src/tests/test-helpers.ok b/src/tests/test-helpers.ok
index fe08287..0626413 100644
--- a/src/tests/test-helpers.ok
+++ b/src/tests/test-helpers.ok
@@ -56,3 +56,12 @@ Testing function ranap_transp_layer_addr_decode()
addr=1.2.3.4
ipv4
addr=1.2.3.4
+Testing function ranap_transp_layer_addr_decode2()
+ ipv4, x213_nsap
+ addr=1.2.3.4, af=2, x213_nsap=1
+ ipv4
+ addr=1.2.3.4, af=2, x213_nsap=0
+ ipv6, x213_nsap
+ addr=f11f:f22f:f33f:f44f:f55f:f66f:f77f:f88f, af=10, x213_nsap=1
+ ipv6
+ addr=f11f:f22f:f33f:f44f:f55f:f66f:f77f:f88f, af=10, x213_nsap=0