Commit 64a9beac authored by 's avatar
Browse files

Added support for PoS protocol.

shm_flows fixed


git-svn-id: file:///home/svn/mapi/trunk@1411 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent cc1723c2
......@@ -6,6 +6,7 @@
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <pcap.h>
#include <netinet/in.h>
#include "mapidflib.h"
......@@ -16,14 +17,13 @@
#include "debug.h"
#include "expiredflowshash.h"
#define EXPIRED_FLOWS "EXPIRED_FLOWS"
#define SEND_SIZE 64 //Number of expired flows send per mapi_read_results.
#define TIMEOUT 30 //in epochs
#define EPOCHDURATION 1
#define EXPIRED_FLOWS "EXPIRED_FLOWS"
#define TIMEOUT 30 //in epochs
#define EPOCHDURATION 1
#define ETHERTYPE_8021Q 0x8100
#define MPLS_MASK 0x8847
#define ETHERTYPE_IP 0x0800 /* IP protocol */
#define ETHERTYPE_IP 0x0800 /* IP protocol */
struct vlan_802q_header {
......@@ -66,11 +66,11 @@ void add_toflow(struct exfl_data *data, eflow_data record, flows_stat *stats) {
struct exfl_hash_node *lookup;
unsigned int value = hash_function(record);
pthread_mutex_lock( &(data->mutex) );
pthread_mutex_lock( &(data->mutex) );
lookup = exfl_hash_lookup(value, data, record);
if(lookup == NULL) {
pthread_mutex_unlock( &(data->mutex) );
exfl_add_to_hashtable_and_list(data, value, record);
......@@ -92,7 +92,7 @@ void shift_node(struct exfl_data *data, struct exfl_list_node *node) {
if( data->list_head == node)
return;
else {
previous = node->previous;
// remove node from list
previous->next = node->next;
......@@ -107,7 +107,7 @@ void shift_node(struct exfl_data *data, struct exfl_list_node *node) {
node->next = data->list_head;
node->previous = NULL;
data->list_head = node;
}
}
......@@ -116,12 +116,12 @@ void exfl_add_to_hashtable_and_list(struct exfl_data *data, unsigned int value,
struct exfl_list_node *newlistnode;
struct exfl_hash_node *newhashnode;
unsigned int pos;
// Create a new list node
// Create a new list node
if( (newlistnode = (struct exfl_list_node *)malloc(sizeof(struct exfl_list_node))) == NULL) {
DEBUG_CMD(Debug_Message("Malloc failed for size %d", sizeof(struct exfl_list_node)));
return;
}
}
newlistnode->value = value;
newlistnode->flow = record;
newlistnode->flow.packets_count = 1;
......@@ -130,7 +130,7 @@ void exfl_add_to_hashtable_and_list(struct exfl_data *data, unsigned int value,
// Create a new hash node
pos = value%EXFL_HASH_SIZE;
if( (newhashnode = (struct exfl_hash_node *)malloc(sizeof(struct exfl_hash_node))) == NULL) {
DEBUG_CMD(Debug_Message("Malloc failed for size %d", sizeof(struct exfl_hash_node)));
DEBUG_CMD(Debug_Message("Malloc failed for size %d", sizeof(struct exfl_hash_node)));
return;
}
......@@ -141,7 +141,7 @@ void exfl_add_to_hashtable_and_list(struct exfl_data *data, unsigned int value,
//add to list
pthread_mutex_lock( &(data->mutex) );
data->list_size++;
if(data->list_tail == NULL) {
data->list_head = data->list_tail = newlistnode;
......@@ -151,12 +151,12 @@ void exfl_add_to_hashtable_and_list(struct exfl_data *data, unsigned int value,
newlistnode->next = data->list_head;
data->list_head = newlistnode;
}
//add to hashtable
if(data->hashtable[pos] != NULL)
data->hashtable[pos]->prev = newhashnode;
data->hashtable[pos] = newhashnode;
pthread_mutex_unlock( &(data->mutex) );
}
......@@ -174,11 +174,11 @@ struct exfl_hash_node *exfl_hash_lookup(unsigned int value, struct exfl_data *da
pos = value%EXFL_HASH_SIZE;
tmp = data->hashtable[pos];
eflow_data *hashflow;
while(tmp) {
if(tmp->value == value){
hashflow = &(tmp->node->flow);
if(record.ptcl == hashflow->ptcl ){
if(record.ptcl == hashflow->ptcl ){
if(compare_ip(record.saddr, hashflow->saddr) && compare_ip(record.daddr, hashflow->daddr)) {
if((record.sport == hashflow->sport) && (record.dport == hashflow->dport)) return tmp;
}
......@@ -192,7 +192,7 @@ struct exfl_hash_node *exfl_hash_lookup(unsigned int value, struct exfl_data *da
int checkhash(struct exfl_hash_node **hashtable) {
int i, count = 0;
struct exfl_hash_node *tmp;
for(i = 0; i < EXFL_HASH_SIZE; i++) {
if(hashtable[i] != NULL) {
tmp = hashtable[i];
......@@ -250,11 +250,10 @@ void poll_expired_flows(mapidflib_function_instance_t *instance) {
shm_struct.size = (unsigned int *)instance->result.data;
shm_struct.Table = (flow_data *)((char *)instance->result.data+sizeof(flows_stat));
shm_struct.smmutex = (pthread_mutex_t *)(((char *)instance->result.data) + sizeof(flows_stat) + sizeof(struct flow_data)*data->shm_flows);
*(shm_struct.size) = 0;
while(data->run) {
pthread_testcancel();
pthread_mutex_lock( mutex );
pthread_mutex_lock( mutex );
tmp = data->list_tail;
check_expired_flows(data, shm_struct);
if(tmp) { //if list is not empty
......@@ -286,7 +285,7 @@ void poll_expired_flows(mapidflib_function_instance_t *instance) {
}
free(lookup_hash);
}
else {
else {
DEBUG_CMD(Debug_Message("hash node not found but list node exist!"));
}
......@@ -378,7 +377,7 @@ static int exprflow_instance(mapidflib_function_instance_t *instance,
MAPI_UNUSED int fd,
MAPI_UNUSED mapidflib_flow_mod_t *flow_mod) {
mapiFunctArg* fargs;
int shm_flows; // max: (DIMAPI_DATA_SIZE - sizeof(flows_stat) - cca24) / sizeof(struct flow_data))
int shm_flows; // max: (DIMAPI_DATA_SIZE - sizeof(flows_stat) - sizeof(mapi_results_t)) / sizeof(struct flow_data))
fargs = instance->args;
shm_flows = getargint(&fargs);
......@@ -390,8 +389,8 @@ static int exprflow_instance(mapidflib_function_instance_t *instance,
static int exprflow_init(mapidflib_function_instance_t *instance, MAPI_UNUSED int fd)
{
int mythread;
int mythread;
pthread_mutex_t tmpmutex = PTHREAD_MUTEX_INITIALIZER;
shm shm_struct;
struct exfl_data *data;
......@@ -419,7 +418,7 @@ static int exprflow_init(mapidflib_function_instance_t *instance, MAPI_UNUSED in
data->epoch=0;
// function arguments
data->shm_flows = getargint(&fargs); // max: (DIMAPI_DATA_SIZE - sizeof(flows_stat) - cca24) / sizeof(struct flow_data))
data->shm_flows = getargint(&fargs); // max: (DIMAPI_DATA_SIZE - sizeof(flows_stat) - sizeof(mapi_results_t)) / sizeof(struct flow_data))
data->expired_flows_list_size_max = getargint(&fargs);
data->packets_count_min = getargint(&fargs);
......@@ -455,7 +454,13 @@ static int exprflow_process(mapidflib_function_instance_t *instance, MAPI_UNUSED
unsigned char *p = NULL;
uint16_t ethertype;
struct ether_header *ep = NULL;
int ether_len =0 , ip_len = 0;
struct hdlc_header {
uint8_t addr; // 0x0F for unicast, 0x8F for broadcast
uint8_t ctrl; // 0x00
uint16_t proto; // http://www.nethelp.no/net/cisco-hdlc.txt
} *hp = NULL;
//int ether_len = 0;
int ip_len = 0;
unsigned int len = pkt_head->caplen;
int headerlenoverplus = 0;
......@@ -464,32 +469,52 @@ static int exprflow_process(mapidflib_function_instance_t *instance, MAPI_UNUSED
struct vlan_802q_header *vlan_header;
p = link_pkt;
// lay the Ethernet header struct over the packet data
ep = (struct ether_header *)p;
ether_len = sizeof(struct ether_header);
switch(instance->hwinfo->link_type) {
case DLT_EN10MB:
// lay the Ethernet header struct over the packet data
ep = (struct ether_header *)p;
//ether_len = sizeof(struct ether_header);
// skip ethernet header
p += sizeof(struct ether_header);
len -= sizeof(struct ether_header);
// skip ethernet header
p += sizeof(struct ether_header);
len -= sizeof(struct ether_header);
ethertype = ntohs(ep->ether_type);
ethertype = ntohs(ep->ether_type);
if(ethertype == ETHERTYPE_8021Q) {
vlan_header = (struct vlan_802q_header*)p;
ethertype = ntohs(vlan_header->ether_type);
p += sizeof(struct vlan_802q_header);
headerlenoverplus = sizeof(struct vlan_802q_header);
}
if(ethertype == ETHERTYPE_8021Q) {
vlan_header = (struct vlan_802q_header*)p;
ethertype = ntohs(vlan_header->ether_type);
p += sizeof(struct vlan_802q_header);
headerlenoverplus = sizeof(struct vlan_802q_header);
}
if(ethertype == MPLS_MASK) {
p += 4;
headerlenoverplus = 4;
}
else if(ethertype != ETHERTYPE_IP) {
DEBUG_CMD(Debug_Message("not an ip packet?"));
return 0;
}
break;
case DLT_CHDLC:
hp = (struct hdlc_header *)p;
if(ethertype == MPLS_MASK) {
p += 4;
headerlenoverplus = 4;
}
else if(ethertype != ETHERTYPE_IP) {
DEBUG_CMD(Debug_Message("not an ip packet?"));
return 1;
p += sizeof(struct hdlc_header);
len -= sizeof(struct hdlc_header);
ethertype = ntohs(hp->ctrl);
if (ethertype != ETHERTYPE_IP) {
return 0;
}
break;
default:
//DEBUG_CMD(Debug_Message("Link layer not supported"));
return 0;
}
// IP header struct over the packet data;
ip =(ip_header*)p;
ip_len = (ip->ver_ihl & 0xf) * 4;
......@@ -600,13 +625,13 @@ void print_flow(eflow_data *data) {
fprintf(stdout, "dst %d.%d.%d.%d:%d\t", data->daddr.byte1, data->daddr.byte2, data->daddr.byte3, data->daddr.byte4, data->dport);
fprintf(stdout, "packets: %lld, bytes: %lld\n", data->packets_count, data->bytes_count);
}
static int exprflow_client_read_result(mapidflib_function_instance_t *instance,mapi_result_t *res) {
shm shm_struct;
flows_stat *stats;
mapiFunctArg* fargs;
int shm_flows; // max: (DIMAPI_DATA_SIZE - sizeof(flows_stat) - cca24) / sizeof(struct flow_data))
int shm_flows; // max: (DIMAPI_DATA_SIZE - sizeof(flows_stat) - sizeof(mapi_results_t)) / sizeof(struct flow_data))
fargs = instance->args;
shm_flows = getargint(&fargs);
......@@ -634,13 +659,13 @@ static int exprflow_client_read_result(mapidflib_function_instance_t *instance,m
static int exprflow_client_init( mapidflib_function_instance_t *instance, void *data) {
mapiFunctArg* fargs;
int shm_flows; // max: (DIMAPI_DATA_SIZE - sizeof(flows_stat) - cca24) / sizeof(struct flow_data))
int shm_flows; // max: (DIMAPI_DATA_SIZE - sizeof(flows_stat) - sizeof(mapi_results_t)) / sizeof(struct flow_data))
fargs = instance->args;
shm_flows = getargint(&fargs);
if(shm_flows > (DIMAPI_DATA_SIZE - sizeof(flows_stat) - 24) / sizeof(struct flow_data)) {
printf("Cannot process %d flows. Maximum is %d.\n", shm_flows, (DIMAPI_DATA_SIZE - sizeof(flows_stat) - 24) / sizeof(struct flow_data));
if(shm_flows > (DIMAPI_DATA_SIZE - sizeof(flows_stat) - sizeof(mapi_results_t)) / sizeof(struct flow_data)) {
printf("Cannot process %d flows. Maximum is %d.\n", shm_flows, (DIMAPI_DATA_SIZE - sizeof(flows_stat) - sizeof(mapi_results_t)) / sizeof(struct flow_data));
return(-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