Files
openairinterface5g/openair-cn/SGI/sgi.h
T
2013-11-15 13:36:54 +00:00

245 lines
8.6 KiB
C
Executable File

#ifndef SGI_H_
#define SGI_H_
#include <net/ethernet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#ifdef ENABLE_USE_PCAP_FOR_SGI
#include <pcap.h>
#endif
//#define SGI_TEST
// Packets include a ethernet header if SGI_PF_PACKET is defined
#define SGI_PF_PACKET
#include "common_types.h"
#include "hashtable.h"
#include "obj_hashtable.h"
#include "sgw_lite_ie_defs.h"
#include "ip_forward_messages_types.h"
# define SGI_IF_DEBUG(x, args...)
# define SGI_IF_ERROR(x, args...)
# define SGI_IF_WARNING(x, args...)
//-----------------------------------------------------------------------------
#ifndef SGI_IF_DEBUG
# define SGI_IF_DEBUG(x, args...) do { fprintf(stdout, "[SGI_IF][D]"x, ##args); } \
while(0)
#endif
#ifndef SGI_IF_ERROR
# define SGI_IF_ERROR(x, args...) do { fprintf(stderr, "[SGI_IF][E]"x, ##args); } \
while(0)
#endif
#ifndef SGI_IF_WARNING
# define SGI_IF_WARNING(x, args...) do { fprintf(stderr, "[SGI_IF][W]"x, ##args); } \
while(0)
#endif
// refer to 3GPP TS 23.203 V10.6.0 (2012-03) page 33
//#define MAX_DEFINED_QCI 0
#define MAX_DEFINED_QCI 9
#define SGI_MIN_EPS_BEARER_ID 5
#define SGI_MAX_SERVED_USERS_PER_PGW 1024
#define SGI_MAX_EPS_BEARERS_PER_USER 11
#define MAX_DEFINED_IPV6_ADDRESSES_PER_UE 16
#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 NIPADDR(addr) \
(uint8_t)(addr & 0x000000FF), \
(uint8_t)((addr & 0x0000FF00) >> 8), \
(uint8_t)((addr & 0x00FF0000) >> 16), \
(uint8_t)((addr & 0xFF000000) >> 24)
#define NMACADDR(addr) \
(uint8_t)(addr[0]), \
(uint8_t)(addr[1]), \
(uint8_t)(addr[2]), \
(uint8_t)(addr[3]), \
(uint8_t)(addr[4]), \
(uint8_t)(addr[5])
#ifdef VLAN8021Q
typedef struct vlan_tag_s {
uint16_t vlan_tpid; /* ETH_P_8021Q */
uint16_t vlan_tci; /* VLAN TCI */
} vlan_tag_t __attribute__ ((__packed__));
typedef struct ether_header_8021q_s
{
u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
vlan_tag_t ether_vlan8021q;
u_int16_t ether_type; /* packet type ID field */
} ether_header_8021q_t __attribute__ ((__packed__));
#endif
typedef struct arphdr_s {
__be16 ar_hrd; /* format of hardware address */
__be16 ar_pro; /* format of protocol address */
unsigned char ar_hln; /* length of hardware address */
unsigned char ar_pln; /* length of protocol address */
__be16 ar_op; /* ARP opcode (command) */
/*
* Ethernet looks like this : This bit is variable sized however...
*/
unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
unsigned char ar_sip[4]; /* sender IP address */
unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
unsigned char ar_tip[4]; /* target IP address */
}arphdr_t;
typedef struct sgi_teid_mapping_s {
int is_outgoing_ipv4_packet_seen;
int is_outgoing_ipv6_packet_seen;
Teid_t enb_S1U_teid; ///< dest tunnel identifier
qci_t qci;
ebi_t eps_bearer_id; ///< EPS bearer identifier
char hw_addrlen;
#ifdef SGI_UE_ETHER_TRAFFIC
char ue_mac_addr[8];
#endif
struct in6_addr in6_addr_captured[MAX_DEFINED_IPV6_ADDRESSES_PER_UE];
struct in_addr in_add_captured;
} sgi_teid_mapping_t;
// Main goal is to do an association IP address <-> MAC address
// may be usefull for netfilter that does not capture MAC address
// if not set on certain hook points (table,path).
typedef struct sgi_addr_mapping_s {
int is_outgoing_packet_seen;
ebi_t eps_bearer_id; ///< EPS default bearer identifier, (really ?)
Teid_t enb_S1U_teid; ///< dest tunnel identifier, for default bearer
Teid_t sgw_S1U_teid; ///< dest tunnel identifier, for default bearer
#ifdef SGI_UE_ETHER_TRAFFIC
char ue_mac_addr[ETH_ALEN];
#endif
} sgi_addr_mapping_t;
typedef struct sgi_data_s {
int sd[SGI_MAX_EPS_BEARERS_PER_USER];
int sd6;
char *interface_name;
int interface_name_len;
int interface_index;
#ifndef SGI_UE_ETHER_TRAFFIC
char interface_hw_address[ETH_ALEN];
#ifdef VLAN8021Q
struct ether_header_8021q_s eh;
#else
struct ether_header eh;
#endif
#endif
uint32_t ipv4_addr;
hash_table_t *teid_mapping;
hash_table_t *addr_v4_mapping;
obj_hash_table_t *addr_v6_mapping;
pthread_t capture_on_sgi_if_thread;
pthread_mutex_t thread_started_mutex;
int thread_started;
void *sock_mmap_ring;
struct iovec *malloc_ring;
int hw_address_of_router_captured;
uint32_t local_addr_v4_4_hw_address_router_capture;
uint32_t ipv4_addr_of_router;
#ifdef ENABLE_USE_PCAP_FOR_SGI
//brief PCAP descriptor for capturing packets on SGI interface.
pcap_t * pcap_descr;
#endif
#define SGI_BUFFER_RECV_LEN 3000
unsigned char recv_buffer[sizeof(struct ether_header) + SGI_BUFFER_RECV_LEN][SGI_MAX_EPS_BEARERS_PER_USER];
} sgi_data_t;
typedef struct sgi_read_thread_args_s {
sgi_data_t *sgi_data;
int socket_index;
}sgi_read_thread_args_t;
//-----------------------------------------------------------------------------
#include "mme_config.h"
#define SGI_MAX_EPS_BEARERS (SGI_MAX_SERVED_USERS_PER_PGW*SGI_MAX_EPS_BEARERS_PER_USER)
//-----------------------------------------------------------------------------
// sgi_task.c
//-----------------------------------------------------------------------------
int sgi_init(const mme_config_t *mme_config);
char* sgi_status_2_str(SGIStatus_t statusP);
//-----------------------------------------------------------------------------
// sgi_nf.c
//-----------------------------------------------------------------------------
#ifdef ENABLE_USE_NETFILTER_FOR_SGI
void* sgi_nf_fw_2_gtpv1u_thread(void *args_p);
#endif
//-----------------------------------------------------------------------------
// sgi_pcap.c
//-----------------------------------------------------------------------------
#ifdef ENABLE_USE_PCAP_FOR_SGI
# define SGI_PCAPMAXBYTES2CAPTURE 65535
# define SGI_PCAPTIMEDELAYKERNEL2USERSPACE 1000
/*! \fn void* sgi_pcap_loop(void*)
* \brief
* \param[in] devname The name of the device (ex "eth1") that will be listened for capturing packets.
* \param[in] iif The interface identifier that will be listened for capturing packets.
*/
void* sgi_pcap_fw_2_gtpv1u_thread(void*);
#endif
//-----------------------------------------------------------------------------
// sgi_util.c
//-----------------------------------------------------------------------------
void sgi_print_hex_octets(unsigned char* dataP, unsigned long sizeP);
char* sgi_status_2_str (SGIStatus_t statusP);
char* sgi_arpopcode_2_str (unsigned short int opcodeP);
unsigned short in_cksum(unsigned short *addr, int len);
void sgi_send_arp_request(sgi_data_t *sgi_dataP, char* dst_ip_addrP);
//-----------------------------------------------------------------------------
// sgi_socket.c
//-----------------------------------------------------------------------------
int sgi_create_sockets(sgi_data_t *sgi_data_p);
int sgi_send_data(uint8_t *buffer, uint32_t length, sgi_data_t *sgi_dataP, Teid_t originating_sgw_S1u_teidP);
#ifdef SGI_TEST
unsigned short in_cksum(unsigned short *addr, int len);
void sgi_test_send_ping(sgi_data_t *sgi_dataP, uint32_t markP, uint64_t src_mac_addrP, uint64_t dst_mac_addrP, char* src_ip_addrP, char* dst_ip_addrP);
#endif
#ifdef ENABLE_USE_RAW_SOCKET_FOR_SGI
void sgi_sock_raw_cleanup_handler(void *args_p);
void* sgi_sock_raw_fw_2_gtpv1u_thread(void* args_p);
#endif
//-----------------------------------------------------------------------------
// sgi_egress.c
//-----------------------------------------------------------------------------
void sgi_forward_ip_packet(sgi_data_t *sgi_dataP, struct ether_header *ehP, int packet_sizeP, sgi_addr_mapping_t *addr_mappingP);
#ifdef ENABLE_USE_RAW_SOCKET_FOR_SGI
void sgi_process_raw_packet(sgi_data_t *sgi_dataP, unsigned char* dataP, int packet_sizeP);
#endif
#endif /* SGI_H_ */