Commit 827a7546 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen
Browse files

Update UDR Config

parent 56977ce6
......@@ -9,8 +9,11 @@ UDR =
NUDR:
{
INTERFACE_NAME = "eth0"; # YOUR NETWORK CONFIG HERE
IPV4_ADDRESS = "192.168.1.68";
IPV4_ADDRESS = "read";
PORT = 80; # YOUR NETWORK CONFIG HERE
HTTP2_PORT = 8080; # YOUR NETWORK CONFIG HERE
API_VERSION = "v1"; # YOUR SMF API VERSION CONFIG HERE
};
};
......
......@@ -27,6 +27,8 @@ include_directories(${SRC_TOP_DIR}/../build/ext/spdlog/include)
add_library(3GPP_COMMON_TYPES STATIC
${CMAKE_CURRENT_SOURCE_DIR}/logger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/pid_file.cpp
${CMAKE_CURRENT_SOURCE_DIR}/if.cpp
${CMAKE_CURRENT_SOURCE_DIR}/string.cpp
)
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file common_defs.h
\brief
\author Sebastien ROUX, Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_COMMON_DEFS_SEEN
#define FILE_COMMON_DEFS_SEEN
#include <arpa/inet.h>
#include <stdint.h>
#define RETURNclear (int)2
#define RETURNerror (int)1
#define RETURNok (int)0
typedef enum {
/* Fatal errors - received message should not be processed */
TLV_MAC_MISMATCH = -14,
TLV_BUFFER_NULL = -13,
TLV_BUFFER_TOO_SHORT = -12,
TLV_PROTOCOL_NOT_SUPPORTED = -11,
TLV_WRONG_MESSAGE_TYPE = -10,
TLV_OCTET_STRING_TOO_LONG_FOR_IEI = -9,
TLV_VALUE_DOESNT_MATCH = -4,
TLV_MANDATORY_FIELD_NOT_PRESENT = -3,
TLV_UNEXPECTED_IEI = -2,
TLV_ERROR_OK = RETURNok,
/* Defines error code limit below which received message should be discarded
* because it cannot be further processed */
TLV_FATAL_ERROR = TLV_VALUE_DOESNT_MATCH
} error_code_e;
//------------------------------------------------------------------------------
#define DECODE_U8(bUFFER, vALUE, sIZE) \
vALUE = *(uint8_t*)(bUFFER); \
sIZE += sizeof(uint8_t)
#define DECODE_U16(bUFFER, vALUE, sIZE) \
vALUE = ntohs(*(uint16_t*)(bUFFER)); \
sIZE += sizeof(uint16_t)
#define DECODE_U24(bUFFER, vALUE, sIZE) \
vALUE = ntohl(*(uint32_t*)(bUFFER)) >> 8; \
sIZE += sizeof(uint8_t) + sizeof(uint16_t)
#define DECODE_U32(bUFFER, vALUE, sIZE) \
vALUE = ntohl(*(uint32_t*)(bUFFER)); \
sIZE += sizeof(uint32_t)
#if (BYTE_ORDER == LITTLE_ENDIAN)
#define DECODE_LENGTH_U16(bUFFER, vALUE, sIZE) \
vALUE = ((*(bUFFER)) << 8) | (*((bUFFER) + 1)); \
sIZE += sizeof(uint16_t)
#else
#define DECODE_LENGTH_U16(bUFFER, vALUE, sIZE) \
vALUE = (*(bUFFER)) | (*((bUFFER) + 1) << 8); \
sIZE += sizeof(uint16_t)
#endif
#define ENCODE_U8(buffer, value, size) \
*(uint8_t*)(buffer) = value; \
size += sizeof(uint8_t)
#define ENCODE_U16(buffer, value, size) \
*(uint16_t*)(buffer) = htons(value); \
size += sizeof(uint16_t)
#define ENCODE_U24(buffer, value, size) \
*(uint32_t*)(buffer) = htonl(value); \
size += sizeof(uint8_t) + sizeof(uint16_t)
#define ENCODE_U32(buffer, value, size) \
*(uint32_t*)(buffer) = htonl(value); \
size += sizeof(uint32_t)
#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR, NwBo, MeSsAgE) \
do { \
struct in_addr inp; \
if (inet_aton(AdDr_StR, &inp) < 0) { \
AssertFatal(0, MeSsAgE); \
} else { \
NwBo = inp.s_addr; \
} \
} while (0)
#define NIPADDR(addr) \
(uint8_t)(addr & 0x000000FF), (uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0xFF000000) >> 24)
#define HIPADDR(addr) \
(uint8_t)((addr & 0xFF000000) >> 24), (uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0x0000FF00) >> 8), (uint8_t)(addr & 0x000000FF)
#define NIP6ADDR(addr) \
ntohs((addr)->s6_addr16[0]), ntohs((addr)->s6_addr16[1]), \
ntohs((addr)->s6_addr16[2]), ntohs((addr)->s6_addr16[3]), \
ntohs((addr)->s6_addr16[4]), ntohs((addr)->s6_addr16[5]), \
ntohs((addr)->s6_addr16[6]), ntohs((addr)->s6_addr16[7])
#define IN6_ARE_ADDR_MASKED_EQUAL(a, b, m) \
(((((__const uint32_t*)(a))[0] & (((__const uint32_t*)(m))[0])) == \
(((__const uint32_t*)(b))[0] & (((__const uint32_t*)(m))[0]))) && \
((((__const uint32_t*)(a))[1] & (((__const uint32_t*)(m))[1])) == \
(((__const uint32_t*)(b))[1] & (((__const uint32_t*)(m))[1]))) && \
((((__const uint32_t*)(a))[2] & (((__const uint32_t*)(m))[2])) == \
(((__const uint32_t*)(b))[2] & (((__const uint32_t*)(m))[2]))) && \
((((__const uint32_t*)(a))[3] & (((__const uint32_t*)(m))[3])) == \
(((__const uint32_t*)(b))[3] & (((__const uint32_t*)(m))[3]))))
////////////
#define IPV4_STR_ADDR_TO_INADDR(AdDr_StR, InAdDr, MeSsAgE) \
do { \
if (inet_aton(AdDr_StR, &InAdDr) <= 0) { \
throw(MeSsAgE); \
} \
} while (0)
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif
#endif /* FILE_COMMON_DEFS_SEEN */
/* From https://gist.github.com/javiermon/6272065#file-gateway_netlink-c */
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "if.hpp"
#include <arpa/inet.h>
#include <errno.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>
#include "common_defs.h"
#include "logger.hpp"
#define BUFFER_SIZE 4096
//------------------------------------------------------------------------------
int get_gateway_and_iface(std::string* gw, std::string* iface) {
int received_bytes = 0, msg_len = 0, route_attribute_len = 0;
int sock = -1, msgseq = 0;
struct nlmsghdr *nlh, *nlmsg;
struct rtmsg* route_entry;
// This struct contain route attributes (route type)
struct rtattr* route_attribute;
char gateway_address[INET_ADDRSTRLEN], interface[IF_NAMESIZE];
char msgbuf[BUFFER_SIZE], buffer[BUFFER_SIZE];
char* ptr = buffer;
struct timeval tv;
int rv = RETURNok;
if ((sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
Logger::system().error("socket raw/NETLINK_ROUTE failed");
return EXIT_FAILURE;
}
memset(msgbuf, 0, sizeof(msgbuf));
memset(gateway_address, 0, sizeof(gateway_address));
memset(interface, 0, sizeof(interface));
memset(buffer, 0, sizeof(buffer));
/* point the header and the msg structure pointers into the buffer */
nlmsg = (struct nlmsghdr*)msgbuf;
/* Fill in the nlmsg header*/
nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
nlmsg->nlmsg_type =
RTM_GETROUTE; // Get the routes from kernel routing table .
nlmsg->nlmsg_flags =
NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
nlmsg->nlmsg_seq = msgseq++; // Sequence of the message packet.
nlmsg->nlmsg_pid = getpid(); // PID of process sending the request.
/* 1 Sec Timeout to avoid stall */
tv.tv_sec = 1;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (struct timeval*)&tv,
sizeof(struct timeval));
/* send msg */
if (send(sock, nlmsg, nlmsg->nlmsg_len, 0) < 0) {
Logger::system().error("send socket raw/NETLINK_ROUTE failed");
return EXIT_FAILURE;
}
/* receive response */
do {
received_bytes = recv(sock, ptr, sizeof(buffer) - msg_len, 0);
if (received_bytes < 0) {
Logger::system().error("recv socket raw/NETLINK_ROUTE failed");
return EXIT_FAILURE;
}
nlh = (struct nlmsghdr*)ptr;
/* Check if the header is valid */
if ((NLMSG_OK(nlmsg, received_bytes) == 0) ||
(nlmsg->nlmsg_type == NLMSG_ERROR)) {
Logger::system().error("recv msg raw/NETLINK_ROUTE failed");
return EXIT_FAILURE;
}
/* If we received all data break */
if (nlh->nlmsg_type == NLMSG_DONE)
break;
else {
ptr += received_bytes;
msg_len += received_bytes;
}
/* Break if its not a multi part message */
if ((nlmsg->nlmsg_flags & NLM_F_MULTI) == 0) break;
} while ((nlmsg->nlmsg_seq != msgseq) || (nlmsg->nlmsg_pid != getpid()));
/* parse response */
for (; NLMSG_OK(nlh, received_bytes); nlh = NLMSG_NEXT(nlh, received_bytes)) {
/* Get the route data */
route_entry = (struct rtmsg*)NLMSG_DATA(nlh);
/* We are just interested in main routing table */
if (route_entry->rtm_table != RT_TABLE_MAIN) continue;
route_attribute = (struct rtattr*)RTM_RTA(route_entry);
route_attribute_len = RTM_PAYLOAD(nlh);
/* Loop through all attributes */
for (; RTA_OK(route_attribute, route_attribute_len);
route_attribute = RTA_NEXT(route_attribute, route_attribute_len)) {
switch (route_attribute->rta_type) {
case RTA_OIF:
if_indextoname(*(int*)RTA_DATA(route_attribute), interface);
break;
case RTA_GATEWAY:
inet_ntop(AF_INET, RTA_DATA(route_attribute), gateway_address,
sizeof(gateway_address));
break;
default:
break;
}
}
if ((*gateway_address) && (*interface)) {
*gw = std::string(gateway_address);
if (iface) {
*iface = std::string(interface);
}
break;
} else {
rv = RETURNerror;
}
}
close(sock);
return rv;
}
//------------------------------------------------------------------------------
int get_inet_addr_from_iface(const std::string& if_name,
struct in_addr& inet_addr) {
struct ifreq ifr;
char str[INET_ADDRSTRLEN];
memset(&ifr, 0, sizeof(ifr));
int fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
// strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*)if_name.c_str());
if (ioctl(fd, SIOCGIFADDR, &ifr)) {
close(fd);
Logger::system().error("Failed to probe %s inet addr: error %s\n",
if_name.c_str(), strerror(errno));
return RETURNerror;
}
close(fd);
struct sockaddr_in* ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
// check
if (inet_ntop(AF_INET, (const void*)&ipaddr->sin_addr, str,
INET_ADDRSTRLEN) == NULL) {
return RETURNerror;
}
inet_addr.s_addr = ipaddr->sin_addr.s_addr;
return RETURNok;
}
//------------------------------------------------------------------------------
int get_mtu_from_iface(const std::string& if_name, uint32_t& mtu) {
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
int fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
// strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*)if_name.c_str());
if (ioctl(fd, SIOCGIFMTU, &ifr)) {
close(fd);
Logger::system().error("Failed to probe %s MTU: error %s\n",
if_name.c_str(), strerror(errno));
return RETURNerror;
}
close(fd);
mtu = ifr.ifr_mtu;
return RETURNok;
}
//------------------------------------------------------------------------------
int get_inet_addr_infos_from_iface(const std::string& if_name,
struct in_addr& inet_addr,
struct in_addr& inet_network,
unsigned int& mtu) {
struct ifreq ifr;
char str[INET_ADDRSTRLEN];
inet_addr.s_addr = INADDR_ANY;
inet_network.s_addr = INADDR_ANY;
mtu = 0;
memset(&ifr, 0, sizeof(ifr));
int fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
// strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*)if_name.c_str());
if (ioctl(fd, SIOCGIFADDR, &ifr)) {
close(fd);
Logger::system().error("Failed to probe %s inet addr: error %s\n",
if_name.c_str(), strerror(errno));
return RETURNerror;
}
struct sockaddr_in* ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
// check
if (inet_ntop(AF_INET, (const void*)&ipaddr->sin_addr, str,
INET_ADDRSTRLEN) == NULL) {
close(fd);
return RETURNerror;
}
inet_addr.s_addr = ipaddr->sin_addr.s_addr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET;
// strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*)if_name.c_str());
if (ioctl(fd, SIOCGIFNETMASK, &ifr)) {
close(fd);
Logger::system().error("Failed to probe %s inet netmask: error %s\n",
if_name.c_str(), strerror(errno));
return RETURNerror;
}
ipaddr = (struct sockaddr_in*)&ifr.ifr_netmask;
// check
if (inet_ntop(AF_INET, (const void*)&ipaddr->sin_addr, str,
INET_ADDRSTRLEN) == NULL) {
close(fd);
return RETURNerror;
}
inet_network.s_addr = ipaddr->sin_addr.s_addr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_addr.sa_family = AF_INET;
// strncpy(ifr.ifr_name, (const char *)if_name.c_str(), IFNAMSIZ-1);
strcpy(ifr.ifr_name, (const char*)if_name.c_str());
if (ioctl(fd, SIOCGIFMTU, &ifr)) {
Logger::system().error("Failed to probe %s MTU: error %s\n",
if_name.c_str(), strerror(errno));
} else {
mtu = ifr.ifr_mtu;
}
close(fd);
return RETURNok;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file get_gateway_netlink.h
\brief
\author Lionel Gauthier
\company Eurecom
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_IF_HPP_SEEN
#define FILE_IF_HPP_SEEN
#include <string>
int get_gateway_and_iface(std::string* gw /*OUT*/, std::string* iface /*OUT*/);
int get_inet_addr_from_iface(const std::string& if_name,
struct in_addr& inet_addr);
int get_mtu_from_iface(const std::string& if_name, uint32_t& mtu);
int get_inet_addr_infos_from_iface(const std::string& if_name,
struct in_addr& inet_addr,
struct in_addr& inet_netmask,
unsigned int& mtu);
#endif /* FILE_IF_HPP_SEEN */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "string.hpp"
#include "logger.hpp"
#include <stdarg.h>
#include <algorithm>
#include <cctype>
#include <functional>
#include <locale>
template <class T>
class Buffer {
public:
explicit Buffer(size_t size) {
msize = size;
mbuf = new T[msize];
}
~Buffer() {
if (mbuf) delete[] mbuf;
}
T* get() { return mbuf; }
private:
Buffer();
size_t msize;
T* mbuf;
};
std::string util::string_format(const char* format, ...) {
va_list args;
va_start(args, format);
size_t size = vsnprintf(NULL, 0, format, args) + 1; // Extra space for '\0'
va_end(args);
Buffer<char> buf(size);
va_start(args, format);
vsnprintf(buf.get(), size, format, args);
va_end(args);
return std::string(buf.get(), size - 1); // We don't want the '\0' inside
}
// Licence : https://creativecommons.org/licenses/by-sa/4.0/legalcode
// https://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring#217605
// trim from start
std::string& util::ltrim(std::string& s) {
s.erase(s.begin(),
std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
// trim from end
std::string& util::rtrim(std::string& s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace)))
.base(),
s.end());
return s;
}
// trim from both ends
std::string& util::trim(std::string& s) { return util::ltrim(util::rtrim(s)); }
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file string.hpp
\brief
\author Lionel GAUTHIER
\date 2018
\email: lionel.gauthier@eurecom.fr
*/
#ifndef FILE_STRING_HPP_FILE_SEEN
#define FILE_STRING_HPP_FILE_SEEN
#include <arpa/inet.h>
#include <string>
namespace util {
std::string string_format(const char* format, ...);
std::string& ltrim(std::string& s);
// trim from end
std::string& rtrim(std::string& s);
// trim from both ends
std::string& trim(std::string& s);
} // namespace util
#endif
......@@ -100,12 +100,9 @@ int main(int argc, char** argv) {
}
// UDR Pistache API server (HTTP1)
/* Pistache::Address addr(
std::string(inet_ntoa(*((struct in_addr*) &udr_cfg.nudr.addr4))),
Pistache::Port(udr_cfg.nudr.port));
*/
// TODO: to be updated
Pistache::Address addr(udr_cfg.nudr.addr4, Pistache::Port(udr_cfg.nudr.port));
Pistache::Address addr(
std::string(inet_ntoa(*((struct in_addr*)&udr_cfg.nudr.addr4))),
Pistache::Port(udr_cfg.nudr.port));
api_server = new UDRApiServer(addr, udr_app_inst);
api_server->init(2);
......