sgi.h 10.7 KB
Newer Older
Lionel Gauthier's avatar
Lionel Gauthier committed
1
/*******************************************************************************
Lionel Gauthier's avatar
GPLv3  
Lionel Gauthier committed
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
Lionel Gauthier's avatar
Lionel Gauthier committed
4

Lionel Gauthier's avatar
GPLv3  
Lionel Gauthier committed
5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
Lionel Gauthier's avatar
Lionel Gauthier committed
9 10


Lionel Gauthier's avatar
GPLv3  
Lionel Gauthier committed
11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
Lionel Gauthier's avatar
Lionel Gauthier committed
15

Lionel Gauthier's avatar
GPLv3  
Lionel Gauthier committed
16 17 18 19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
   see <http://www.gnu.org/licenses/>.
Lionel Gauthier's avatar
Lionel Gauthier committed
20

Lionel Gauthier's avatar
GPLv3  
Lionel Gauthier committed
21 22 23 24 25 26 27 28
  Contact Information
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.

 *******************************************************************************/
Lionel Gauthier's avatar
Lionel Gauthier committed
29 30 31 32 33 34
/*! \file sgi.h
* \brief
* \author Lionel Gauthier
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
Cedric Roux's avatar
 
Cedric Roux committed
35 36 37 38 39 40 41 42
#ifndef SGI_H_
#define SGI_H_

#include <net/ethernet.h>
#include <netinet/in.h>
#include <pthread.h>
 #include <stdio.h>

Lionel Gauthier's avatar
 
Lionel Gauthier committed
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#ifdef ENABLE_USE_NETFILTER_FOR_SGI
#warning "ENABLE_USE_NETFILTER_FOR_SGI"
#define SGI_SOCKET_RAW        1
#define SGI_SOCKET_BIND_TO_IF 1
#undef  SGI_MARKING
#undef  SGI_PACKET_RX_RING
#undef  SGI_SOCKET_UDP
#else
#warning "DISABLE_USE_NETFILTER_FOR_SGI"
//#define  SGI_SOCKET_RAW        1
#undef  SGI_SOCKET_RAW
#define SGI_SOCKET_DGRAM      1
#define SGI_SOCKET_BIND_TO_IF 1
#undef  SGI_PACKET_RX_RING
#undef  SGI_MARKING
#undef  SGI_SOCKET_UDP
#endif

Cedric Roux's avatar
 
Cedric Roux committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74
#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"

Raymond Knopp's avatar
 
Raymond Knopp committed
75 76 77
# define SGI_IF_DEBUG(x, args...)
# define SGI_IF_ERROR(x, args...)
# define SGI_IF_WARNING(x, args...)
Cedric Roux's avatar
 
Cedric Roux committed
78 79 80 81 82 83 84 85 86 87
//-----------------------------------------------------------------------------
#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
Cedric Roux's avatar
Cedric Roux committed
88 89
 # define SGI_IF_WARNING(x, args...) do { fprintf(stderr, "[SGI_IF][W]"x, ##args); } \
     while(0)
Cedric Roux's avatar
 
Cedric Roux committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
#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];
Lionel Gauthier's avatar
 
Lionel Gauthier committed
188
    unsigned int        if_index[SGI_MAX_EPS_BEARERS_PER_USER];
Cedric Roux's avatar
 
Cedric Roux committed
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    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;
Lionel Gauthier's avatar
Lionel Gauthier committed
215
    char                hss_associated;
Cedric Roux's avatar
 
Cedric Roux committed
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243


#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
//-----------------------------------------------------------------------------
Lionel Gauthier's avatar
Lionel Gauthier committed
244 245
#include "spgw_config.h"
int sgi_init(const pgw_config_t *pgw_config_p);
Cedric Roux's avatar
 
Cedric Roux committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
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);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
283 284
int sgi_dgram_send_data(uint8_t *buffer_pP, uint32_t length, sgi_data_t *sgi_data_pP, Teid_t originating_sgw_S1u_teidP);

Cedric Roux's avatar
 
Cedric Roux committed
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
#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
Lionel Gauthier's avatar
 
Lionel Gauthier committed
301
void sgi_process_dgram_packet(sgi_data_t *sgi_dataP, unsigned char* dataP, int packet_sizeP);
Cedric Roux's avatar
 
Cedric Roux committed
302
#endif /* SGI_H_ */