git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4414 818b1a75-f10b-46b9-bf7c-635c3b92a50f
245 lines
8.6 KiB
C
Executable File
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_ */
|