2017-09-13 07:22:39 +00:00
|
|
|
#define TRACE_MODULE _gtp_conv
|
|
|
|
|
|
|
|
#include "core_debug.h"
|
2017-12-05 04:28:34 +00:00
|
|
|
#include "core_network.h"
|
2017-09-13 07:22:39 +00:00
|
|
|
|
2017-12-03 12:34:39 +00:00
|
|
|
#include "gtp_message.h"
|
|
|
|
#include "gtp_types.h"
|
2017-09-13 07:22:39 +00:00
|
|
|
#include "gtp_conv.h"
|
|
|
|
|
|
|
|
void gtp_bearers_in_create_indirect_tunnel_request(
|
|
|
|
tlv_bearer_context_t *bearers[][GTP_MAX_NUM_OF_INDIRECT_TUNNEL],
|
|
|
|
gtp_create_indirect_data_forwarding_tunnel_request_t *req)
|
|
|
|
{
|
|
|
|
|
|
|
|
(*bearers)[0] = &req->bearer_context_0;
|
|
|
|
(*bearers)[1] = &req->bearer_context_1;
|
|
|
|
(*bearers)[2] = &req->bearer_context_2;
|
|
|
|
(*bearers)[3] = &req->bearer_context_3;
|
|
|
|
(*bearers)[4] = &req->bearer_context_4;
|
|
|
|
(*bearers)[5] = &req->bearer_context_5;
|
|
|
|
(*bearers)[6] = &req->bearer_context_6;
|
|
|
|
(*bearers)[7] = &req->bearer_context_7;
|
|
|
|
(*bearers)[8] = &req->bearer_context_8;
|
|
|
|
(*bearers)[9] = &req->bearer_context_9;
|
|
|
|
(*bearers)[10] = &req->bearer_context_10;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gtp_bearers_in_create_indirect_tunnel_response(
|
|
|
|
tlv_bearer_context_t *bearers[][GTP_MAX_NUM_OF_INDIRECT_TUNNEL],
|
|
|
|
gtp_create_indirect_data_forwarding_tunnel_response_t *rsp)
|
|
|
|
{
|
|
|
|
(*bearers)[0] = &rsp->bearer_context_0;
|
|
|
|
(*bearers)[1] = &rsp->bearer_context_1;
|
|
|
|
(*bearers)[2] = &rsp->bearer_context_2;
|
|
|
|
(*bearers)[3] = &rsp->bearer_context_3;
|
|
|
|
(*bearers)[4] = &rsp->bearer_context_4;
|
|
|
|
(*bearers)[5] = &rsp->bearer_context_5;
|
|
|
|
(*bearers)[6] = &rsp->bearer_context_6;
|
|
|
|
(*bearers)[7] = &rsp->bearer_context_7;
|
|
|
|
(*bearers)[8] = &rsp->bearer_context_8;
|
|
|
|
(*bearers)[9] = &rsp->bearer_context_9;
|
|
|
|
(*bearers)[10] = &rsp->bearer_context_10;
|
|
|
|
}
|
2017-12-05 04:28:34 +00:00
|
|
|
|
|
|
|
status_t gtp_f_teid_to_sockaddr(
|
|
|
|
gtp_f_teid_t *f_teid, c_uint16_t port, c_sockaddr_t **list)
|
|
|
|
{
|
|
|
|
c_sockaddr_t *addr = NULL, *addr6 = NULL;
|
|
|
|
|
|
|
|
d_assert(f_teid, return CORE_ERROR,);
|
|
|
|
d_assert(list, return CORE_ERROR,);
|
|
|
|
|
|
|
|
addr = core_calloc(1, sizeof(c_sockaddr_t));
|
|
|
|
d_assert(addr, return CORE_ERROR,);
|
|
|
|
addr->c_sa_family = AF_INET;
|
|
|
|
addr->c_sa_port = htons(port);
|
|
|
|
|
|
|
|
addr6 = core_calloc(1, sizeof(c_sockaddr_t));
|
|
|
|
d_assert(addr6, return CORE_ERROR,);
|
|
|
|
addr6->c_sa_family = AF_INET6;
|
|
|
|
addr6->c_sa_port = htons(port);
|
|
|
|
|
|
|
|
if (f_teid->ipv4 && f_teid->ipv6)
|
|
|
|
{
|
|
|
|
addr->next = addr6;
|
|
|
|
|
2017-12-07 05:48:25 +00:00
|
|
|
addr->sin.sin_addr.s_addr = f_teid->both.addr;
|
|
|
|
memcpy(addr6->sin6.sin6_addr.s6_addr, f_teid->both.addr6, IPV6_LEN);
|
2017-12-06 03:13:56 +00:00
|
|
|
|
|
|
|
*list = addr;
|
2017-12-05 04:28:34 +00:00
|
|
|
}
|
|
|
|
else if (f_teid->ipv4)
|
|
|
|
{
|
2017-12-07 05:48:25 +00:00
|
|
|
addr->sin.sin_addr.s_addr = f_teid->addr;
|
2017-12-05 04:28:34 +00:00
|
|
|
core_free(addr6);
|
2017-12-06 03:13:56 +00:00
|
|
|
|
|
|
|
*list = addr;
|
2017-12-05 04:28:34 +00:00
|
|
|
}
|
|
|
|
else if (f_teid->ipv6)
|
|
|
|
{
|
2017-12-07 05:48:25 +00:00
|
|
|
memcpy(addr6->sin6.sin6_addr.s6_addr, f_teid->addr6, IPV6_LEN);
|
2017-12-05 04:28:34 +00:00
|
|
|
core_free(addr);
|
2017-12-06 03:13:56 +00:00
|
|
|
|
|
|
|
*list = addr6;
|
2017-12-05 04:28:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
core_free(addr);
|
|
|
|
core_free(addr6);
|
|
|
|
d_assert(0, return CORE_ERROR,);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
status_t gtp_sockaddr_to_f_teid(
|
2017-12-07 07:51:21 +00:00
|
|
|
c_sockaddr_t *addr, c_sockaddr_t *addr6, gtp_f_teid_t *f_teid, int *len)
|
2017-12-05 04:28:34 +00:00
|
|
|
{
|
|
|
|
d_assert(f_teid, return CORE_ERROR,);
|
|
|
|
|
|
|
|
if (addr && addr6)
|
|
|
|
{
|
|
|
|
f_teid->ipv4 = 1;
|
2017-12-07 05:48:25 +00:00
|
|
|
f_teid->both.addr = addr->sin.sin_addr.s_addr;
|
2017-12-05 04:28:34 +00:00
|
|
|
f_teid->ipv6 = 1;
|
2017-12-07 05:48:25 +00:00
|
|
|
memcpy(f_teid->both.addr6, addr6->sin6.sin6_addr.s6_addr, IPV6_LEN);
|
2017-12-07 07:51:21 +00:00
|
|
|
*len = GTP_F_TEID_IPV4V6_LEN;
|
2017-12-05 04:28:34 +00:00
|
|
|
}
|
|
|
|
else if (addr)
|
|
|
|
{
|
|
|
|
f_teid->ipv4 = 1;
|
2017-12-09 09:50:12 +00:00
|
|
|
f_teid->ipv6 = 0;
|
2017-12-07 05:48:25 +00:00
|
|
|
f_teid->addr = addr->sin.sin_addr.s_addr;
|
2017-12-07 07:51:21 +00:00
|
|
|
*len = GTP_F_TEID_IPV4_LEN;
|
2017-12-05 04:28:34 +00:00
|
|
|
}
|
|
|
|
else if (addr6)
|
|
|
|
{
|
2017-12-09 09:50:12 +00:00
|
|
|
f_teid->ipv4 = 0;
|
2017-12-05 04:28:34 +00:00
|
|
|
f_teid->ipv6 = 1;
|
2017-12-07 05:48:25 +00:00
|
|
|
memcpy(f_teid->addr6, addr6->sin6.sin6_addr.s6_addr, IPV6_LEN);
|
2017-12-07 07:51:21 +00:00
|
|
|
*len = GTP_F_TEID_IPV6_LEN;
|
2017-12-05 04:28:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
d_assert(0, return CORE_ERROR,);
|
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
2017-12-07 04:27:17 +00:00
|
|
|
|
2017-12-07 07:51:21 +00:00
|
|
|
status_t gtp_f_teid_to_ip(gtp_f_teid_t *f_teid, ip_t *ip)
|
2017-12-07 04:27:17 +00:00
|
|
|
{
|
2017-12-07 07:51:21 +00:00
|
|
|
d_assert(ip, return CORE_ERROR,);
|
|
|
|
d_assert(f_teid, return CORE_ERROR,);
|
2017-12-07 06:04:35 +00:00
|
|
|
|
|
|
|
memset(ip, 0, sizeof(ip_t));
|
|
|
|
|
|
|
|
ip->ipv4 = f_teid->ipv4;
|
|
|
|
ip->ipv6 = f_teid->ipv6;
|
|
|
|
|
|
|
|
if (ip->ipv4 && ip->ipv6)
|
|
|
|
{
|
|
|
|
ip->both.addr = f_teid->both.addr;
|
|
|
|
memcpy(ip->both.addr6, f_teid->both.addr6, IPV6_LEN);
|
2017-12-07 07:51:21 +00:00
|
|
|
ip->len = IPV4V6_LEN;
|
2017-12-07 06:04:35 +00:00
|
|
|
}
|
|
|
|
else if (ip->ipv4)
|
|
|
|
{
|
|
|
|
ip->addr = f_teid->addr;
|
2017-12-07 07:51:21 +00:00
|
|
|
ip->len = IPV4_LEN;
|
2017-12-07 06:04:35 +00:00
|
|
|
}
|
|
|
|
else if (ip->ipv6)
|
|
|
|
{
|
|
|
|
memcpy(ip->addr6, f_teid->addr6, IPV6_LEN);
|
2017-12-07 07:51:21 +00:00
|
|
|
ip->len = IPV6_LEN;
|
2017-12-07 06:04:35 +00:00
|
|
|
}
|
|
|
|
else
|
2017-12-07 07:51:21 +00:00
|
|
|
d_assert(0, return CORE_ERROR,);
|
2017-12-07 06:04:35 +00:00
|
|
|
|
2017-12-07 07:51:21 +00:00
|
|
|
return CORE_OK;
|
2017-12-07 06:04:35 +00:00
|
|
|
}
|
|
|
|
|
2017-12-07 07:51:21 +00:00
|
|
|
status_t gtp_ip_to_f_teid(ip_t *ip, gtp_f_teid_t *f_teid, int *len)
|
2017-12-07 06:04:35 +00:00
|
|
|
{
|
2017-12-07 07:51:21 +00:00
|
|
|
d_assert(ip, return CORE_ERROR,);
|
|
|
|
d_assert(f_teid, return CORE_ERROR,);
|
2017-12-07 06:04:35 +00:00
|
|
|
|
|
|
|
f_teid->ipv4 = ip->ipv4;
|
|
|
|
f_teid->ipv6 = ip->ipv6;
|
|
|
|
|
|
|
|
if (f_teid->ipv4 && f_teid->ipv6)
|
|
|
|
{
|
|
|
|
f_teid->both.addr = ip->both.addr;
|
|
|
|
memcpy(f_teid->both.addr6, ip->both.addr6, IPV6_LEN);
|
2017-12-07 07:51:21 +00:00
|
|
|
*len = GTP_F_TEID_IPV4V6_LEN;
|
2017-12-07 06:04:35 +00:00
|
|
|
}
|
|
|
|
else if (f_teid->ipv4)
|
|
|
|
{
|
|
|
|
f_teid->addr = ip->addr;
|
2017-12-07 07:51:21 +00:00
|
|
|
*len = GTP_F_TEID_IPV4_LEN;
|
2017-12-07 06:04:35 +00:00
|
|
|
}
|
|
|
|
else if (f_teid->ipv6)
|
|
|
|
{
|
|
|
|
memcpy(f_teid->addr6, ip->addr6, IPV6_LEN);
|
2017-12-07 07:51:21 +00:00
|
|
|
*len = GTP_F_TEID_IPV6_LEN;
|
2017-12-07 06:04:35 +00:00
|
|
|
}
|
|
|
|
else
|
2017-12-07 07:51:21 +00:00
|
|
|
d_assert(0, return CORE_ERROR,);
|
2017-12-07 06:04:35 +00:00
|
|
|
|
2017-12-07 07:51:21 +00:00
|
|
|
return CORE_OK;
|
2017-12-07 06:04:35 +00:00
|
|
|
}
|