Commit 97f33932 authored by 's avatar
Browse files

cooking can now be applied to up to 65536 flows



git-svn-id: file:///home/svn/mapi/trunk@205 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent c2aea105
......@@ -373,7 +373,7 @@ static int cook_init(mapidflib_function_instance_t *instance,
desc.linktype = instance->hwinfo->link_type;
desc.bufsize = instance->hwinfo->cap_length;
nids_mapi_init(&desc, instance->hwinfo->link_type);
nids_mapi_init(&desc, instance->hwinfo->link_type,0);
nids_register_tcp(tcp_callback);
......@@ -433,7 +433,7 @@ static int cook_process(mapidflib_function_instance_t *instance,const unsigned c
if(iph->ip_p != IPPROTO_TCP) // no TCP packet
return 1;
nids_mapi_next(&h, link_pkt);
nids_mapi_next(&h, link_pkt,0);
//if(callbacks>1)
//fprintf(stderr,">> %d %d %d\n",callbacks,status,pkt_head->caplen);
......@@ -445,7 +445,8 @@ static int cook_process(mapidflib_function_instance_t *instance,const unsigned c
tcph = (struct tcphdr *)(link_pkt + ether_len + ip_len);
stream= find_stream(tcph,iph,&from_client);
//XXX replace 0
stream= find_stream(tcph,iph,&from_client,0);
if(stream) {
//fprintf(stderr,"\tStream found\n");
headers = malloc(sizeof(struct headers_data));
......@@ -493,8 +494,9 @@ static int cook_process(mapidflib_function_instance_t *instance,const unsigned c
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);
//XXX replace 0
stream= find_stream(tcph,iph,&from_client,0);
if(stream==NULL) {
//fprintf(stderr,"\tNULL stream %d %d\n",headers->ts.tv_sec,headers->ts.tv_usec);
create_mod_pkt(link_pkt,flow,pkt_head);
......
No preview for this file type
......@@ -38,14 +38,15 @@ extern int raw_init();
static void nids_syslog(int, int, struct ip *, void *);
static int nids_ip_filter(struct ip *, int);
static struct proc_node *ip_frag_procs;
static struct proc_node *ip_procs;
static struct proc_node *udp_procs;
static struct proc_node *ip_frag_procs[MAX_LIBNIDS_INSTANCES];
static struct proc_node *ip_procs[MAX_LIBNIDS_INSTANCES];
static struct proc_node *udp_procs[MAX_LIBNIDS_INSTANCES];
struct proc_node *tcp_procs;
static unsigned int linkoffset = 0;
static int linktype;
static pcap_t *desc = 0;
struct proc_node *tcp_procs[MAX_LIBNIDS_INSTANCES];
static unsigned int linkoffset[MAX_LIBNIDS_INSTANCES];
static int linktype[MAX_LIBNIDS_INSTANCES];
static pcap_t *desc[MAX_LIBNIDS_INSTANCES];
char nids_errbuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr * nids_last_pcap_header = NULL;
......@@ -182,23 +183,29 @@ static void pcap_hand(u_char * par, struct pcap_pkthdr *hdr, u_char * data)
{
struct proc_node *i;
u_char *data_aligned;
int id=0;
if(par) {
id=*((unsigned int *)par);
}
#ifdef DLT_IEEE802_11
unsigned short fc;
int linkoffset_tweaked_by_prism_code = 0;
#endif
nids_last_pcap_header = hdr;
(void)par; /* warnings... */
switch (linktype) {
switch (linktype[id]) {
case DLT_EN10MB:
if (hdr->caplen < 14)
return;
/* Only handle IP packets and 802.1Q VLAN tagged packets below. */
if (data[12] == 8 && data[13] == 0) {
/* Regular ethernet */
linkoffset = 14;
linkoffset[id] = 14;
} else if (data[12] == 0x81 && data[13] == 0) {
/* Skip 802.1Q VLAN and priority information */
linkoffset = 18;
linkoffset[id] = 18;
} else
/* non-ip frame */
return;
......@@ -208,7 +215,7 @@ static void pcap_hand(u_char * par, struct pcap_pkthdr *hdr, u_char * data)
#error DLT_PRISM_HEADER is defined, but DLT_IEEE802_11 is not ???
#endif
case DLT_PRISM_HEADER:
linkoffset = 144; //sizeof(prism2_hdr);
linkoffset[id] = 144; //sizeof(prism2_hdr);
linkoffset_tweaked_by_prism_code = 1;
//now let DLT_IEEE802_11 do the rest
#endif
......@@ -218,8 +225,8 @@ static void pcap_hand(u_char * par, struct pcap_pkthdr *hdr, u_char * data)
* works for tcpdump, so who am I to complain? (wam)
*/
if (!linkoffset_tweaked_by_prism_code)
linkoffset = 0;
fc = EXTRACT_LE_16BITS(data + linkoffset);
linkoffset[id] = 0;
fc = EXTRACT_LE_16BITS(data + linkoffset[id]);
if (FC_TYPE(fc) != T_DATA || FC_WEP(fc)) {
return;
}
......@@ -227,26 +234,26 @@ static void pcap_hand(u_char * par, struct pcap_pkthdr *hdr, u_char * data)
/* a wireless distribution system packet will have another
* MAC addr in the frame
*/
linkoffset += 30;
linkoffset[id] += 30;
} else {
linkoffset += 24;
linkoffset[id] += 24;
}
if (hdr->len < linkoffset + LLC_FRAME_SIZE)
if (hdr->len < linkoffset[id] + LLC_FRAME_SIZE)
return;
if (ETHERTYPE_IP !=
EXTRACT_16BITS(data + linkoffset + LLC_OFFSET_TO_TYPE_FIELD)) {
EXTRACT_16BITS(data + linkoffset[id] + LLC_OFFSET_TO_TYPE_FIELD)) {
/* EAP, LEAP, and other 802.11 enhancements can be
* encapsulated within a data packet too. Look only at
* encapsulated IP packets (Type field of the LLC frame).
*/
return;
}
linkoffset += LLC_FRAME_SIZE;
linkoffset[id] += LLC_FRAME_SIZE;
break;
#endif
default:;
}
if (hdr->caplen < linkoffset)
if (hdr->caplen < linkoffset[id])
return;
/*
......@@ -255,19 +262,19 @@ static void pcap_hand(u_char * par, struct pcap_pkthdr *hdr, u_char * data)
* handle->offset in pcap sources), so memcpy should not be called.
*/
#ifdef LBL_ALIGN
if ((unsigned long) (data + linkoffset) & 0x3) {
data_aligned = alloca(hdr->caplen - linkoffset + 4);
if ((unsigned long) (data + linkoffset[id]) & 0x3) {
data_aligned = alloca(hdr->caplen - linkoffset[id] + 4);
data_aligned -= (unsigned long) data_aligned % 4;
memcpy(data_aligned, data + linkoffset, hdr->caplen - linkoffset);
memcpy(data_aligned, data + linkoffset[id], hdr->caplen - linkoffset[id]);
} else
#endif
data_aligned = data + linkoffset;
for (i = ip_frag_procs; i; i = i->next) {
(i->item) (data_aligned, hdr->caplen - linkoffset);
data_aligned = data + linkoffset[id];
for (i = ip_frag_procs[id]; i; i = i->next) {
(i->item) (data_aligned, hdr->caplen - linkoffset[id],id);
}
}
static void gen_ip_frag_proc(u_char * data, int len)
static void gen_ip_frag_proc(u_char * data, int len,int id)
{
struct proc_node *i;
struct ip *iph = (struct ip *) data;
......@@ -305,11 +312,11 @@ static void gen_ip_frag_proc(u_char * data, int len)
skblen = (skblen + 15) & ~15;
skblen += nids_params.sk_buff_size;
for (i = ip_procs; i; i = i->next) {
(i->item) (iph, skblen);
for (i = ip_procs[id]; i; i = i->next) {
(i->item) (iph, skblen,id);
}
if (need_free)
free(iph);
free(iph);
}
#if HAVE_BSD_UDPHDR
......@@ -322,9 +329,9 @@ static void gen_ip_frag_proc(u_char * data, int len)
#define UH_DPORT dest
#endif
static void process_udp(char *data)
static void process_udp(char *data,int id)
{
struct proc_node *ipp = udp_procs;
struct proc_node *ipp = udp_procs[id];
struct ip *iph = (struct ip *) data;
struct udphdr *udph;
struct tuple4 addr;
......@@ -350,62 +357,73 @@ static void process_udp(char *data)
ipp = ipp->next;
}
}
int mycnt=0;
static void gen_ip_proc(u_char * data, int skblen)
static void gen_ip_proc(u_char * data, int skblen,int id)
{
switch (((struct ip *) data)->ip_p) {
case IPPROTO_TCP:
process_tcp(data, skblen);
process_tcp(data, skblen,id);
break;
case IPPROTO_UDP:
process_udp(data);
process_udp(data,id);
break;
case IPPROTO_ICMP:
if (nids_params.n_tcp_streams)
process_icmp(data);
process_icmp(data,id);
break;
default:
//printf("other!\n");
break;
}
}
static void init_procs()
static void init_procs(int id)
{
ip_frag_procs = mknew(struct proc_node);
ip_frag_procs->item = gen_ip_frag_proc;
ip_frag_procs->next = 0;
ip_procs = mknew(struct proc_node);
ip_procs->item = gen_ip_proc;
ip_procs->next = 0;
tcp_procs = 0;
udp_procs = 0;
ip_frag_procs[id] = mknew(struct proc_node);
ip_frag_procs[id]->item = gen_ip_frag_proc;
ip_frag_procs[id]->next = 0;
ip_procs[id] = mknew(struct proc_node);
ip_procs[id]->item = gen_ip_proc;
ip_procs[id]->next = 0;
tcp_procs[id] = 0;
udp_procs[id] = 0;
}
void nids_register_udp(void (*x))
void nids_register_udp(void (*x)) {
nids_mapi_register_udp(x,0);
}
void nids_mapi_register_udp(void (*x),int id)
{
struct proc_node *ipp = mknew(struct proc_node);
ipp->item = x;
ipp->next = udp_procs;
udp_procs = ipp;
ipp->next = udp_procs[id];
udp_procs[id] = ipp;
}
void nids_register_ip(void (*x)) {
nids_mapi_register_ip(x,0);
}
void nids_register_ip(void (*x))
void nids_mapi_register_ip(void (*x),int id)
{
struct proc_node *ipp = mknew(struct proc_node);
ipp->item = x;
ipp->next = ip_procs;
ip_procs = ipp;
ipp->next = ip_procs[id];
ip_procs[id] = ipp;
}
void nids_register_ip_frag(void (*x))
void nids_register_ip_frag(void (*x),int id)
{
struct proc_node *ipp = mknew(struct proc_node);
ipp->item = x;
ipp->next = ip_frag_procs;
ip_frag_procs = ipp;
ipp->next = ip_frag_procs[id];
ip_frag_procs[id] = ipp;
}
static int open_live()
{
......@@ -423,7 +441,7 @@ static int open_live()
else
promisc = (nids_params.promisc != 0);
if ((desc = pcap_open_live(device, 16384, promisc,
if ((desc[0] = pcap_open_live(device, 16384, promisc,
nids_params.pcap_timeout, nids_errbuf)) == NULL)
return 0;
#ifdef __linux__
......@@ -442,35 +460,12 @@ static int open_live()
return 1;
}
// nids to nids_mapi
// wnat pcap_datalink(desc)
int nids_mapi_init(pcap_t *d,int ltype)
int nids_mapi_init(pcap_t *d,int ltype,int id)
{
//printf("in nids_mapi_init\n");
/*
if (nids_params.filename) {
if ((desc = pcap_open_offline(nids_params.filename,
nids_errbuf)) == NULL)
return 0;
} else if (!open_live())
return 0;
*/
/*if (nids_params.pcap_filter != NULL) {
u_int mask = 0;
struct bpf_program fcode;
if (pcap_compile(desc, &fcode, nids_params.pcap_filter, 1, mask) <
0) return 0;
if (pcap_setfilter(desc, &fcode) == -1)
return 0;
}
*/
desc = d;
linktype=ltype;
desc[id] = d;
linktype[id]=ltype;
switch (linktype) {
switch (linktype[id]) {
#ifdef DLT_IEEE802_11
#ifdef DLT_PRISM_HEADER
case DLT_PRISM_HEADER:
......@@ -481,36 +476,36 @@ int nids_mapi_init(pcap_t *d,int ltype)
#endif
#ifdef DLT_NULL
case DLT_NULL:
linkoffset = 4;
linkoffset[id] = 4;
break;
#endif
case DLT_EN10MB:
linkoffset = 14;
linkoffset[id] = 14;
break;
case DLT_PPP:
linkoffset = 4;
linkoffset[id] = 4;
break;
/* Token Ring Support by vacuum@technotronic.com, thanks dugsong! */
case DLT_IEEE802:
linkoffset = 22;
linkoffset[id] = 22;
break;
case DLT_RAW:
case DLT_SLIP:
linkoffset = 0;
linkoffset[id] = 0;
break;
#define DLT_LINUX_SLL 113
case DLT_LINUX_SLL:
linkoffset = 16;
linkoffset[id] = 16;
break;
#ifdef DLT_FDDI
case DLT_FDDI:
linkoffset = 21;
linkoffset[id] = 21;
break;
#endif
#ifdef DLT_PPP_SERIAL
case DLT_PPP_SERIAL:
linkoffset = 4;
linkoffset[id] = 4;
break;
#endif
default:
......@@ -519,7 +514,7 @@ int nids_mapi_init(pcap_t *d,int ltype)
return 0;
}
if (nids_params.dev_addon == -1) {
if (linktype == DLT_EN10MB)
if (linktype[id] == DLT_EN10MB)
nids_params.dev_addon = 16;
else
nids_params.dev_addon = 0;
......@@ -527,8 +522,8 @@ int nids_mapi_init(pcap_t *d,int ltype)
if (nids_params.syslog == nids_syslog)
openlog("libnids", 0, LOG_LOCAL0);
init_procs();
tcp_init(nids_params.n_tcp_streams);
init_procs(id);
tcp_init(nids_params.n_tcp_streams,id);
ip_frag_init(nids_params.n_hosts);
scan_init();
return 1;
......@@ -539,7 +534,7 @@ int nids_mapi_init(pcap_t *d,int ltype)
int nids_init()
{
if (nids_params.filename) {
if ((desc = pcap_open_offline(nids_params.filename,
if ((desc[0] = pcap_open_offline(nids_params.filename,
nids_errbuf)) == NULL)
return 0;
} else if (!open_live())
......@@ -549,12 +544,12 @@ int nids_init()
u_int mask = 0;
struct bpf_program fcode;
if (pcap_compile(desc, &fcode, nids_params.pcap_filter, 1, mask) <
if (pcap_compile(desc[0], &fcode, nids_params.pcap_filter, 1, mask) <
0) return 0;
if (pcap_setfilter(desc, &fcode) == -1)
if (pcap_setfilter(desc[0], &fcode) == -1)
return 0;
}
switch ((linktype = pcap_datalink(desc))) {
switch ((linktype[0] = pcap_datalink(desc[0]))) {
#ifdef DLT_IEEE802_11
#ifdef DLT_PRISM_HEADER
case DLT_PRISM_HEADER:
......@@ -565,36 +560,36 @@ int nids_init()
#endif
#ifdef DLT_NULL
case DLT_NULL:
linkoffset = 4;
linkoffset[0] = 4;
break;
#endif
case DLT_EN10MB:
linkoffset = 14;
linkoffset[0] = 14;
break;
case DLT_PPP:
linkoffset = 4;
linkoffset[0] = 4;
break;
/* Token Ring Support by vacuum@technotronic.com, thanks dugsong! */
case DLT_IEEE802:
linkoffset = 22;
linkoffset[0] = 22;
break;
case DLT_RAW:
case DLT_SLIP:
linkoffset = 0;
linkoffset[0] = 0;
break;
#define DLT_LINUX_SLL 113
case DLT_LINUX_SLL:
linkoffset = 16;
linkoffset[0] = 16;
break;
#ifdef DLT_FDDI
case DLT_FDDI:
linkoffset = 21;
linkoffset[0] = 21;
break;
#endif
#ifdef DLT_PPP_SERIAL
case DLT_PPP_SERIAL:
linkoffset = 4;
linkoffset[0] = 4;
break;
#endif
default:
......@@ -610,8 +605,8 @@ int nids_init()
if (nids_params.syslog == nids_syslog)
openlog("libnids", 0, LOG_LOCAL0);
init_procs();
tcp_init(nids_params.n_tcp_streams);
init_procs(0);
tcp_init(nids_params.n_tcp_streams,0);
ip_frag_init(nids_params.n_hosts);
scan_init();
return 1;
......@@ -619,46 +614,47 @@ int nids_init()
void nids_run()
{
if (!desc) {
if (!desc[0]) {
strcpy(nids_errbuf, "Libnids not initialized");
return;
}
pcap_loop(desc, -1, (pcap_handler) pcap_hand, 0);
clear_stream_buffers();
pcap_loop(desc[0], -1, (pcap_handler) pcap_hand, 0);
clear_stream_buffers(0);
strcpy(nids_errbuf, "loop: ");
strncat(nids_errbuf, pcap_geterr(desc), sizeof(nids_errbuf) - 7);
pcap_close(desc);
strncat(nids_errbuf, pcap_geterr(desc[0]), sizeof(nids_errbuf) - 7);
pcap_close(desc[0]);
}
int nids_getfd()
{
if (!desc) {
if (!desc[0]) {
strcpy(nids_errbuf, "Libnids not initialized");
return -1;
}
return pcap_fileno(desc);
return pcap_fileno(desc[0]);
}
// nids to nids_mapi
int nids_mapi_next(struct pcap_pkthdr *h, unsigned char* data)
int nids_mapi_next(struct pcap_pkthdr *h, unsigned char* data,int id)
{
//printf("in nids_mapi_next1\n");
int mid=id;
if(!desc){
if(!desc[id]){
strcpy(nids_errbuf, "Libnids not initialized");
return 0;
}
if(!data){
strcpy(nids_errbuf, "next: ");
strncat(nids_errbuf, desc , sizeof(nids_errbuf) - 7);
strncat(nids_errbuf, desc[id] , sizeof(nids_errbuf) - 7);
return 0;
}
// printf("in nids_mapi_next2\n");
pcap_hand(0, h, data);
pcap_hand((unsigned char *)(&mid), h, data);
return 1;
}
......@@ -669,13 +665,13 @@ int nids_next()
struct pcap_pkthdr h;
char *data;
if (!desc) {
if (!desc[0]) {
strcpy(nids_errbuf, "Libnids not initialized");
return 0;
}
if (!(data = (char *) pcap_next(desc, &h))) {
if (!(data = (char *) pcap_next(desc[0], &h))) {
strcpy(nids_errbuf, "next: ");
strncat(nids_errbuf, pcap_geterr(desc), sizeof(nids_errbuf) - 7);
strncat(nids_errbuf, pcap_geterr(desc[0]), sizeof(nids_errbuf) - 7);
return 0;
}
pcap_hand(0, &h, data);
......
......@@ -127,20 +127,27 @@ struct nids_prm
};
int nids_init ();
int nids_mapi_init(pcap_t *,int linktype);
void nids_register_ip_frag (void (*));
int nids_mapi_init(pcap_t *,int linktype,int id);
void nids_register_ip_frag (void (*),int id);
void nids_mapi_register_ip (void (*),int id);
void nids_register_ip (void (*));
void nids_mapi_register_tcp (void (*),int id);
void nids_register_tcp (void (*));
void nids_mapi_register_udp (void (*),int id);
void nids_register_udp (void (*));
void nids_killtcp (struct tcp_stream *);
void nids_discard (struct tcp_stream *, int);
void nids_run ();
int nids_getfd ();
int nids_mapi_next();
int nids_mapi_next(struct pcap_pkthdr *h, unsigned char* data,int id);
int nids_next ();
extern struct nids_prm nids_params;
extern char *nids_warnings[];
extern char nids_errbuf[];
extern struct pcap_pkthdr *last_pcap_header;
#define MAX_LIBNIDS_INSTANCES 65536
#endif /* _NIDS_NIDS_H */
......@@ -47,15 +47,15 @@ enum {
#define EXP_SEQ (snd->first_data_seq + rcv->count + rcv->urg_count)
extern struct proc_node *tcp_procs;
extern struct proc_node *tcp_procs[MAX_LIBNIDS_INSTANCES];
static struct tcp_stream **tcp_stream_table;
static struct tcp_stream *streams_pool;
static struct tcp_stream **tcp_stream_table[MAX_LIBNIDS_INSTANCES];
static struct tcp_stream *streams_pool[MAX_LIBNIDS_INSTANCES];
static int tcp_num = 0;
static int tcp_stream_table_size;
static int max_stream;
static struct tcp_stream *tcp_latest = 0, *tcp_oldest = 0;
static struct tcp_stream *free_streams;
static struct tcp_stream *tcp_latest[MAX_LIBNIDS_INSTANCES], *tcp_oldest[MAX_LIBNIDS_INSTANCES];
static struct tcp_stream *free_streams[MAX_LIBNIDS_INSTANCES];
static struct ip *ugly_iphdr;
static void purge_queue(struct half_stream * h)
......@@ -73,7 +73,7 @@ static void purge_queue(struct half_stream * h)
}
static void