Commit 6c9bc6e1 authored by 's avatar
Browse files

untested version of cooking , it just compiles



git-svn-id: file:///home/svn/mapi/trunk@184 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent a1c557cd
......@@ -6,6 +6,10 @@
#include <pcap.h>
#include <sys/shm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <assert.h>
#include "mapid.h"
#include "mapidflib.h"
......@@ -51,14 +55,304 @@ int status;
int cooked_pkts = 0;
int un_cooked_pkts = 0;
unsigned char *last_dev_pkt;
int callbacks=0;
struct mapidlibflow *cook_tmp_flow;
static int cook_instance(mapidflib_function_instance_t* instance, flist_t *flist, mapidflib_flow_mod_t *flow_mod,function_manipulation_t* manip)
{
flist_node_t *n;
struct mapidlibflow *flow=NULL;
mapidlib_instance_t *i;
i = flow_mod->mi;
n = flist_head(i->flowlist);
while(n)
{
flow = flist_data(n);
if(flow->fd == instance->fd)
{
break;
}
n = flist_next(n);
}
cook_tmp_flow=flow;
return 0;
}
void create_mod_pkt(unsigned char *dev_pkt,struct mapidlibflow *flow,mapid_pkthdr_t *pkt_head) {
ether_header* eth = NULL;
ip_header* ip = NULL;
tcp_header* tcp = NULL;
int ether_len = 0, ip_len = 0, tcp_len = 0;
eth = (ether_header*)dev_pkt;
ether_len = sizeof(ether_header);
ip = (ip_header*)(dev_pkt + ether_len);
ip_len = (ip->ver_ihl & 0xf) * 4;
tcp = (tcp_header*)(dev_pkt + ether_len + ip_len);
tcp_len = tcp->off * 4;
tcp->seq = 0;
ip->tlen = ntohs(client_size + ip_len + tcp_len);
flow->mod_pkt = malloc(sizeof(char) * (client_size + ether_len + ip_len + tcp_len));
if(flow->mod_pkt==NULL) {
//fprintf(stderr,"client size: %d\n",client_size);
assert(flow->mod_pkt!=NULL);
}
memcpy(flow->mod_pkt, eth, ether_len);
memcpy(&flow->mod_pkt[ether_len], ip, ip_len);
memcpy(&flow->mod_pkt[ether_len + ip_len], tcp, tcp_len);
memcpy(&flow->mod_pkt[ether_len + ip_len + tcp_len], ret_client_data, client_size);
//server packet
flow->server_mod_pkt = malloc(sizeof(char) * (server_size + ether_len + ip_len + tcp_len));
if(flow->server_mod_pkt==NULL) {
fprintf(stderr,"client size: %d\n",client_size);
assert(flow->server_mod_pkt!=NULL);
}
memcpy(flow->server_mod_pkt, eth, ether_len);
memcpy(&flow->server_mod_pkt[ether_len], ip, ip_len);
memcpy(&flow->server_mod_pkt[ether_len + ip_len], tcp, tcp_len);
memcpy(&flow->server_mod_pkt[ether_len + ip_len + tcp_len], ret_server_data, server_size);
flow->server_mod_pkt_head.caplen = flow->server_mod_pkt_head.wlen = server_size + ether_len + ip_len + tcp_len;
flow->client_headers = ret_client_headers;
flow->server_headers = ret_server_headers;
pkt_head->caplen = client_size + ether_len + ip_len + tcp_len;
pkt_head->wlen = client_size + ether_len + ip_len + tcp_len;
}
void tcp_callback(struct tcp_stream *ns, void **param)
{
callbacks++;
cooked_pkts++;
if(ns->nids_state == NIDS_JUST_EST)
{
//fprintf(stderr,"JUST_EST\n");
ns->client.collect++;
if(threshold==-1) {
ns->client.reassembled_data = NULL;
ns->client_reassembly_limit=0;
}
else {
ns->client.reassembled_data = (char *)malloc(sizeof(char) * threshold+2000);
}
ns->client.read = 0;
ns->client.total_read = 0;
if(ns->client.headers==NULL) {
fprintf(stderr,"Initing 2..\n");
ns->client.headers = (flist_t *)malloc(sizeof(flist_t));
flist_init(ns->client.headers);
}
ns->client.pkt_count = 0;
// and by a server
ns->server.collect++;
if(threshold==-1) {
ns->server.reassembled_data = NULL;
ns->server_reassembly_limit=0;
}
else {
ns->server.reassembled_data = (char *)malloc(sizeof(char) * threshold+2000);
}
ns->server.read = 0;
ns->server.total_read = 0;
if(ns->server.headers==NULL) {
ns->server.headers = (flist_t *)malloc(sizeof(flist_t));
flist_init(ns->server.headers);
}
ns->server.pkt_count = 0;
ns->flow=NULL;
return;
}
status = CHECKED;
if(ns->nids_state == NIDS_EXITING) {
struct mapidlibflow *flow;
ret_client_data = ns->client.reassembled_data;
ret_server_data = ns->server.reassembled_data;
client_size = ns->client.read;
server_size = ns->server.read;
ret_client_headers = ns->client.headers;
ret_server_headers = ns->server.headers;
flow=(struct mapidlibflow *)(ns->flow);
create_mod_pkt(last_dev_pkt,flow,&flow->mod_pkt_head);
process_flushed_data(flow);
return;
}
if(ns->nids_state == NIDS_CLOSE || ns->nids_state == NIDS_RESET || ns->nids_state == NIDS_TIMED_OUT || ns->nids_state == NIDS_EXITING)
{
//fprintf(stderr,"session closed %d %d - %d\n",ns->nids_state==NIDS_CLOSE,ns->client.total_read,ns->client.count);
if(to_free != NULL) { free(to_free); to_free = NULL; }
if(to_free2 != NULL) { free(to_free2); to_free2 = NULL; }
if(ns->client.total_read < ns->client.count || threshold == -1)
{
if(ret_client_data == NULL)
{
ret_client_data = ns->client.reassembled_data;
ret_server_data = ns->server.reassembled_data;
to_free = ret_client_data;
to_free2 = ret_server_data;
client_size = ns->client.read;
server_size = ns->server.read;
ret_client_headers = ns->client.headers;
ret_server_headers = ns->server.headers;
//fprintf(stderr,"final data: %d %d %d\n",client_size,flist_size(ns->client.headers),ns->nids_state==NIDS_EXITING);
return;
}
}
else if(ns->server.total_read < ns->server.count || threshold ==-1)
{
if(ret_server_data == NULL)
{
ret_server_data = ns->server.reassembled_data;
ret_client_data = ns->client.reassembled_data;
to_free = ret_server_data;
to_free2 = ret_client_data;
server_size = ns->server.read;
client_size = ns->client.read;
//fprintf(stderr,"++final data: %d %d\n",server_size,flist_size(ns->server.headers));
ret_server_headers = ns->server.headers;
ret_client_headers = ns->client.headers;
return;
}
}
return;
}
if(ns->nids_state == NIDS_DATA)
{
if(ns->client.count_new)
{
char *dest = NULL;
ns->client.pkt_count++;
if(threshold == -1 ) {
if((ns->client.read + ns->client.count_new) > ns->client_reassembly_limit) {
ns->client.reassembled_data=(unsigned char *)realloc(ns->client.reassembled_data,ns->client_reassembly_limit+INCR_SIZE);
ns->client_reassembly_limit+=INCR_SIZE;
}
dest = &ns->client.reassembled_data[ns->client.read];
ns->client.total_read = ns->client.count;
ns->client.read += (ns->client.count_new);
memcpy(dest, ns->client.data, ns->client.count_new);
return;
}
if((ns->client.read + ns->client.count_new) > threshold)
{
dest = &ns->client.reassembled_data[ns->client.read];
ret_client_headers = ns->client.headers;
ret_client_data = ns->client.reassembled_data;
client_size = ns->client.read + ns->client.count_new;
ns->client.total_read = ns->client.count;
ns->client.read = 0;
ret_server_headers = ns->server.headers;
ret_server_data = ns->server.reassembled_data;
server_size=ns->server.read;
ns->server.total_read = ns->server.count;
ns->server.read = 0;
memcpy(dest, ns->client.data, ns->client.count_new);
return;
}
else if((ns->client.count - ns->client.count_new) == 0)
{
dest = ns->client.reassembled_data;
}
else
{
dest = &ns->client.reassembled_data[ns->client.read];
}
memcpy(dest, ns->client.data, ns->client.count_new);
ns->client.read += (ns->client.count_new);
}
if(ns->server.count_new)
{
char *dest = NULL;
ns->server.pkt_count++;
if(threshold == -1 ) {
if((ns->server.read + ns->server.count_new) > ns->server_reassembly_limit) {
ns->server.reassembled_data=(unsigned char *)realloc(ns->server.reassembled_data,ns->server_reassembly_limit+INCR_SIZE);
ns->server_reassembly_limit+=INCR_SIZE;
}
dest = &ns->server.reassembled_data[ns->server.read];
ns->server.total_read = ns->server.count;
ns->server.read += (ns->server.count_new);
memcpy(dest, ns->server.data, ns->server.count_new);
return;
}
if((ns->server.read + ns->server.count_new) > threshold)
{
dest = &ns->server.reassembled_data[ns->server.read];
ret_server_headers = ns->server.headers;
ret_server_data = ns->server.reassembled_data;
server_size = ns->server.read + ns->server.count_new;
ret_client_headers = ns->client.headers;
ret_client_data = ns->client.reassembled_data;
client_size = ns->client.read;
ns->client.total_read = ns->client.count;
ns->client.read=0;
ns->server.total_read = ns->server.count;
ns->server.read = 0;
memcpy(dest, ns->server.data, ns->server.count_new);
return;
}
else if((ns->server.count - ns->server.count_new) == 0)
{
dest = ns->server.reassembled_data;
}
else
{
dest = &ns->server.reassembled_data[ns->server.read];
}
memcpy(dest, ns->server.data, ns->server.count_new);
ns->server.read += ns->server.count_new;
}
}
return;
}
static int cook_init(mapidflib_function_instance_t *instance,
......@@ -71,7 +365,8 @@ static int cook_init(mapidflib_function_instance_t *instance,
fargs=instance->args;
data->threshold=getargint(&fargs);
data->timeout=getargint(&fargs);
data->flow=cook_tmp_flow;
desc.fd = 1;
desc.linktype = instance->hwinfo->link_type;
desc.bufsize = instance->hwinfo->cap_length;
......@@ -97,6 +392,140 @@ static int cook_init(mapidflib_function_instance_t *instance,
static int cook_process(mapidflib_function_instance_t *instance,unsigned char* dev_pkt, unsigned char* link_pkt, mapid_pkthdr_t* pkt_head)
{
struct pcap_pkthdr h;
ether_header* eth = NULL;
struct ip *iph;
struct tcphdr *tcph;
int ether_len = 0, ip_len = 0;
struct mapidlibflow *flow;
//fprintf(stderr,"I am COOKING\n");
precooked_data = dev_pkt;
last_dev_pkt= dev_pkt;
last_mapid_header = pkt_head;
h.caplen=pkt_head->caplen;
h.len=pkt_head->wlen;
h.ts.tv_sec=pkt_head->ts; //XXX
h.ts.tv_usec=pkt_head->ts;
struct cooking_data* data = (struct cooking_data*)(instance->internal_data);
threshold = data->threshold;
timeout = data->timeout;
flow=data->flow;
status = NON_CHECKED;
ret_client_data = NULL;
ret_server_data = NULL;
client_size=server_size=0;
callbacks=0;
eth = (ether_header*)dev_pkt;
ether_len = sizeof(ether_header);
iph = (struct ip*)(dev_pkt + ether_len);
ip_len = (iph->ip_hl & 0xf) * 4;
if(iph->ip_p != IPPROTO_TCP) // no TCP packet
return 1;
nids_mapi_next(&h, dev_pkt);
//if(callbacks>1)
//fprintf(stderr,">> %d %d %d\n",callbacks,status,pkt_head->caplen);
if(status == NON_CHECKED)
{
//fprintf(stderr,"\tnon check report\n");
struct tcp_stream *stream;
int from_client;
tcph = (struct tcphdr *)(dev_pkt + ether_len + ip_len);
stream= find_stream(tcph,iph,&from_client);
if(stream) {
//fprintf(stderr,"\tStream found\n");
headers = malloc(sizeof(struct headers_data));
headers->header = malloc(pkt_head->caplen); //added 100 more bytes
memcpy(headers->header,dev_pkt,pkt_head->caplen);
headers->caplen = pkt_head->caplen;
headers->wlen = pkt_head->wlen;
headers->ts.tv_sec = pkt_head->ts; //XXX
headers->ts.tv_usec = pkt_head->ts;
if(from_client==0) {
if(stream->client.headers==NULL) {
stream->client.headers = (flist_t *)malloc(sizeof(flist_t));
flist_init(stream->client.headers);
}
flist_append(stream->client.headers, stream->client.pkt_count, (void *)headers);
}
else {
if(stream->server.headers==NULL) {
stream->server.headers = (flist_t *)malloc(sizeof(flist_t));
flist_init(stream->server.headers);
}
flist_append(stream->server.headers, stream->server.pkt_count, (void *)headers);
}
stream->flow=(void *)flow;
}
else { //unsolicited data
//fprintf(stderr,"Stream not found\n");
return 1;
}
un_cooked_pkts++;
return 0;
}
else {
struct tcp_stream *stream;
int from_client;
//fprintf(stderr,"\tcheck report %d\n",client_size);
tcph = (struct tcphdr *)(dev_pkt + ether_len + ip_len);
headers = malloc(sizeof(struct headers_data));
headers->header = malloc(pkt_head->caplen);
memcpy(headers->header, dev_pkt,pkt_head->caplen);
headers->caplen = pkt_head->caplen;
headers->wlen = pkt_head->wlen;
headers->ts.tv_sec = pkt_head->ts; //XXX
headers->ts.tv_usec = pkt_head->ts;
stream= find_stream(tcph,iph,&from_client);
if(stream==NULL) {
//fprintf(stderr,"\tNULL stream %d %d\n",headers->ts.tv_sec,headers->ts.tv_usec);
create_mod_pkt(dev_pkt,flow,pkt_head);
flist_append(flow->server_headers,0, (void *)headers);
return 1;
}
stream->flow=(void *)flow;
if(from_client==0) {
if(stream->client.headers==NULL) {
stream->client.headers = (flist_t *)malloc(sizeof(flist_t));
flist_init(stream->client.headers);
}
flist_append(stream->client.headers, stream->client.pkt_count, (void *)headers);
}
else {
if(stream->server.headers==NULL) {
stream->server.headers = (flist_t *)malloc(sizeof(flist_t));
flist_init(stream->server.headers);
}
flist_append(stream->server.headers, stream->server.pkt_count, (void *)headers);
}
}
if(ret_client_data != NULL || ret_server_data!=NULL)
{
// Set pseudoheader and new cooked packet to return to the daemon
create_mod_pkt(dev_pkt,flow,pkt_head);
return 1;
}
return 0;
}
......
......@@ -10,7 +10,16 @@ struct cooking_data
{
int threshold;
int timeout;
void* sessions;
struct mapidlibflow *flow;
};
struct headers_data {
unsigned char *header;
int header_len;
unsigned int caplen;
unsigned int wlen;
struct timeval ts;
void *decoded_pkt;
};
/////////////////////////////////////////////////////////////////////
......
Supports Markdown
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