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
This commit is contained in:
Philipp Maier 2022-01-10 13:54:57 +01:00 committed by laforge
parent 45631aa04f
commit c0a0b2562b
4 changed files with 122 additions and 0 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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