Commit ea655773 authored by Lionel Gauthier's avatar Lionel Gauthier

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7535 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 9aa4543a
This diff is collapsed.
################################################################################
# OpenAirInterface
# Copyright(c) 1999 - 2014 Eurecom
#
# 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.
#
#
# 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.
#
# 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/>.
#
# 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.
#
################################################################################
AM_CFLAGS = @ADD_CFLAGS@ \
-I$(top_srcdir)/COMMON \
-I$(top_srcdir)/SGW-LITE \
-I$(top_srcdir)/UTILS \
-I$(top_srcdir)/UTILS/HASHTABLE \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/api/network \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/include \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/ies \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/emm/msg \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/esm/msg \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/util \
-I$(top_srcdir)/GTPV1-U \
-I$(top_srcdir)/INTERTASK_INTERFACE
noinst_LTLIBRARIES = libsgi.la
libsgi_la_LDFLAGS = -all-static
libsgi_la_SOURCES = \
sgi_task.c sgi.h \
sgi_socket.c \
sgi_egress.c \
sgi_util.c
if ENABLE_USE_PCAP_FOR_SGI
libsgi_la_SOURCES += sgi_pcap.c \
/usr/lib/libpcap.a
endif
if ENABLE_USE_NETFILTER_FOR_SGI
libsgi_la_SOURCES += sgi_nf.c \
/usr/lib/libnetfilter_queue.a \
/usr/lib/libnfnetlink.la
endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
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.
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.
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/>.
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.
*******************************************************************************/
/*! \file sgi_pcap.c
* \brief
* \author Lionel Gauthier
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
#include <string.h>
#include "sgi.h"
//---------------------------------------------------------------------------------------------------------------------
void* sgi_pcap_fw_2_gtpv1u_thread(void* args_p)
{
bpf_u_int32 netaddr = 0, mask = 0; // To store network address and netmask
struct bpf_program filter; // Place to store the BPF filter program
char errbuf[PCAP_ERRBUF_SIZE]; // Error buffer
struct pcap_pkthdr pkthdr; // Packet information (timestamp, size...)
const unsigned char *packet = NULL; // Received raw data
char filter_string[] = "";
sgi_data_t *sgi_data_p;
sgi_data_p = (sgi_data_t*)args_p;
SGI_IF_DEBUG("[PCAP] Device is %s and iif is %d\n", sgi_data_p->interface_name, sgi_data_p->interface_index);
memset(errbuf, 0, PCAP_ERRBUF_SIZE);
sgi_data_p->pcap_descr = pcap_open_live(sgi_data_p->interface_name, SGI_PCAPMAXBYTES2CAPTURE, 0, SGI_PCAPTIMEDELAYKERNEL2USERSPACE, errbuf);
if (sgi_data_p->pcap_descr == NULL)
SGI_IF_ERROR("Error %s", errbuf);
else if (*errbuf)
SGI_IF_WARNING("Warning %s\n", errbuf);
// Look up info from the capture device
if (pcap_lookupnet(sgi_data_p->interface_name, &netaddr, &mask, errbuf) == -1) {
SGI_IF_ERROR("Can't get netmask for device %s\n", sgi_data_p->interface_name);
netaddr = 0;
mask = 0;
pthread_exit(NULL);
}
// Compiles the filter expression into a BPF filter program
if (pcap_compile(sgi_data_p->pcap_descr, &filter, filter_string, 0, mask) == -1) {
SGI_IF_ERROR("Couldn't parse filter : %s\n", pcap_geterr(sgi_data_p->pcap_descr));
pthread_exit(NULL);
}
// Load the filter program into the packet capture device
if (pcap_setfilter(sgi_data_p->pcap_descr, &filter) == -1) {
SGI_IF_ERROR("Couldn't install filter: %s\n", pcap_geterr(sgi_data_p->pcap_descr));
pthread_exit(NULL);
}
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
sgi_data_p->thread_started = 1;
while (1) {
packet = pcap_next(sgi_data_p->pcap_descr, &pkthdr); // Get one packet
if ( ( pkthdr.len > 0 ) && ( packet != NULL ) ) {
sgi_print_hex_octets(packet, pkthdr.len);
if (packet[54] == 0x85) { // case ROUTER SOLICITATION WITH ETHERNET HEADER
}
}
}
pthread_exit(NULL);
}
This diff is collapsed.
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
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.
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.
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/>.
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.
*******************************************************************************/
/*! \file sgi_util.c
* \brief
* \author Lionel Gauthier
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include "sgi.h"
#define FW_2_PRINT_BUFFER_LEN 10000
static char fw_2_print_buffer[FW_2_PRINT_BUFFER_LEN];
//-----------------------------------------------------------------------------
void sgi_print_hex_octets(unsigned char* dataP, unsigned long sizeP)
//-----------------------------------------------------------------------------
{
unsigned long octet_index = 0;
unsigned long buffer_marker = 0;
unsigned char aindex;
struct timeval tv;
struct timezone tz;
char timeofday[64];
unsigned int h,m,s;
if (dataP == NULL) {
return;
}
gettimeofday(&tv, &tz);
h = (tv.tv_sec/3600) % 24;
m = (tv.tv_sec / 60) % 60;
s = tv.tv_sec % 60;
snprintf(timeofday, 64, "%02d:%02d:%02d.%06d", h,m,s,tv.tv_usec);
SGI_IF_DEBUG("%s------+-------------------------------------------------+\n",timeofday);
SGI_IF_DEBUG("%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday);
SGI_IF_DEBUG("%s------+-------------------------------------------------+\n",timeofday);
for (octet_index = 0; octet_index < sizeP; octet_index++) {
if ((octet_index % 16) == 0) {
if (octet_index != 0) {
buffer_marker+=snprintf(&fw_2_print_buffer[buffer_marker], FW_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
SGI_IF_DEBUG("%s%s",timeofday, fw_2_print_buffer);
buffer_marker = 0;
}
buffer_marker+=snprintf(&fw_2_print_buffer[buffer_marker], FW_2_PRINT_BUFFER_LEN - buffer_marker, " %04ld |", octet_index);
}
/*
* Print every single octet in hexadecimal form
*/
buffer_marker+=snprintf(&fw_2_print_buffer[buffer_marker], FW_2_PRINT_BUFFER_LEN - buffer_marker, " %02x", dataP[octet_index]);
/*
* Align newline and pipes according to the octets in groups of 2
*/
}
/*
* Append enough spaces and put final pipe
*/
for (aindex = octet_index; aindex < 16; ++aindex)
buffer_marker+=snprintf(&fw_2_print_buffer[buffer_marker], FW_2_PRINT_BUFFER_LEN - buffer_marker, " ");
//SGI_IF_DEBUG(" ");
buffer_marker+=snprintf(&fw_2_print_buffer[buffer_marker], FW_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
SGI_IF_DEBUG("%s%s",timeofday,fw_2_print_buffer);
}
//-----------------------------------------------------------------------------
char* sgi_status_2_str(SGIStatus_t statusP)
//-----------------------------------------------------------------------------
{
switch (statusP) {
case SGI_STATUS_OK:
return "SGI_STATUS_OK";
break;
case SGI_STATUS_ERROR_CONTEXT_ALREADY_EXIST:
return "SGI_STATUS_ERROR_CONTEXT_ALREADY_EXIST";
break;
case SGI_STATUS_ERROR_CONTEXT_NOT_FOUND:
return "SGI_STATUS_ERROR_CONTEXT_NOT_FOUND";
break;
case SGI_STATUS_ERROR_INVALID_MESSAGE_FORMAT:
return "SGI_STATUS_ERROR_INVALID_MESSAGE_FORMAT";
break;
case SGI_STATUS_ERROR_SERVICE_NOT_SUPPORTED:
return "SGI_STATUS_ERROR_SERVICE_NOT_SUPPORTED";
break;
case SGI_STATUS_ERROR_SYSTEM_FAILURE:
return "SGI_STATUS_ERROR_SYSTEM_FAILURE";
break;
case SGI_STATUS_ERROR_NO_RESOURCES_AVAILABLE:
return "SGI_STATUS_ERROR_NO_RESOURCES_AVAILABLE";
break;
case SGI_STATUS_ERROR_NO_MEMORY_AVAILABLE:
return "SGI_STATUS_ERROR_NO_MEMORY_AVAILABLE";
break;
default:
return "UNKNOWN_SGI_STATUS";
}
}
//-----------------------------------------------------------------------------
char* sgi_arpopcode_2_str(unsigned short int opcodeP)
//-----------------------------------------------------------------------------
{
switch (opcodeP) {
case ARPOP_REQUEST:
return "ARPOP_REQUEST";
break;
case ARPOP_REPLY:
return "ARPOP_REPLY";
break;
case ARPOP_RREQUEST:
return "ARPOP_RREQUEST";
break;
case ARPOP_RREPLY:
return "ARPOP_RREPLY";
break;
case ARPOP_InREQUEST:
return "ARPOP_InREQUEST";
break;
case ARPOP_InREPLY:
return "ARPOP_InREPLY";
break;
case ARPOP_NAK:
return "ARPOP_NAK";
break;
default:
return "UNKNOWN_ARP_OPCODE";
}
}
//-----------------------------------------------------------------------------
unsigned short in_cksum(unsigned short *addr, int len)
//-----------------------------------------------------------------------------
{
register int sum = 0;
u_short answer = 0;
register u_short *w = addr;
register int nleft = len;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
//-----------------------------------------------------------------------------
void sgi_send_arp_request(sgi_data_t *sgi_dataP, char* dst_ip_addrP)
//-----------------------------------------------------------------------------
{
char buffer[100]; // ARP request is 60 bytes including ethernet
struct arphdr_s *arph = (struct arphdr_s *)(buffer);
struct hostent *hp = NULL;
uint32_t i;
struct in_addr ip_dst;
struct ifreq ifr;
struct iovec iov[2];
sgi_dataP->eh.ether_dhost[0] = (u_int8_t)(0xFF);
sgi_dataP->eh.ether_dhost[1] = (u_int8_t)(0xFF);
sgi_dataP->eh.ether_dhost[2] = (u_int8_t)(0xFF);
sgi_dataP->eh.ether_dhost[3] = (u_int8_t)(0xFF);
sgi_dataP->eh.ether_dhost[4] = (u_int8_t)(0xFF);
sgi_dataP->eh.ether_dhost[5] = (u_int8_t)(0xFF);
// get IP address of the default virtual interface
ifr.ifr_addr.sa_family = AF_INET;
sprintf(ifr.ifr_name, "%s.%d",sgi_dataP->interface_name,SGI_MIN_EPS_BEARER_ID);
if (ioctl(sgi_dataP->sd[0], SIOCGIFADDR, &ifr) != 0) {
SGI_IF_ERROR("Error during IP ADDRESS RETRIEVAL ON SGI INTERFACE (%s:%d)\n",strerror(errno), errno);
exit (-1);
}
if ((hp = gethostbyname(dst_ip_addrP)) == NULL) {
SGI_IF_DEBUG("gethostbyname() is OK.\n");
if ((ip_dst.s_addr = inet_addr(dst_ip_addrP)) == -1) {
SGI_IF_ERROR("%s: Can't resolve, unknown host.\n", dst_ip_addrP);
exit(1);
}
} else
bcopy(hp->h_addr_list[0], &ip_dst.s_addr, hp->h_length);
arph->ar_hrd = htons(ARPHRD_ETHER);
arph->ar_pro = htons(ETH_P_IP);
arph->ar_hln = ETH_ALEN;
arph->ar_pln = 4;
arph->ar_op = htons(ARPOP_REQUEST);
// sources
memcpy(arph->ar_sha, sgi_dataP->eh.ether_shost, ETH_ALEN);
i = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
arph->ar_sip[3] = i >> 24;
arph->ar_sip[2] = (i & 0x00FF0000) >> 16;
arph->ar_sip[1] = (i & 0x0000FF00) >> 8;
arph->ar_sip[0] = (i & 0x000000FF);
// destinations
memset(arph->ar_tha, 0, ETH_ALEN);
i = ip_dst.s_addr;
arph->ar_tip[3] = i >> 24;
arph->ar_tip[2] = (i & 0x00FF0000) >> 16;
arph->ar_tip[1] = (i & 0x0000FF00) >> 8;
arph->ar_tip[0] = (i & 0x000000FF);
// save ip address of router for comparing with ARP REPLY
sgi_dataP->ipv4_addr_of_router = ip_dst.s_addr;
iov[0].iov_base = &sgi_dataP->eh;
iov[0].iov_len = sizeof(sgi_dataP->eh);
iov[1].iov_base = (void *)buffer;
iov[1].iov_len = sizeof (struct arphdr) + ETH_ALEN*2 + 4*2;
#ifdef VLAN8021Q
sgi_data_p->eh.ether_vlan8021q.vlan_tpid = htons(0x8100);
sgi_dataP->eh.ether_vlan8021q.vlan_tci = htons(0x7000 | 0x0000 | SGI_MIN_EPS_BEARER_ID);
#endif
sgi_dataP->eh.ether_type = htons(ETH_P_ARP);
sgi_print_hex_octets(iov[0].iov_base, iov[0].iov_len);
sgi_print_hex_octets(iov[1].iov_base, iov[1].iov_len);
if (writev(sgi_dataP->sd[0], (const struct iovec *)&iov, 2) < 0) {
SGI_IF_ERROR("Error during send ARP to socket %d bearer id %d : (%s:%d)\n",
sgi_dataP->sd[0],
SGI_MIN_EPS_BEARER_ID,
strerror(errno),
errno);
exit(1);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment