Large update: pcap support, threading fixes, initial stream tracking, time handling, pool support, runmodes, decoders added, autojunk update.

remotes/origin/master-1.0.x
Victor Julien 16 years ago
parent a0b390c541
commit 9c7f5afa79

@ -40,6 +40,10 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE

@ -136,6 +136,10 @@ AC_CHECK_LIB(net, libnet_build_icmpv6_unreach,, LLIBNET="no")
CFLAGS="$CFLAGS -DHAVE_LIBNET_ICMPV6_UNREACH"
fi
# libpcap
CFLAGS="${CFLAGS} `pcap-config --defines` `pcap-config --cflags`"
LIBS="${LIBS} -lpcap"
AC_SUBST(CFLAGS)
AC_SUBST(LDFLAGS)
AC_SUBST(CPPFLAGS)

12987
ltmain.sh

File diff suppressed because it is too large Load Diff

@ -4,7 +4,11 @@ config.c config.h \
packet-queue.c packet-queue.h \
threads.c threads.h \
source-nfq.c source-nfq.h \
source-pcap.c source-pcap.h \
source-pcap-file.c source-pcap-file.h \
decode.c decode.h \
decode-ethernet.c decode-ethernet.h \
decode-sll.c decode-sll.h \
decode-ipv4.c decode-ipv4.h \
decode-ipv6.c decode-ipv6.h \
decode-icmpv4.c decode-icmpv4.h \
@ -67,6 +71,8 @@ util-hash.c util-hash.h \
util-hashlist.c util-hashlist.h \
util-bloomfilter.c util-bloomfilter.h \
util-bloomfilter-counting.c util-bloomfilter-counting.h \
util-pool.c util-pool.h \
util-time.c util-time.h \
util-var.c util-var.h \
util-var-name.c util-var-name.h \
tm-modules.c tm-modules.h \
@ -81,6 +87,7 @@ alert-debuglog.c alert-debuglog.h \
log-httplog.c log-httplog.h \
alert-unified-log.c alert-unified-log.h \
alert-unified-alert.c alert-unified-alert.h \
stream-tcp.c stream-tcp.h \
respond-reject.c respond-reject.h \
respond-reject-libnet11.h respond-reject-libnet11.c

@ -243,6 +243,8 @@ int AlertUnifiedLogThreadInit(ThreadVars *t, void *initdata, void **data)
int AlertUnifiedLogThreadDeinit(ThreadVars *t, void *data)
{
printf("AlertUnifiedLogThreadDeinit started\n");
AlertUnifiedLogThread *aun = (AlertUnifiedLogThread *)data;
if (aun == NULL) {
goto error;
@ -254,6 +256,7 @@ int AlertUnifiedLogThreadDeinit(ThreadVars *t, void *data)
/* clear memory */
memset(aun, 0, sizeof(AlertUnifiedLogThread));
free(aun);
printf("AlertUnifiedLogThreadDeinit done\n");
return 0;
error:
@ -262,6 +265,7 @@ error:
memset(aun, 0, sizeof(AlertUnifiedLogThread));
free(aun);
}
printf("AlertUnifiedLogThreadDeinit done (error)\n");
return -1;
}

@ -0,0 +1,29 @@
/* Copyright (c) 2009 Victor Julien <victor@inliniac.net> */
#include "decode.h"
#include "decode-ethernet.h"
void DecodeEthernet(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len, PacketQueue *pq)
{
if (len < ETHERNET_HEADER_LEN)
return;
EthernetHdr *ethh = (EthernetHdr *)pkt;
if (ethh == NULL)
return;
#ifdef DEBUG
printf("DecodeEthernet: p %p pkt %p ether type %04x\n", p, pkt, ntohs(ethh->eth_type));
#endif
if (ntohs(ethh->eth_type) == ETHERNET_TYPE_IP) {
//printf("DecodeEthernet ip4\n");
DecodeIPV4(t, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, pq);
} else if(ntohs(ethh->eth_type) == ETHERNET_TYPE_IPV6) {
//printf("DecodeEthernet ip6\n");
DecodeIPV6(t, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN);
}
return;
}

@ -2,6 +2,8 @@
#ifndef __DECODE_ETHERNET_H__
#define __DECODE_ETHERNET_H__
#define ETHERNET_HEADER_LEN 14
/* Ethernet types -- taken from Snort and Libdnet */
#define ETHERNET_TYPE_PUP 0x0200 /* PUP protocol */
#define ETHERNET_TYPE_IP 0x0800

@ -0,0 +1,27 @@
/* Copyright (c) 2009 Victor Julien <victor@inliniac.net> */
#include "decode.h"
#include "decode-sll.h"
void DecodeSll(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len, PacketQueue *pq)
{
if (len < SLL_HEADER_LEN)
return;
SllHdr *sllh = (SllHdr *)pkt;
if (sllh == NULL)
return;
#ifdef DEBUG
printf("DecodeSll: p %p pkt %p sll_protocol %04x\n", p, pkt, ntohs(sllh->sll_protocol));
#endif
if (ntohs(sllh->sll_protocol) == ETHERNET_TYPE_IP) {
//printf("DecodeSll ip4\n");
DecodeIPV4(t, p, pkt + SLL_HEADER_LEN, len - SLL_HEADER_LEN, pq);
} else if(ntohs(sllh->sll_protocol) == ETHERNET_TYPE_IPV6) {
//printf("DecodeSll ip6\n");
DecodeIPV6(t, p, pkt + SLL_HEADER_LEN, len - SLL_HEADER_LEN);
}
}

@ -0,0 +1,16 @@
/* Copyright (c) 2009 Victor Julien <victor@inliniac.net> */
#ifndef __DECODE_SLL_H__
#define __DECODE_SLL_H__
#define SLL_HEADER_LEN 16
typedef struct SllHdr_ {
u_int16_t sll_pkttype; /* packet type */
u_int16_t sll_hatype; /* link-layer address type */
u_int16_t sll_halen; /* link-layer address length */
u_int8_t sll_addr[8]; /* link-layer address */
u_int16_t sll_protocol; /* protocol */
} SllHdr;
#endif /* __DECODE_SLL_H__ */

@ -14,6 +14,7 @@
#define TCP_OPTMAX 20 /* every opt is at least 2 bytes
* (type + len), except EOL and NOP */
/* TCP flags */
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
@ -61,6 +62,15 @@
#define TCP_GET_ACK(p) TCP_GET_RAW_ACK(p->tcph)
#define TCP_GET_WINDOW(p) TCP_GET_RAW_WINDOW(p->tcph)
#define TCP_ISSET_FLAG_FIN(p) ((p)->tcph->th_flags & TH_FIN)
#define TCP_ISSET_FLAG_SYN(p) ((p)->tcph->th_flags & TH_SYN)
#define TCP_ISSET_FLAG_RST(p) ((p)->tcph->th_flags & TH_RST)
#define TCP_ISSET_FLAG_PUSH(p) ((p)->tcph->th_flags & TH_PUSH)
#define TCP_ISSET_FLAG_ACK(p) ((p)->tcph->th_flags & TH_ACK)
#define TCP_ISSET_FLAG_URG(p) ((p)->tcph->th_flags & TH_URG)
#define TCP_ISSET_FLAG_RES2(p) ((p)->tcph->th_flags & TH_RES2)
#define TCP_ISSET_FLAG_RES1(p) ((p)->tcph->th_flags & TH_RES1)
typedef struct _TCPOpt {
u_int8_t type;
u_int8_t len;

@ -33,6 +33,7 @@
#include "action-globals.h"
#include "decode-ethernet.h"
#include "decode-sll.h"
#include "decode-ipv4.h"
#include "decode-ipv6.h"
#include "decode-icmpv4.h"
@ -129,13 +130,14 @@ typedef u_int16_t Port;
#define CMP_PORT(p1,p2) \
((p1 == p2))
#define PKT_IS_IPV4(p) (((p)->ip4h != NULL))
#define PKT_IS_IPV6(p) (((p)->ip6h != NULL))
#define PKT_IS_TCP(p) (((p)->tcph != NULL))
#define PKT_IS_UDP(p) (((p)->udph != NULL))
#define PKT_IS_ICMPV4 (((p)->icmpv4 != NULL))
#define PKT_IS_ICMPV6 (((p)->icmpv6 != NULL))
#define PKT_IS_IPV4(p) (((p)->ip4h != NULL))
#define PKT_IS_IPV6(p) (((p)->ip6h != NULL))
#define PKT_IS_TCP(p) (((p)->tcph != NULL))
#define PKT_IS_UDP(p) (((p)->udph != NULL))
#define PKT_IS_ICMPV4 (((p)->icmpv4 != NULL))
#define PKT_IS_ICMPV6 (((p)->icmpv6 != NULL))
#define PKT_IS_TOSERVER(p) (((p)->flowflags & FLOW_PKT_TOSERVER))
#define PKT_IS_TOCLIENT(p) (((p)->flowflags & FLOW_PKT_TOCLIENT))
/* structure to store the sids/gids/etc the detection engine
* found in this packet */
@ -358,6 +360,8 @@ typedef struct _PacketQueue {
/* decoder functions */
void DecodeEthernet(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *);
void DecodeSll(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *);
void DecodeTunnel(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *);
void DecodeIPV4(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *);
void DecodeIPV6(ThreadVars *, Packet *, u_int8_t *, u_int16_t);
@ -373,5 +377,11 @@ Packet *TunnelPktSetup(ThreadVars *, Packet *, u_int8_t *, u_int16_t, u_int8_t);
#define DECODER_SET_EVENT(p, e) ((p)->events[(e/8)] |= (1<<(e%8)))
#define DECODER_ISSET_EVENT(p, e) ((p)->events[(e/8)] & (1<<(e%8)))
/* libpcap shows us the way to linktype codes
* XXX we need more & maybe put them in a separate
* file? */
#define LINKTYPE_ETHERNET DLT_EN10MB
#define LINKTYPE_LINUX_SLL 113
#endif /* __DECODE_H__ */

@ -270,7 +270,7 @@ void SigLoadSignatures (void)
}
*/
#define LOADSIGS
//#define LOADSIGS
#ifdef LOADSIGS
int good = 0, bad = 0;
//FILE *fp = fopen("/etc/vips/rules/bleeding-all.rules", "r");

@ -16,6 +16,8 @@
(f)->lastts.tv_usec = 0; \
GenericVarFree((f)->flowvar); \
(f)->flowvar = NULL; \
(f)->stream = NULL; \
(f)->use_cnt = 0; \
}
Flow *FlowAlloc(void);

@ -5,6 +5,8 @@
#include "decode.h"
#include "threads.h"
#include "util-time.h"
#include "flow.h"
#include "flow-queue.h"
#include "flow-hash.h"
@ -89,6 +91,14 @@ static int FlowPrune (FlowQueue *q, struct timeval *ts, u_int32_t timeout)
DEBUGPRINT("got lock, now check: %ld+%u=(%ld) < %ld", f->lastts.tv_sec,
timeout, f->lastts.tv_sec + timeout, ts->tv_sec);
/* never prune a flow that is used by a packet we are currently
* processing in one of the threads */
if (f->use_cnt > 0) {
mutex_unlock(&f->fb->m);
mutex_unlock(&f->m);
return 0;
}
/* do the timeout check */
if ((f->lastts.tv_sec + timeout) >= ts->tv_sec) {
mutex_unlock(&f->fb->m);
@ -180,6 +190,17 @@ void FlowSetIPOnlyFlag(Flow *f, char direction) {
mutex_unlock(&f->m);
}
/* decrease the use cnt of a flow */
void FlowDecrUsecnt(ThreadVars *th_v, Packet *p) {
if (p == NULL || p->flow == NULL)
return;
mutex_lock(&p->flow->m);
if (p->flow->use_cnt > 0)
p->flow->use_cnt--;
mutex_unlock(&p->flow->m);
}
/* FlowHandlePacket
*
* This is called for every packet.
@ -195,6 +216,8 @@ void FlowHandlePacket (ThreadVars *th_v, Packet *p)
if (f == NULL)
return;
f->use_cnt++;
/* update the last seen timestamp of this flow */
COPY_TIMESTAMP(&p->ts, &f->lastts);
@ -393,7 +416,8 @@ void *FlowManagerThread(void *td)
/* Get the time */
memset(&ts, 0, sizeof(ts));
gettimeofday(&ts, NULL);
//gettimeofday(&ts, NULL);
TimeGet(&ts);
DEBUGPRINT("ts %ld", ts.tv_sec);
/* see if we still have enough spare flows */

@ -61,6 +61,9 @@ typedef struct _Flow
u_int32_t tosrcpktcnt;
u_int64_t bytecnt;
void *stream;
u_int16_t use_cnt; /* how many pkts are using the flow *right now* */
pthread_mutex_t m;
/* list flow ptrs
@ -79,6 +82,7 @@ void FlowInitConfig (void);
void FlowPrintFlows (void);
void FlowShutdown(void);
void FlowSetIPOnlyFlag(Flow *, char);
void FlowDecrUsecnt(ThreadVars *, Packet *);
void *FlowManagerThread(void *td);

@ -127,13 +127,6 @@ static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
/* pass on... */
tv->tmqh_out(tv, p);
mutex_lock(&mutex_pending);
pending++;
#ifdef DBG_PERF
if (pending > dbg_maxpending)
dbg_maxpending = pending;
#endif /* DBG_PERF */
mutex_unlock(&mutex_pending);
return 0;
}
@ -355,7 +348,8 @@ void NFQSetVerdict(NFQThreadVars *t, Packet *p) {
verdict = NF_ACCEPT;
} else if (p->action == ACTION_DROP) {
verdict = NF_DROP;
} else if (p->action == ACTION_REJECT || p->action == ACTION_REJECT_DST ||
} else if (p->action == ACTION_REJECT ||
p->action == ACTION_REJECT_DST ||
p->action == ACTION_REJECT_BOTH){
verdict = NF_DROP;
} else {
@ -423,10 +417,15 @@ int DecodeNFQ(ThreadVars *t, Packet *p, void *data, PacketQueue *pq)
printf("DecodeNFQ\n");
#endif
if (IPV4_GET_RAW_VER(ip4h) == 4)
if (IPV4_GET_RAW_VER(ip4h) == 4) {
printf("DecodeNFQ ip4\n");
DecodeIPV4(t, p, p->pkt, p->pktlen, pq);
else if(IPV6_GET_RAW_VER(ip6h) == 6)
} else if(IPV6_GET_RAW_VER(ip6h) == 6) {
printf("DecodeNFQ ip6\n");
DecodeIPV6(t, p, p->pkt, p->pktlen);
} else {
printf("DecodeNFQ %02x\n", *p->pkt);
}
return 0;
}

@ -0,0 +1,178 @@
/* Copyright (c) 2009 Victor Julien <victor@inliniac.net> */
/* TODO
*
*
*
*/
#include <pthread.h>
#include <sys/signal.h>
#include <pcap/pcap.h>
#include "vips.h"
#include "decode.h"
#include "packet-queue.h"
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "source-pcap-file.h"
#include "util-time.h"
typedef struct PcapFileGlobalVars_ {
pcap_t *pcap_handle;
void (*Decoder)(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *);
} PcapFileGlobalVars;
typedef struct PcapFileThreadVars_
{
/* counters */
u_int32_t pkts;
u_int64_t bytes;
u_int32_t errs;
ThreadVars *tv;
} PcapFileThreadVars;
static PcapFileGlobalVars pcap_g = { NULL, NULL, };
int ReceivePcapFile(ThreadVars *, Packet *, void *, PacketQueue *);
int ReceivePcapFileThreadInit(ThreadVars *, void *, void **);
void ReceivePcapFileThreadExitStats(ThreadVars *, void *);
int ReceivePcapFileThreadDeinit(ThreadVars *, void *);
int DecodePcapFile(ThreadVars *, Packet *, void *, PacketQueue *);
void TmModuleReceivePcapFileRegister (void) {
tmm_modules[TMM_RECEIVEPCAPFILE].name = "ReceivePcapFile";
tmm_modules[TMM_RECEIVEPCAPFILE].Init = ReceivePcapFileThreadInit;
tmm_modules[TMM_RECEIVEPCAPFILE].Func = ReceivePcapFile;
tmm_modules[TMM_RECEIVEPCAPFILE].ExitPrintStats = ReceivePcapFileThreadExitStats;
tmm_modules[TMM_RECEIVEPCAPFILE].Deinit = NULL;
tmm_modules[TMM_RECEIVEPCAPFILE].RegisterTests = NULL;
}
void TmModuleDecodePcapFileRegister (void) {
tmm_modules[TMM_DECODEPCAPFILE].name = "DecodePcapFile";
tmm_modules[TMM_DECODEPCAPFILE].Init = NULL;
tmm_modules[TMM_DECODEPCAPFILE].Func = DecodePcapFile;
tmm_modules[TMM_DECODEPCAPFILE].ExitPrintStats = NULL;
tmm_modules[TMM_DECODEPCAPFILE].Deinit = NULL;
tmm_modules[TMM_DECODEPCAPFILE].RegisterTests = NULL;
}
void PcapFileCallback(char *user, struct pcap_pkthdr *h, u_char *pkt) {
//printf("PcapFileCallback: user %p, h %p, pkt %p\n", user, h, pkt);
PcapFileThreadVars *ptv = (PcapFileThreadVars *)user;
ThreadVars *tv = ptv->tv;
mutex_lock(&mutex_pending);
if (pending > MAX_PENDING) {
pthread_cond_wait(&cond_pending, &mutex_pending);
}
mutex_unlock(&mutex_pending);
Packet *p = tv->tmqh_in(tv);
p->ts.tv_sec = h->ts.tv_sec;
p->ts.tv_usec = h->ts.tv_usec;
TimeSet(&p->ts);
ptv->pkts++;
ptv->bytes += h->caplen;
p->pktlen = h->caplen;
memcpy(p->pkt, pkt, p->pktlen);
//printf("PcapFileCallback: p->pktlen: %u (pkt %02x, p->pkt %02x)\n", p->pktlen, *pkt, *p->pkt);
/* pass on... */
tv->tmqh_out(tv, p);
}
int ReceivePcapFile(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) {
PcapFileThreadVars *ptv = (PcapFileThreadVars *)data;
//printf("ReceivePcap: tv %p\n", tv);
int r = pcap_dispatch(pcap_g.pcap_handle, 1, (pcap_handler)PcapFileCallback, (u_char *)ptv);
if (r <= 0) {
printf("ReceivePcap: code %d error %s\n", r, pcap_geterr(pcap_g.pcap_handle));
#if 0
/* Stop the engine so it quits after processing the pcap file
* but first make sure all packets are processed by all other
* threads. */
char done = 0;
do {
mutex_lock(&mutex_pending);
if (pending == 0)
done = 1;
mutex_unlock(&mutex_pending);
if (done == 0) {
usleep(100);
}
} while (done == 0);
printf("ReceivePcapFile: all packets processed by threads, stopping engine\n");
#endif
EngineStop();
return 1;
}
return 0;
}
int ReceivePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (initdata == NULL) {
printf("ReceivePcapFileThreadInit error: initdata == NULL\n");
return -1;
}
PcapFileThreadVars *ptv = malloc(sizeof(PcapFileThreadVars));
if (ptv == NULL) {
return -1;
}
memset(ptv, 0, sizeof(PcapFileThreadVars));
/* XXX create a general pcap setup function */
char errbuf[PCAP_ERRBUF_SIZE];
pcap_g.pcap_handle = pcap_open_offline((char *)initdata, errbuf);
if (pcap_g.pcap_handle == NULL) {
printf("error %s\n", pcap_geterr(pcap_g.pcap_handle));
exit(1);
}
int datalink = pcap_datalink(pcap_g.pcap_handle);
printf("TmModuleReceivePcapFileRegister: datalink %d\n", datalink);
if (datalink == LINKTYPE_LINUX_SLL)
pcap_g.Decoder = DecodeSll;
else if (datalink == LINKTYPE_ETHERNET)
pcap_g.Decoder = DecodeEthernet;
else {
printf("Error: datalink type %d not yet supported in module PcapFile.\n", datalink);
}
ptv->tv = tv;
*data = (void *)ptv;
return 0;
}
void ReceivePcapFileThreadExitStats(ThreadVars *tv, void *data) {
PcapFileThreadVars *ptv = (PcapFileThreadVars *)data;
printf(" - (%s) Packets %u, bytes %llu.\n", tv->name, ptv->pkts, ptv->bytes);
return;
}
int ReceivePcapFileThreadDeinit(ThreadVars *tv, void *data) {
return 0;
}
int DecodePcapFile(ThreadVars *t, Packet *p, void *data, PacketQueue *pq) {
/* call the decoder */
pcap_g.Decoder(t,p,p->pkt,p->pktlen,pq);
return 0;
}
/* eof */

@ -0,0 +1,10 @@
/* Copyright (c) 2009 Victor Julien <victor@inliniac.net> */
#ifndef __SOURCE_PCAP_FILE_H__
#define __SOURCE_PCAP_FILE_H__
void TmModuleReceivePcapFileRegister (void);
void TmModuleDecodePcapFileRegister (void);
#endif /* __SOURCE_PCAP_FILE_H__ */

@ -0,0 +1,165 @@
/* Copyright (c) 2009 Victor Julien <victor@inliniac.net> */
/* TODO
*
*
*
*/
#include <pthread.h>
#include <sys/signal.h>
#include <pcap/pcap.h>
#include "vips.h"
#include "decode.h"
#include "packet-queue.h"
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "source-pcap.h"
typedef struct PcapGlobalVars_ {
pcap_t *pcap_handle;
void (*Decoder)(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *);
} PcapGlobalVars;
typedef struct PcapThreadVars_
{
/* counters */
u_int32_t pkts;
u_int64_t bytes;
u_int32_t errs;
ThreadVars *tv;
} PcapThreadVars;
static PcapGlobalVars pcap_g = { NULL, NULL, };
int ReceivePcap(ThreadVars *, Packet *, void *, PacketQueue *);
int ReceivePcapThreadInit(ThreadVars *, void *, void **);
void ReceivePcapThreadExitStats(ThreadVars *, void *);
int ReceivePcapThreadDeinit(ThreadVars *, void *);
int DecodePcap(ThreadVars *, Packet *, void *, PacketQueue *);
void TmModuleReceivePcapRegister (void) {
tmm_modules[TMM_RECEIVEPCAP].name = "ReceivePcap";
tmm_modules[TMM_RECEIVEPCAP].Init = ReceivePcapThreadInit;
tmm_modules[TMM_RECEIVEPCAP].Func = ReceivePcap;
tmm_modules[TMM_RECEIVEPCAP].ExitPrintStats = ReceivePcapThreadExitStats;
tmm_modules[TMM_RECEIVEPCAP].Deinit = NULL;
tmm_modules[TMM_RECEIVEPCAP].RegisterTests = NULL;
}
void TmModuleDecodePcapRegister (void) {
tmm_modules[TMM_DECODEPCAP].name = "DecodePcap";
tmm_modules[TMM_DECODEPCAP].Init = NULL;
tmm_modules[TMM_DECODEPCAP].Func = DecodePcap;
tmm_modules[TMM_DECODEPCAP].ExitPrintStats = NULL;
tmm_modules[TMM_DECODEPCAP].Deinit = NULL;
tmm_modules[TMM_DECODEPCAP].RegisterTests = NULL;
}
void PcapCallback(char *user, struct pcap_pkthdr *h, u_char *pkt) {
//printf("PcapCallback: user %p, h %p, pkt %p\n", user, h, pkt);
PcapThreadVars *ptv = (PcapThreadVars *)user;
ThreadVars *tv = ptv->tv;
mutex_lock(&mutex_pending);
if (pending > MAX_PENDING) {
pthread_cond_wait(&cond_pending, &mutex_pending);
}
mutex_unlock(&mutex_pending);
Packet *p = tv->tmqh_in(tv);
p->ts.tv_sec = h->ts.tv_sec;
p->ts.tv_usec = h->ts.tv_usec;
ptv->pkts++;
ptv->bytes += h->caplen;
p->pktlen = h->caplen;
memcpy(p->pkt, pkt, p->pktlen);
//printf("PcapCallback: p->pktlen: %u (pkt %02x, p->pkt %02x)\n", p->pktlen, *pkt, *p->pkt);
/* pass on... */
tv->tmqh_out(tv, p);
}
int ReceivePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) {
PcapThreadVars *ptv = (PcapThreadVars *)data;
//printf("ReceivePcap: tv %p\n", tv);
int r = pcap_dispatch(pcap_g.pcap_handle, 1, (pcap_handler)PcapCallback, (u_char *)ptv);
if (r <= 0) {
//printf("ReceivePcap: error %s\n", pcap_geterr(pcap_g.pcap_handle));
}
return 0;
}
int ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (initdata == NULL) {
printf("ReceivePcapThreadInit error: initdata == NULL\n");
return -1;
}
PcapThreadVars *ptv = malloc(sizeof(PcapThreadVars));
if (ptv == NULL) {
return -1;
}
memset(ptv, 0, sizeof(PcapThreadVars));
ptv->tv = tv;
printf("ReceivePcapThreadInit: using interface %s\n", (char *)initdata);
/* XXX create a general pcap setup function */
char errbuf[PCAP_ERRBUF_SIZE];
pcap_g.pcap_handle = pcap_create((char *)initdata, errbuf);
if (pcap_g.pcap_handle == NULL) {
printf("error %s\n", pcap_geterr(pcap_g.pcap_handle));
exit(1);
}
int r = pcap_activate(pcap_g.pcap_handle);
printf("ReceivePcapThreadInit: pcap_activate(%p) returned %d\n", pcap_g.pcap_handle, r);
if (r != 0) {
printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(pcap_g.pcap_handle));
}
int datalink = pcap_datalink(pcap_g.pcap_handle);
printf("TmModuleReceivePcapRegister: datalink %d\n", datalink);
if (datalink == LINKTYPE_LINUX_SLL)
pcap_g.Decoder = DecodeSll;
else if (datalink == LINKTYPE_ETHERNET)
pcap_g.Decoder = DecodeEthernet;
else {
printf("Error: datalink type %d not yet supported in module Pcap.\n", datalink);
}
*data = (void *)ptv;
return 0;
}
void ReceivePcapThreadExitStats(ThreadVars *tv, void *data) {
PcapThreadVars *ptv = (PcapThreadVars *)data;
printf(" - (%s) Packets %u, bytes %llu.\n", tv->name, ptv->pkts, ptv->bytes);
return;
}
int ReceivePcapThreadDeinit(ThreadVars *tv, void *data) {
return 0;
}
int DecodePcap(ThreadVars *t, Packet *p, void *data, PacketQueue *pq) {
/* call the decoder */
pcap_g.Decoder(t,p,p->pkt,p->pktlen,pq);
return 0;
}
/* eof */

@ -0,0 +1,10 @@
/* Copyright (c) 2009 Victor Julien <victor@inliniac.net> */
#ifndef __SOURCE_PCAP_H__
#define __SOURCE_PCAP_H__
void TmModuleReceivePcapRegister (void);
void TmModuleDecodePcapRegister (void);
#endif /* __SOURCE_PCAP_H__ */

@ -0,0 +1,566 @@
/* Copyright (c) 2008 Victor Julien <victor@inliniac.net> */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "vips.h"
#include "debug.h"
#include "detect.h"
#include "flow.h"
#include "threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "util-pool.h"
#include "util-unittest.h"
int StreamTcp (ThreadVars *, Packet *, void *, PacketQueue *);
int StreamTcpThreadInit(ThreadVars *, void *, void **);
int StreamTcpThreadDeinit(ThreadVars *, void *);
void StreamTcpExitPrintStats(ThreadVars *, void *);
typedef struct _TcpStream {
u_int32_t isn; /* initial sequence number */
u_int32_t next_seq; /* next expected sequence number */
u_int32_t last_ack; /* last ack'd sequence number */
u_int32_t next_win; /* next max seq within window */
u_int8_t wscale;
u_int16_t window;
} TcpStream;
/* from /usr/include/netinet/tcp.h */
enum
{
TCP_ESTABLISHED = 1,
TCP_SYN_SENT,
TCP_SYN_RECV,
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
TCP_CLOSING /* now a valid state */
};
/* Macro's for comparing Sequence numbers
* Page 810 from TCP/IP Illustrated, Volume 2. */
#define SEQ_EQ(a,b) ((int)((a) - (b)) == 0)
#define SEQ_LT(a,b) ((int)((a) - (b)) < 0)
#define SEQ_LEQ(a,b) ((int)((a) - (b)) <= 0)
#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
#define SEQ_GEQ(a,b) ((int)((a) - (b)) >= 0)
typedef struct _TcpSession {
u_int8_t state;
TcpStream server;
TcpStream client;
} TcpSession;
void *StreamTcpSessionAlloc(void) {
void *ptr = malloc(sizeof(TcpSession));
if (ptr == NULL)
return NULL;
memset(ptr, 0, sizeof(TcpSession));
return ptr;
}
#define StreamTcpSessionFree free
static Pool *ssn_pool;
static pthread_mutex_t ssn_pool_mutex;
void TmModuleStreamTcpRegister (void) {
tmm_modules[TMM_STREAMTCP].name = "StreamTcp";
tmm_modules[TMM_STREAMTCP].Init = StreamTcpThreadInit;
tmm_modules[TMM_STREAMTCP].Func = StreamTcp;
tmm_modules[TMM_STREAMTCP].ExitPrintStats = StreamTcpExitPrintStats;
tmm_modules[TMM_STREAMTCP].Deinit = StreamTcpThreadDeinit;
tmm_modules[TMM_STREAMTCP].RegisterTests = NULL;
ssn_pool = PoolInit(262144, 32768, StreamTcpSessionAlloc, StreamTcpSessionFree);
if (ssn_pool == NULL) {
exit(1);
}
pthread_mutex_init(&ssn_pool_mutex, NULL);
}
typedef struct _StreamTcpThread {
u_int64_t pkts;
} StreamTcpThread;
/* StreamTcpPacketStateNone
* Handle packets while the session state is None which means a
* newly initialized structure, or a fully closed session.
*/
static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
switch (p->tcph->th_flags) {
case TH_SYN:
/* get a stream */
mutex_lock(&ssn_pool_mutex);
p->flow->stream = PoolGet(ssn_pool);
mutex_unlock(&ssn_pool_mutex);
TcpSession *ssn = (TcpSession *)p->flow->stream;
if (ssn == NULL)
return -1;
/* set the state */
ssn->state = TCP_SYN_SENT;
printf("StreamTcpPacketStateNone (%p): =~ ssn state is now TCP_SYN_SENT\n", ssn);
/* set the sequence numbers and window */
ssn->client.isn = TCP_GET_SEQ(p);
ssn->client.next_seq = ssn->client.isn + 1;
ssn->client.window = TCP_GET_WINDOW(p);
//ssn->server.last_ack = ssn->client.isn + 1;
//ssn->server.last_ack = TCP_GET_ACK(p);
printf("StreamTcpPacketStateNone (%p): ssn->client.isn %u, ssn->client.next_seq %u, ssn->SERVER.last_ack %u\n",
ssn, ssn->client.isn, ssn->client.next_seq, ssn->server.last_ack);
if (p->tcpvars.ws != NULL) {
printf("StreamTcpPacketStateNone (%p): p->tcpvars.ws %p, %02x\n", ssn, p->tcpvars.ws, *p->tcpvars.ws->data);
ssn->client.wscale = *p->tcpvars.ws->data;
}
break;
default:
//printf("StreamTcpPacketStateNone: default case\n");
break;
}
return 0;
}
static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch (p->tcph->th_flags) {
case TH_SYN:
printf("StreamTcpPacketStateSynSent (%p): SYN packet on state SYN_SENT... resent\n", ssn);
break;
case TH_SYN|TH_ACK:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateSynSent (%p): SYN/ACK received in the wrong direction\n", ssn);
return -1;
}
/* Check if the SYN/ACK packet ack's the earlier
* received SYN packet. */
if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.isn + 1))) {
printf("StreamTcpPacketStateSynSent (%p): ACK mismatch, packet ACK %u != %u from stream\n",
ssn, TCP_GET_ACK(p), ssn->client.isn + 1);
return -1;
}
/* update state */
ssn->state = TCP_SYN_RECV;
printf("StreamTcpPacketStateSynSent (%p): =~ ssn state is now TCP_SYN_RECV\n", ssn);
/* sequence number & window */
ssn->server.isn = TCP_GET_SEQ(p);
ssn->server.next_seq = ssn->server.isn + 1;
ssn->server.window = TCP_GET_WINDOW(p);
printf("StreamTcpPacketStateSynSent: (%p): window %u\n", ssn, ssn->server.window);
ssn->client.last_ack = TCP_GET_ACK(p);
ssn->server.last_ack = ssn->server.isn + 1;
if (ssn->client.wscale != 0 && p->tcpvars.ws != NULL) {
printf("StreamTcpPacketStateSynSent (%p): p->tcpvars.ws %p, %02x\n", ssn, p->tcpvars.ws, *p->tcpvars.ws->data);
ssn->server.wscale = *p->tcpvars.ws->data;
} else {
ssn->client.wscale = 0;
}
ssn->server.next_win = ssn->server.last_ack + ssn->server.window;
printf("StreamTcpPacketStateSynSent (%p): next_win %u\n", ssn, ssn->server.next_win);
printf("StreamTcpPacketStateSynSent (%p): ssn->server.isn %u, ssn->server.next_seq %u, ssn->CLIENT.last_ack %u\n",
ssn, ssn->server.isn, ssn->server.next_seq, ssn->client.last_ack);
break;
default:
printf("StreamTcpPacketStateSynSent (%p): default case\n", ssn);
break;
}
return 0;
}
static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch (p->tcph->th_flags) {
case TH_SYN:
printf("StreamTcpPacketStateSynRecv (%p): SYN packet on state SYN_RECV... resent\n", ssn);
break;
case TH_SYN|TH_ACK:
printf("StreamTcpPacketStateSynRecv (%p): SYN/ACK packet on state SYN_RECV... resent\n", ssn);
break;
case TH_ACK:
if (PKT_IS_TOCLIENT(p)) {
printf("StreamTcpPacketStateSynRecv (%p): ACK received in the wrong direction\n", ssn);
return -1;
}
if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq))) {
printf("StreamTcpPacketStateSynRecv (%p): ACK received in the wrong direction\n", ssn);
return -1;
}
printf("StreamTcpPacketStateSynRecv (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
ssn->state = TCP_ESTABLISHED;
printf("StreamTcpPacketStateSynRecv (%p): =~ ssn state is now TCP_ESTABLISHED\n", ssn);
ssn->client.next_seq += p->payload_len;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
ssn->server.last_ack = TCP_GET_ACK(p);
ssn->client.next_win = ssn->client.last_ack + ssn->client.window;
printf("StreamTcpPacketStateSynRecv (%p): next_win %u\n", ssn, ssn->client.next_win);
break;
default:
printf("StreamTcpPacketStateSynRecv (%p): default case\n", ssn);
break;
}
return 0;
}
static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch (p->tcph->th_flags) {
case TH_SYN:
printf("StreamTcpPacketStateEstablished (%p): SYN packet on state ESTABLISED... resent\n", ssn);
break;
case TH_SYN|TH_ACK:
printf("StreamTcpPacketStateEstablished (%p): SYN/ACK packet on state ESTABLISHED... resent\n", ssn);
break;
case TH_ACK:
case TH_ACK|TH_PUSH:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateEstablished (%p): =+ pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) {
ssn->client.next_seq += p->payload_len;
printf("StreamTcpPacketStateEstablished (%p): ssn->client.next_seq %u\n", ssn, ssn->client.next_seq);
}
if (SEQ_GEQ(TCP_GET_SEQ(p), ssn->client.last_ack) &&
SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win)) {
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
if (SEQ_GT(ssn->client.last_ack + ssn->client.window, ssn->client.next_win)) {
ssn->client.next_win = ssn->client.last_ack + ssn->client.window;
printf("StreamTcpPacketStateEstablished (%p): ssn->client.next_win %u\n", ssn, ssn->client.next_win);
}
} else {
printf("StreamTcpPacketStateEstablished (%p): !!!!! => SEQ mismatch, packet SEQ %u, payload size %u (%u), last_ack %u, next_win %u\n",
ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, ssn->client.last_ack, ssn->client.next_win);
}
printf("StreamTcpPacketStateEstablished (%p): next SEQ %u, last ACK %u, next win %u, win %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack, ssn->client.next_win, ssn->client.window);
} else { /* implied to client */
printf("StreamTcpPacketStateEstablished (%p): =+ pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) {
ssn->server.next_seq += p->payload_len;
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
}
if (SEQ_GEQ(TCP_GET_SEQ(p), ssn->server.last_ack) &&
SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win)) {
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
if (SEQ_GT(ssn->server.last_ack + ssn->server.window, ssn->server.next_win)) {
ssn->server.next_win = ssn->server.last_ack + ssn->server.window;
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_win %u\n", ssn, ssn->server.next_win);
}
} else {
printf("StreamTcpPacketStateEstablished (%p): !!!!! => SEQ mismatch, packet SEQ %u, payload size %u (%u), last_ack %u, next_win %u\n",
ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, ssn->server.last_ack, ssn->server.next_win);
}
printf("StreamTcpPacketStateEstablished (%p): next SEQ %u, last ACK %u, next win %u, win %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack, ssn->server.next_win, ssn->server.window);
}
break;
case TH_FIN:
case TH_FIN|TH_ACK:
case TH_FIN|TH_ACK|TH_PUSH:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateEstablished (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
printf("StreamTcpPacketStateEstablished (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateEstablished (%p): state changed to TCP_FIN_WAIT1\n", ssn);
ssn->state = TCP_FIN_WAIT1;
ssn->client.next_seq = TCP_GET_ACK(p);
ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1;
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
printf("StreamTcpPacketStateEstablished (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacketStateEstablished (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->server.next_seq) {
printf("StreamTcpPacketStateEstablished (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateEstablished (%p): state changed to TCP_FIN_WAIT1\n", ssn);
ssn->state = TCP_FIN_WAIT1;
ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1;
ssn->client.next_seq = TCP_GET_ACK(p);
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
printf("StreamTcpPacketStateEstablished (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
}
return 0;
}
static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch (p->tcph->th_flags) {
case TH_FIN:
case TH_FIN|TH_ACK:
case TH_FIN|TH_ACK|TH_PUSH:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateFinWait1 (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
printf("StreamTcpPacketStateFinWait1 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait1 (%p): state changed to TCP_FIN_WAIT2\n", ssn);
ssn->state = TCP_FIN_WAIT2;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
printf("StreamTcpPacketStateFinWait1 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacketStateFinWait1 (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->server.next_seq) {
printf("StreamTcpPacketStateFinWait1 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait1 (%p): state changed to TCP_FIN_WAIT2\n", ssn);
ssn->state = TCP_FIN_WAIT2;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
printf("StreamTcpPacketStateFinWait1 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
}
return 0;
}
static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch (p->tcph->th_flags) {
case TH_ACK:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateFinWait2 (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
printf("StreamTcpPacketStateFinWait2 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait2 (%p): state changed to 0\n", ssn);
ssn->state = 0;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
printf("StreamTcpPacketStateFinWait2 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacketStateFinWait2 (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->server.next_seq) {
printf("StreamTcpPacketStateFinWait2 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait2 (%p): state changed to 0\n", ssn);
ssn->state = 0;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
printf("StreamTcpPacketStateFinWait2 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
}
return 0;
}
/* flow is and stays locked */
static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
if (ssn == NULL || ssn->state == 0) {
StreamTcpPacketStateNone(tv, p, stt);
} else {
switch (ssn->state) {
case TCP_SYN_SENT:
StreamTcpPacketStateSynSent(tv, p, stt);
break;
case TCP_SYN_RECV:
StreamTcpPacketStateSynRecv(tv, p, stt);
break;
case TCP_ESTABLISHED:
StreamTcpPacketStateEstablished(tv, p, stt);
break;
case TCP_FIN_WAIT1:
StreamTcpPacketStateFinWait1(tv, p, stt);
break;
case TCP_FIN_WAIT2:
StreamTcpPacketStateFinWait2(tv, p, stt);
break;
}
}
return 0;
}
int StreamTcp (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq)
{
StreamTcpThread *stt = (StreamTcpThread *)data;
if (!(PKT_IS_TCP(p)))
return 0;
if (p->flow == NULL)
return 0;
#if 0
printf("StreamTcp: seq %u, ack %u, %s%s%s%s%s%s%s%s: ", TCP_GET_SEQ(p), TCP_GET_ACK(p),
TCP_ISSET_FLAG_FIN(p) ? "FIN " :"",
TCP_ISSET_FLAG_SYN(p) ? "SYN " :"",
TCP_ISSET_FLAG_RST(p) ? "RST " :"",
TCP_ISSET_FLAG_PUSH(p)? "PUSH ":"",
TCP_ISSET_FLAG_ACK(p) ? "ACK " :"",
TCP_ISSET_FLAG_URG(p) ? "URG " :"",
TCP_ISSET_FLAG_RES2(p)? "RES2 ":"",
TCP_ISSET_FLAG_RES1(p)? "RES1 ":"");
#endif
mutex_lock(&p->flow->m);
StreamTcpPacket(tv, p, stt);
mutex_unlock(&p->flow->m);
stt->pkts++;
return 0;
}
int StreamTcpThreadInit(ThreadVars *t, void *initdata, void **data)
{
StreamTcpThread *stt = malloc(sizeof(StreamTcpThread));
if (stt == NULL) {
return -1;
}
memset(stt, 0, sizeof(StreamTcpThread));
/* XXX */
*data = (void *)stt;
return 0;
}
int StreamTcpThreadDeinit(ThreadVars *t, void *data)
{
StreamTcpThread *stt = (StreamTcpThread *)data;
if (stt == NULL) {
return 0;
}
/* XXX */
/* clear memory */
memset(stt, 0, sizeof(StreamTcpThread));
free(stt);
return 0;
}
void StreamTcpExitPrintStats(ThreadVars *tv, void *data) {
StreamTcpThread *stt = (StreamTcpThread *)data;
if (stt == NULL) {
return;
}
printf(" - (%s) Packets %llu.\n", tv->name, stt->pkts);
}

@ -0,0 +1,9 @@
/* Copyright (c) 2008 Victor Julien <victor@inliniac.net> */
#ifndef __STREAM_TCP_H__
#define __STREAM_TCP_H__
void TmModuleStreamTcpRegister (void);
#endif /* __STREAM_TCP_H__ */

@ -7,8 +7,9 @@
#include "util-mpm.h"
#include "tm-queues.h"
#define THV_USE 0x01
#define THV_KILL 0x02
#define THV_USE 0x01
#define THV_KILL 0x02
#define THV_CLOSED 0x04 /* thread done, should be joinable */
typedef struct _ThreadVars {
pthread_t t;
@ -16,8 +17,6 @@ typedef struct _ThreadVars {
u_int8_t flags;
/* queue's */
int pickup_q_id;
int verdict_q_id;
Tmq *inq;
Tmq *outq;
@ -31,9 +30,6 @@ typedef struct _ThreadVars {
char set_cpu_affinity; /* bool: 0 no, 1 yes */
int cpu_affinity; /* cpu or core to set affinity to */
//#ifdef NFQ
// NFQThreadVars *nfq_t;
//#endif
struct _ThreadVars *next;
struct _ThreadVars *prev;

@ -14,6 +14,10 @@ enum {
TMM_DECODENFQ,
TMM_VERDICTNFQ,
TMM_RECEIVENFQ,
TMM_RECEIVEPCAP,
TMM_RECEIVEPCAPFILE,
TMM_DECODEPCAP,
TMM_DECODEPCAPFILE,
TMM_DETECT,
TMM_ALERTFASTLOG,
TMM_ALERTFASTLOG4,
@ -25,6 +29,7 @@ enum {
TMM_LOGHTTPLOG,
TMM_LOGHTTPLOG4,
TMM_LOGHTTPLOG6,
TMM_STREAMTCP,
TMM_SIZE,
};

@ -14,7 +14,7 @@ enum {
typedef struct _Tmqh {
char *name;
Packet *(*InHandler)(ThreadVars *);
void (*OutHandler);
void (*OutHandler)(ThreadVars *, Packet *);
} Tmqh;
Tmqh tmqh_table[TMQH_SIZE];

@ -70,6 +70,7 @@ void *TmThreadsSlot1NoIn(void *td) {
if (s->s.SlotInit != NULL) {
r = s->s.SlotInit(tv, s->s.slot_initdata, &s->s.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -97,10 +98,12 @@ void *TmThreadsSlot1NoIn(void *td) {
if (s->s.SlotDeinit != NULL) {
r = s->s.SlotDeinit(tv, s->s.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
tv->flags |= THV_CLOSED;
pthread_exit((void *) 0);
}
@ -117,6 +120,7 @@ void *TmThreadsSlot1NoOut(void *td) {
if (s->s.SlotInit != NULL) {
r = s->s.SlotInit(tv, s->s.slot_initdata, &s->s.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -139,10 +143,12 @@ void *TmThreadsSlot1NoOut(void *td) {
if (s->s.SlotDeinit != NULL) {
r = s->s.SlotDeinit(tv, s->s.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
tv->flags |= THV_CLOSED;
pthread_exit((void *) 0);
}
@ -160,6 +166,7 @@ void *TmThreadsSlot1NoInOut(void *td) {
if (s->s.SlotInit != NULL) {
r = s->s.SlotInit(tv, s->s.slot_initdata, &s->s.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -169,6 +176,9 @@ void *TmThreadsSlot1NoInOut(void *td) {
r = s->s.SlotFunc(tv, NULL, s->s.slot_data, /* no outqh, no pq */NULL);
//printf("%s: TmThreadsSlot1NoInNoOut: r %d\n", tv->name, r);
/* XXX handle error */
if (r == 1) {
run = 0;
}
if (tv->flags & THV_KILL) {
//printf("%s: TmThreadsSlot1NoInOut: KILL is set\n", tv->name);
@ -183,11 +193,13 @@ void *TmThreadsSlot1NoInOut(void *td) {
if (s->s.SlotDeinit != NULL) {
r = s->s.SlotDeinit(tv, s->s.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
//printf("TmThreadsSlot1NoInOut: %s ending\n", tv->name);
tv->flags |= THV_CLOSED;
pthread_exit((void *) 0);
}
@ -206,6 +218,7 @@ void *TmThreadsSlot1(void *td) {
if (s->s.SlotInit != NULL) {
r = s->s.SlotInit(tv, s->s.slot_initdata, &s->s.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -245,11 +258,13 @@ void *TmThreadsSlot1(void *td) {
if (s->s.SlotDeinit != NULL) {
r = s->s.SlotDeinit(tv, s->s.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
//printf("TmThreadsSlot1: %s ending\n", tv->name);
tv->flags |= THV_CLOSED;
pthread_exit((void *) 0);
}
@ -268,12 +283,14 @@ void *TmThreadsSlot2(void *td) {
if (s->s1.SlotInit != NULL) {
r = s->s1.SlotInit(tv, s->s1.slot_initdata, &s->s1.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
if (s->s2.SlotInit != NULL) {
r = s->s2.SlotInit(tv, s->s2.slot_initdata, &s->s2.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -326,6 +343,7 @@ void *TmThreadsSlot2(void *td) {
r = s->s1.SlotDeinit(tv, s->s1.slot_data);
if (r != 0) {
pthread_exit((void *) -1);
tv->flags |= THV_CLOSED;
}
}
@ -337,10 +355,12 @@ void *TmThreadsSlot2(void *td) {
r = s->s2.SlotDeinit(tv, s->s2.slot_data);
if (r != 0) {
pthread_exit((void *) -1);
tv->flags |= THV_CLOSED;
}
}
//printf("TmThreadsSlot2: %s ending\n", tv->name);
tv->flags |= THV_CLOSED;
pthread_exit((void *) 0);
}
@ -359,18 +379,21 @@ void *TmThreadsSlot3(void *td) {
if (s->s1.SlotInit != NULL) {
r = s->s1.SlotInit(tv, s->s1.slot_initdata, &s->s1.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
if (s->s2.SlotInit != NULL) {
r = s->s2.SlotInit(tv, s->s2.slot_initdata, &s->s2.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
if (s->s3.SlotInit != NULL) {
r = s->s3.SlotInit(tv, s->s3.slot_initdata, &s->s3.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -447,6 +470,7 @@ void *TmThreadsSlot3(void *td) {
if (s->s1.SlotDeinit != NULL) {
r = s->s1.SlotDeinit(tv, s->s1.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -458,6 +482,7 @@ void *TmThreadsSlot3(void *td) {
if (s->s2.SlotDeinit != NULL) {
r = s->s2.SlotDeinit(tv, s->s2.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -469,11 +494,13 @@ void *TmThreadsSlot3(void *td) {
if (s->s3.SlotDeinit != NULL) {
r = s->s3.SlotDeinit(tv, s->s3.slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
//printf("TmThreadsSlot3: %s ending\n", tv->name);
tv->flags |= THV_CLOSED;
pthread_exit((void *) 0);
}
@ -519,6 +546,7 @@ void *TmThreadsSlotVar(void *td) {
if (slot->SlotInit != NULL) {
r = slot->SlotInit(tv, slot->slot_initdata, &slot->slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
@ -553,12 +581,14 @@ void *TmThreadsSlotVar(void *td) {
if (slot->SlotDeinit != NULL) {
r = slot->SlotDeinit(tv, slot->slot_data);
if (r != 0) {
tv->flags |= THV_CLOSED;
pthread_exit((void *) -1);
}
}
}
//printf("TmThreadsSlot1: %s ending\n", tv->name);
tv->flags |= THV_CLOSED;
pthread_exit((void *) 0);
}
@ -838,12 +868,28 @@ void TmThreadKillThreads(void) {
printf("TmThreadKillThreads: t->inq->usecnt %u\n", t->inq->usecnt);
/* make sure our packet pending counter doesn't block */
pthread_cond_signal(&cond_pending);
/* signal the queue for the number of users */
for (i = 0; i < t->inq->usecnt; i++)
pthread_cond_signal(&trans_q[t->inq->id].cond_q);
/* to be sure, signal more */
for (i = 0; i < 1000; i++)
pthread_cond_signal(&trans_q[t->inq->id].cond_q);
int cnt = 0;
while (1) {
if (t->flags & THV_CLOSED) {
printf("signalled the thread %d times\n", cnt);
break;
}
cnt++;
for (i = 0; i < t->inq->usecnt; i++)
pthread_cond_signal(&trans_q[t->inq->id].cond_q);
usleep(100);
}
printf("TmThreadKillThreads: signalled t->inq->id %u\n", t->inq->id);
}

@ -1,9 +1,11 @@
/* Packetpool queue handlers */
#include "vips.h"
#include "packet-queue.h"
#include "decode.h"
#include "threads.h"
#include "threadvars.h"
#include "flow.h"
#include "tm-queuehandlers.h"
@ -23,6 +25,15 @@ Packet *TmqhInputPacketpool(ThreadVars *t)
/* XXX */
Packet *p = SetupPkt();
mutex_lock(&mutex_pending);
pending++;
//printf("PcapFileCallback: pending %u\n", pending);
#ifdef DBG_PERF
if (pending > dbg_maxpending)
dbg_maxpending = pending;
#endif /* DBG_PERF */
mutex_unlock(&mutex_pending);
/*
* Disabled because it can enter a 'wait' state, while
* keeping the nfq queue locked thus making it impossble
@ -92,6 +103,8 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
//printf("TmqhOutputPacketpool: tunnel stuff done, move on\n");
}
FlowDecrUsecnt(t,p);
if (proot) {
CLEAR_PACKET(p->root);
}
@ -105,7 +118,8 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
mutex_unlock(&q->mutex_q);
mutex_lock(&mutex_pending);
if (pending) {
//printf("TmqhOutputPacketpool: pending %u\n", pending);
if (pending > 0) {
pending--;
} else {
printf("TmqhOutputPacketpool: warning, trying to subtract from 0 pending counter.\n");

@ -0,0 +1,215 @@
/* Copyright (c) 2008 by Victor Julien <victor@inliniac.net> */
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "util-pool.h"
#include "util-unittest.h"
Pool *PoolInit(u_int32_t size, u_int32_t prealloc_size, void *(*Alloc)(void), void (*Free)(void *))
{
Pool *p = NULL;
if (Alloc == NULL) {
//printf("ERROR: PoolInit no Hash function\n");
goto error;
}
if (prealloc_size > size)
goto error;
/* setup the filter */
p = malloc(sizeof(Pool));
if (p == NULL)
goto error;
memset(p,0,sizeof(Pool));
p->Alloc = Alloc;
p->Free = Free;
/* alloc the buckets and place them in the empty list */
u_int32_t u32 = 0;
for (u32 = 0; u32 < size; u32++) {
/* populate pool */
PoolBucket *pb = malloc(sizeof(PoolBucket));
if (pb == NULL)
goto error;
memset(pb, 0, sizeof(PoolBucket));
pb->next = p->empty_list;
p->empty_list = pb;
p->empty_list_size++;
}
/* prealloc the buckets and requeue them to the alloc list */
for (u32 = 0; u32 < prealloc_size; u32++) {
PoolBucket *pb = p->empty_list;
if (pb == NULL)
goto error;
p->empty_list = pb->next;
p->empty_list_size--;
pb->data = p->Alloc();
pb->next = p->alloc_list;
p->alloc_list = pb;
p->alloc_list_size++;
}
return p;
error:
/* XXX */
return NULL;
}
void PoolFree(Pool *p) {
if (p == NULL)
return;
while (p->alloc_list != NULL) {
PoolBucket *pb = p->alloc_list;
p->alloc_list = pb->next;
p->Free(pb->data);
free(pb);
}
while (p->empty_list != NULL) {
PoolBucket *pb = p->empty_list;
p->empty_list = pb->next;
free(pb);
}
free(p);
}
void PoolPrint(Pool *p) {
printf("\n----------- Hash Table Stats ------------\n");
printf("Buckets: %u\n", p->empty_list_size + p->alloc_list_size);
printf("-----------------------------------------\n");
}
void *PoolGet(Pool *p) {
PoolBucket *pb = p->alloc_list;
if (pb == NULL)
return NULL;
/* pull from the alloc list */
p->alloc_list = pb->next;
p->alloc_list_size--;
/* put in the empty list */
pb->next = p->empty_list;
p->empty_list = pb;
p->empty_list_size++;
void *ptr = pb->data;
pb->data = NULL;
return ptr;
}
/*
* ONLY TESTS BELOW THIS COMMENT
*/
void *PoolTestAlloc(void) {
return malloc(10);
}
void PoolTestFree(void *ptr) {
free(ptr);
}
static int PoolTestInit01 (void) {
Pool *p = PoolInit(10,5,PoolTestAlloc,PoolTestFree);
if (p == NULL)
return 0;
PoolFree(p);
return 1;
}
static int PoolTestInit02 (void) {
int retval = 0;
Pool *p = PoolInit(10,5,PoolTestAlloc,PoolTestFree);
if (p == NULL)
goto end;
if (p->alloc_list == NULL || p->empty_list == NULL) {
printf("list(s) not properly initialized (a:%p e:%p): ",
p->alloc_list, p->empty_list);
retval = 0;
goto end;
} else {
retval = 1;
}
if (p->Alloc != PoolTestAlloc) {
printf("Alloc func ptr %p != %p: ",
p->Alloc, PoolTestAlloc);
retval = 0;
goto end;
} else {
retval = 1;
}
if (p->Free != PoolTestFree) {
printf("Free func ptr %p != %p: ",
p->Free, PoolTestFree);
retval = 0;
goto end;
} else {
retval = 1;
}
end:
if (p != NULL)
PoolFree(p);
return retval;
}
static int PoolTestInit03 (void) {
int retval = 0;
Pool *p = PoolInit(10,5,PoolTestAlloc,PoolTestFree);
if (p == NULL)
goto end;
void *data = PoolGet(p);
if (data == NULL) {
printf("PoolGet returned NULL: ");
retval = 0;
goto end;
}
if (p->alloc_list_size != 4) {
printf("p->alloc_list_size 4 != %u: ", p->alloc_list_size);
retval = 0;
goto end;
}
if (p->empty_list_size != 6) {
printf("p->empty_list_size 6 != %u: ", p->empty_list_size);
retval = 0;
goto end;
}
retval = 1;
end:
if (p != NULL)
PoolFree(p);
return retval;
}
void PoolRegisterTests(void) {
UtRegisterTest("PoolTestInit01", PoolTestInit01, 1);
UtRegisterTest("PoolTestInit02", PoolTestInit02, 1);
UtRegisterTest("PoolTestInit03", PoolTestInit03, 1);
}

@ -0,0 +1,31 @@
/* Copyright (c) 2008 by Victor Julien <victor@inliniac.net> */
#ifndef __POOL_H__
#define __POOL_H__
/* hash bucket structure */
typedef struct _PoolBucket {
void *data;
struct _PoolBucket *next;
} PoolBucket;
/* hash table structure */
typedef struct _Pool {
PoolBucket *alloc_list;
u_int32_t alloc_list_size;
PoolBucket *empty_list;
u_int32_t empty_list_size;
void *(*Alloc)(void);
void (*Free)(void *);
} Pool;
/* prototypes */
Pool* PoolInit(u_int32_t, u_int32_t, void *(*Alloc)(void), void (*Free)(void *));
void PoolFree(Pool *);
void PoolPrint(Pool *);
void *PoolGet(Pool *);
void PoolRegisterTests(void);
#endif /* __POOL_H__ */

@ -0,0 +1,51 @@
/* Time keeping for non-live packet handling (pcap files) */
#include "vips.h"
#include "detect.h"
#include "threads.h"
static struct timeval current_time = { 0,0 };
static pthread_mutex_t current_time_mutex = PTHREAD_MUTEX_INITIALIZER;
static char live = TRUE;
void TimeModeSetLive(void) {
live = TRUE;
}
void TimeModeSetNonlive (void) {
live = FALSE;
}
void TimeSet(struct timeval *tv) {
if (live == TRUE)
return;
if (tv == NULL)
return;
mutex_lock(&current_time_mutex);
current_time.tv_sec = tv->tv_sec;
current_time.tv_usec = tv->tv_usec;
//printf("TimeSet: time set to %lu sec, %lu usec\n",
// current_time.tv_sec, current_time.tv_usec);
mutex_unlock(&current_time_mutex);
}
void TimeGet(struct timeval *tv) {
if (tv == NULL)
return;
if (live == TRUE) {
gettimeofday(tv, NULL);
} else {
mutex_lock(&current_time_mutex);
tv->tv_sec = current_time.tv_sec;
tv->tv_usec = current_time.tv_usec;
mutex_unlock(&current_time_mutex);
}
//printf("TimeGet: time we got is %lu sec, %lu usec\n",
// tv->tv_sec, tv->tv_usec);
}

@ -0,0 +1,10 @@
#ifndef __UTIL_TIME_H__
#define __UTIL_TIME_H__
void TimeSet(struct timeval *);
void TimeGet(struct timeval *);
void TimeModeSetLive(void);
void TimeModeSetNonlive (void);
#endif /* __UTIL_TIME_H__ */

@ -26,6 +26,7 @@
#include "util-hashlist.h"
#include "util-bloomfilter.h"
#include "util-bloomfilter-counting.h"
#include "util-pool.h"
#include "detect-parse.h"
#include "detect-engine-mpm.h"
@ -42,11 +43,16 @@
#include "log-httplog.h"
#include "stream-tcp.h"
#ifdef NFQ
#include "source-nfq.h"
#include "source-nfq-prototypes.h"
#endif /* NFQ */
#include "source-pcap.h"
#include "source-pcap-file.h"
#include "respond-reject.h"
#include "flow.h"
@ -56,6 +62,7 @@
#include "util-cidr.h"
#include "util-unittest.h"
#include "util-time.h"
pthread_attr_t attr;
@ -69,6 +76,8 @@ static int sigterm_count = 0;
#define VIPS_SIGINT 0x01
#define VIPS_SIGHUP 0x02
#define VIPS_SIGTERM 0x04
#define VIPS_STOP 0x08
#define VIPS_KILL 0x10
static u_int8_t sigflags = 0;
@ -88,6 +97,27 @@ setup_signal_handler(int sig, void (*handler)())
sigaction(sig, &action, 0);
}
Packet *SetupPktWait (void)
{
Packet *p = NULL;
do {
mutex_lock(&packet_q.mutex_q);
p = PacketDequeue(&packet_q);
mutex_unlock(&packet_q.mutex_q);
if (p == NULL) {
//TmqDebugList();
usleep(1000); /* sleep 1ms */
/* XXX check for recv'd signals, so
* we can exit on signals received */
}
} while (p == NULL);
memset(p, 0, sizeof(Packet));
return p;
}
Packet *SetupPkt (void)
{
Packet *p = NULL;
@ -157,129 +187,46 @@ Packet *TunnelPktSetup(ThreadVars *t, Packet *parent, u_int8_t *pkt, u_int16_t l
return p;
}
int main(int argc, char **argv)
{
int rc;
sigset_t set;
sigaddset(&set, SIGINT);
/* registering signals we use */
setup_signal_handler(SIGINT, handle_sigint);
setup_signal_handler(SIGTERM, handle_sigterm);
setup_signal_handler(SIGHUP, handle_sighup);
//pthread_sigmask(SIG_BLOCK, &set, 0);
/* create table for O(1) lowercase conversion lookup */
u_int8_t c = 0;
for ( ; c < 255; c++) {
if (c >= 'A' && c <= 'Z')
g_u8_lowercasetable[c] = (c + ('a' - 'A'));
else
g_u8_lowercasetable[c] = c;
}
/* hardcoded initialization code */
MpmTableSetup(); /* load the pattern matchers */
SigTableSetup(); /* load the rule keywords */
TmqhSetup();
BinSearchInit();
CIDRInit();
SigParsePrepare();
PatternMatchPrepare(mpm_ctx);
TmModuleReceiveNFQRegister();
TmModuleVerdictNFQRegister();
TmModuleDecodeNFQRegister();
TmModuleDetectRegister();
TmModuleAlertFastlogRegister();
TmModuleAlertDebuglogRegister();
TmModuleRespondRejectRegister();
TmModuleAlertFastlogIPv4Register();
TmModuleAlertFastlogIPv6Register();
TmModuleAlertUnifiedLogRegister();
TmModuleAlertUnifiedAlertRegister();
TmModuleLogHttplogRegister();
TmModuleLogHttplogIPv4Register();
TmModuleLogHttplogIPv6Register();
TmModuleDebugList();
/* test and initialize the unittesting subsystem */
UtRunSelftest(); /* inits and cleans up again */
UtInitialize();
TmModuleRegisterTests();
SigTableRegisterTests();
HashTableRegisterTests();
HashListTableRegisterTests();
BloomFilterRegisterTests();
BloomFilterCountingRegisterTests();
MpmRegisterTests();
FlowBitRegisterTests();
SigRegisterTests();
//UtRunTests();
UtCleanup();
//exit(1);
//LoadConfig();
//exit(1);
/* initialize packet queues */
memset(&packet_q,0,sizeof(packet_q));
memset(&trans_q, 0,sizeof(trans_q));
/* pre allocate packets */
printf("Preallocating packets... packet size %u\n", sizeof(Packet));
int i = 0;
for (i = 0; i < MAX_PENDING; i++) {
/* XXX pkt alloc function */
Packet *p = malloc(sizeof(Packet));
if (p == NULL) {
printf("ERROR: malloc failed: %s\n", strerror(errno));
exit(1);
}
memset(p, 0, sizeof(Packet));
PacketEnqueue(&packet_q,p);
}
printf("Preallocating packets... done\n");
FlowInitConfig();
/* XXX hack: make sure threads can stop the engine by calling this
function. Purpose: pcap file mode needs to be able to tell the
engine the file eof is reached. */
void EngineStop(void) {
sigflags |= VIPS_STOP;
}
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
void EngineKill(void) {
sigflags |= VIPS_KILL;
}
SigLoadSignatures();
int RunModeIdsPcap(char *iface) {
TimeModeSetLive();
//#define PERF_THREADS
#define MANY_THREADS
#ifndef PERF_THREADS
/* create the threads */
ThreadVars *tv_receivenfq = TmThreadCreate("ReceiveNFQ","packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receivenfq == NULL) {
ThreadVars *tv_receivepcap = TmThreadCreate("ReceivePcap","packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receivepcap == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
TmModule *tm_module = TmModuleGetByName("ReceiveNFQ");
TmModule *tm_module = TmModuleGetByName("ReceivePcap");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
printf("ERROR: TmModuleGetByName failed for ReceivePcap\n");
exit(1);
}
Tm1SlotSetFunc(tv_receivenfq,tm_module,NULL);
Tm1SlotSetFunc(tv_receivepcap,tm_module,(void *)iface);
if (TmThreadSpawn(tv_receivenfq) != 0) {
if (TmThreadSpawn(tv_receivepcap) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
#ifdef MANY_THREADS
ThreadVars *tv_decode1 = TmThreadCreate("Decode1","pickup-queue","simple","decode-queue1","simple","1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
tm_module = TmModuleGetByName("DecodePcap");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName DecodePcap failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_decode1,tm_module,NULL);
@ -289,24 +236,24 @@ int main(int argc, char **argv)
exit(1);
}
ThreadVars *tv_decode2 = TmThreadCreate("Decode2","pickup-queue","simple","decode-queue2","simple","1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
ThreadVars *tv_stream1 = TmThreadCreate("Stream1","decode-queue1","simple","stream-queue1","simple","1slot");
if (tv_stream1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Stream1\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
tm_module = TmModuleGetByName("StreamTcp");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName StreamTcp failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_decode2,tm_module,NULL);
Tm1SlotSetFunc(tv_stream1,tm_module,NULL);
if (TmThreadSpawn(tv_decode2) != 0) {
if (TmThreadSpawn(tv_stream1) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
ThreadVars *tv_detect1 = TmThreadCreate("Detect1","decode-queue1","simple","verdict-queue","simple","1slot");
ThreadVars *tv_detect1 = TmThreadCreate("Detect1","stream-queue1","simple","verdict-queue","simple","1slot");
if (tv_detect1 == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
@ -323,8 +270,8 @@ int main(int argc, char **argv)
exit(1);
}
ThreadVars *tv_detect2 = TmThreadCreate("Detect2","decode-queue2","simple","verdict-queue","simple","1slot");
if (tv_detect1 == NULL) {
ThreadVars *tv_detect2 = TmThreadCreate("Detect2","stream-queue1","simple","verdict-queue","simple","1slot");
if (tv_detect2 == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
@ -340,24 +287,7 @@ int main(int argc, char **argv)
exit(1);
}
ThreadVars *tv_verdict = TmThreadCreate("Verdict","verdict-queue","simple","respond-queue","simple","1slot");
if (tv_verdict == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_verdict,tm_module,NULL);
if (TmThreadSpawn(tv_verdict) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
ThreadVars *tv_rreject = TmThreadCreate("RespondReject","respond-queue","simple","alert-queue1","simple","1slot");
ThreadVars *tv_rreject = TmThreadCreate("RespondReject","verdict-queue","simple","alert-queue1","simple","1slot");
if (tv_rreject == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
@ -398,7 +328,6 @@ int main(int argc, char **argv)
exit(1);
}
//ThreadVars *tv_unified = TmThreadCreate("AlertUnifiedLog","alert-queue2","simple","packetpool","packetpool","2slot");
ThreadVars *tv_unified = TmThreadCreate("AlertUnifiedLog","alert-queue2","simple","alert-queue3","simple","2slot");
if (tv_unified == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
@ -442,352 +371,294 @@ int main(int argc, char **argv)
exit(1);
}
#else /* MANY_THREADS */
ThreadVars *tv_main = TmThreadCreate("MainThread","pickup-queue","simple","packetpool","packetpool","varslot");
if (tv_main == NULL) {
printf("ERROR: TmThreadsCreate failed for MainThread\n");
return 0;
}
int RunModeIpsNFQ(void) {
TimeModeSetLive();
/* create the threads */
ThreadVars *tv_receivenfq = TmThreadCreate("ReceiveNFQ","packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receivenfq == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
TmModule *tm_module = TmModuleGetByName("ReceiveNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module,NULL);
Tm1SlotSetFunc(tv_receivenfq,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName Detect failed\n");
if (TmThreadSpawn(tv_receivenfq) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module,(void *)g_de_ctx);
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module,NULL);
/*
tm_module = TmModuleGetByName("RespondReject");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for RespondReject failed\n");
ThreadVars *tv_decode1 = TmThreadCreate("Decode1","pickup-queue","simple","decode-queue1","simple","1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
tm_module = TmModuleGetByName("AlertFastlog");
tm_module = TmModuleGetByName("DecodeNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for AlertFastlog failed\n");
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
Tm1SlotSetFunc(tv_decode1,tm_module,NULL);
tm_module = TmModuleGetByName("LogHttplog");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed\n");
if (TmThreadSpawn(tv_decode1) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
tm_module = TmModuleGetByName("AlertUnifiedLog");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n");
ThreadVars *tv_stream1 = TmThreadCreate("Stream1","decode-queue1","simple","stream-queue1","simple","1slot");
if (tv_stream1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Stream1\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
tm_module = TmModuleGetByName("AlertUnifiedAlert");
tm_module = TmModuleGetByName("StreamTcp");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n");
printf("ERROR: TmModuleGetByName StreamTcp failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
Tm1SlotSetFunc(tv_stream1,tm_module,NULL);
tm_module = TmModuleGetByName("AlertDebuglog");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
*/
if (TmThreadSpawn(tv_main) != 0) {
if (TmThreadSpawn(tv_stream1) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
#endif /* MANY_THREADS */
#else /* PERF_THREADS */
#if 0
/* create the threads */
ThreadVars *tv_receivenfq = TmThreadCreate("ReceiveNFQ1","packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receivenfq == NULL) {
ThreadVars *tv_detect1 = TmThreadCreate("Detect1","stream-queue1","simple","verdict-queue","simple","1slot");
if (tv_detect1 == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
TmModule *tm_module = TmModuleGetByName("ReceiveNFQ");
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
printf("ERROR: TmModuleGetByName Detect failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_receivenfq,tm_module);
Tm1SlotSetFunc(tv_detect1,tm_module,(void *)g_de_ctx);
if (TmThreadSpawn(tv_receivenfq) != 0) {
if (TmThreadSpawn(tv_detect1) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
ThreadVars *tv_decode1 = TmThreadCreate("Decode1","pickup-queue","simple","verdict-queue","simple","2slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
ThreadVars *tv_detect2 = TmThreadCreate("Detect2","stream-queue1","simple","verdict-queue","simple","1slot");
if (tv_detect2 == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
Tm2SlotSetFunc1(tv_decode1,tm_module);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName Detect failed\n");
exit(1);
}
Tm2SlotSetFunc2(tv_decode1,tm_module);
TmThreadSetCPUAffinity(tv_decode1,0);
Tm1SlotSetFunc(tv_detect2,tm_module,(void *)g_de_ctx);
if (TmThreadSpawn(tv_decode1) != 0) {
if (TmThreadSpawn(tv_detect2) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
ThreadVars *tv_decode2 = TmThreadCreate("Decode2","pickup-queue","simple","verdict-queue","simple","2slot");
if (tv_decode2 == NULL) {
ThreadVars *tv_verdict = TmThreadCreate("Verdict","verdict-queue","simple","respond-queue","simple","1slot");
if (tv_verdict == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
Tm2SlotSetFunc1(tv_decode2,tm_module);
tm_module = TmModuleGetByName("Detect");
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
exit(1);
}
Tm2SlotSetFunc2(tv_decode2,tm_module);
TmThreadSetCPUAffinity(tv_decode2,1);
Tm1SlotSetFunc(tv_verdict,tm_module,NULL);
if (TmThreadSpawn(tv_decode2) != 0) {
if (TmThreadSpawn(tv_verdict) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
/*
ThreadVars *tv_decode3 = TmThreadCreate("Decode3","pickup-queue","simple","verdict-queue","simple","2slot");
if (tv_decode3 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
ThreadVars *tv_rreject = TmThreadCreate("RespondReject","respond-queue","simple","alert-queue1","simple","1slot");
if (tv_rreject == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
Tm2SlotSetFunc1(tv_decode3,tm_module);
tm_module = TmModuleGetByName("Detect");
tm_module = TmModuleGetByName("RespondReject");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName for RespondReject failed\n");
exit(1);
}
Tm2SlotSetFunc2(tv_decode3,tm_module);
TmThreadSetCPUAffinity(tv_decode3,0);
Tm1SlotSetFunc(tv_rreject,tm_module,NULL);
if (TmThreadSpawn(tv_decode3) != 0) {
if (TmThreadSpawn(tv_rreject) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
ThreadVars *tv_decode4 = TmThreadCreate("Decode4","pickup-queue","simple","verdict-queue","simple","2slot");
if (tv_decode4 == NULL) {
ThreadVars *tv_alert = TmThreadCreate("AlertFastlog&Httplog","alert-queue1","simple","alert-queue2","simple","2slot");
if (tv_alert == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
tm_module = TmModuleGetByName("AlertFastlog");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName for AlertFastlog failed\n");
exit(1);
}
Tm2SlotSetFunc1(tv_decode4,tm_module);
Tm2SlotSetFunc1(tv_alert,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
tm_module = TmModuleGetByName("LogHttplog");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName failed\n");
exit(1);
}
Tm2SlotSetFunc2(tv_decode4,tm_module);
TmThreadSetCPUAffinity(tv_decode4,1);
Tm2SlotSetFunc2(tv_alert,tm_module,NULL);
if (TmThreadSpawn(tv_decode4) != 0) {
if (TmThreadSpawn(tv_alert) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
*/
//ThreadVars *tv_verdict = TmThreadCreate("Verdict","verdict-queue","simple","respond-queue","simple","1slot");
ThreadVars *tv_verdict = TmThreadCreate("Verdict","verdict-queue","simple","packetpool","packetpool","1slot");
if (tv_verdict == NULL) {
ThreadVars *tv_unified = TmThreadCreate("AlertUnifiedLog","alert-queue2","simple","alert-queue3","simple","2slot");
if (tv_unified == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
tm_module = TmModuleGetByName("VerdictNFQ");
tm_module = TmModuleGetByName("AlertUnifiedLog");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_verdict,tm_module);
Tm2SlotSetFunc1(tv_unified,tm_module,NULL);
if (TmThreadSpawn(tv_verdict) != 0) {
tm_module = TmModuleGetByName("AlertUnifiedAlert");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n");
exit(1);
}
Tm2SlotSetFunc2(tv_unified,tm_module,NULL);
if (TmThreadSpawn(tv_unified) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
#endif
/* create the threads */
ThreadVars *tv_receivenfq = TmThreadCreate("ReceiveNFQ1","packetpool","packetpool","pickup-queue1","simple","1slot_noinout");
if (tv_receivenfq == NULL) {
ThreadVars *tv_debugalert = TmThreadCreate("AlertDebuglog","alert-queue3","simple","packetpool","packetpool","1slot");
if (tv_debugalert == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
TmModule *tm_module = TmModuleGetByName("ReceiveNFQ");
tm_module = TmModuleGetByName("AlertDebuglog");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
printf("ERROR: TmModuleGetByName failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_receivenfq,tm_module,NULL);
TmThreadSetCPUAffinity(tv_receivenfq,0);
Tm1SlotSetFunc(tv_debugalert,tm_module,NULL);
if (TmThreadSpawn(tv_receivenfq) != 0) {
if (TmThreadSpawn(tv_debugalert) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
/* wait for queue 0 to settle */
sleep(1);
return 0;
}
int RunModeFilePcap(char *file) {
printf("RunModeFilePcap: file %s\n", file);
TimeModeSetNonlive();
/* create the threads */
ThreadVars *tv_receivenfq2 = TmThreadCreate("ReceiveNFQ2","packetpool","packetpool","pickup-queue2","simple","1slot_noinout");
if (tv_receivenfq2 == NULL) {
ThreadVars *tv_receivepcap = TmThreadCreate("ReceivePcapFile","packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receivepcap == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
tm_module = TmModuleGetByName("ReceiveNFQ");
TmModule *tm_module = TmModuleGetByName("ReceivePcapFile");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
printf("ERROR: TmModuleGetByName failed for ReceivePcap\n");
exit(1);
}
Tm1SlotSetFunc(tv_receivenfq2,tm_module,NULL);
TmThreadSetCPUAffinity(tv_receivenfq2,1);
Tm1SlotSetFunc(tv_receivepcap,tm_module,file);
if (TmThreadSpawn(tv_receivenfq2) != 0) {
if (TmThreadSpawn(tv_receivepcap) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
sleep(1);
ThreadVars *tv_decode1 = TmThreadCreate("Decode1","pickup-queue1","simple","packetpool","packetpool","3slot");
ThreadVars *tv_decode1 = TmThreadCreate("Decode1","pickup-queue","simple","decode-queue1","simple","1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
tm_module = TmModuleGetByName("DecodePcapFile");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
printf("ERROR: TmModuleGetByName DecodePcap failed\n");
exit(1);
}
Tm3SlotSetFunc1(tv_decode1,tm_module,NULL);
Tm1SlotSetFunc(tv_decode1,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
if (TmThreadSpawn(tv_decode1) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
Tm3SlotSetFunc2(tv_decode1,tm_module,(void *)g_de_ctx);
tm_module = TmModuleGetByName("VerdictNFQ");
//#if 0
ThreadVars *tv_stream1 = TmThreadCreate("Stream1","decode-queue1","simple","stream-queue1","simple","1slot");
if (tv_stream1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Stream1\n");
exit(1);
}
tm_module = TmModuleGetByName("StreamTcp");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
printf("ERROR: TmModuleGetByName StreamTcp failed\n");
exit(1);
}
Tm3SlotSetFunc3(tv_decode1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode1,0);
Tm1SlotSetFunc(tv_stream1,tm_module,NULL);
if (TmThreadSpawn(tv_decode1) != 0) {
if (TmThreadSpawn(tv_stream1) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
sleep(1);
ThreadVars *tv_decode2 = TmThreadCreate("Decode2","pickup-queue2","simple","packetpool","packetpool","3slot");
if (tv_decode2 == NULL) {
ThreadVars *tv_detect1 = TmThreadCreate("Detect1","stream-queue1","simple","packetpool","packetpool","1slot");
//#endif
//ThreadVars *tv_detect1 = TmThreadCreate("Detect1","decode-queue1","simple","packetpool","packetpool","1slot");
if (tv_detect1 == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
tm_module = TmModuleGetByName("DecodeNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
Tm3SlotSetFunc1(tv_decode2,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
Tm3SlotSetFunc2(tv_decode2,tm_module,(void *)g_de_ctx);
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
printf("ERROR: TmModuleGetByName Detect failed\n");
exit(1);
}
Tm3SlotSetFunc3(tv_decode2,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode2,1);
Tm1SlotSetFunc(tv_detect1,tm_module,(void *)g_de_ctx);
if (TmThreadSpawn(tv_decode2) != 0) {
if (TmThreadSpawn(tv_detect1) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
/*
//ThreadVars *tv_verdict = TmThreadCreate("Verdict","verdict-queue","simple","respond-queue","simple","1slot");
ThreadVars *tv_verdict = TmThreadCreate("Verdict","verdict-queue","simple","packetpool","packetpool","1slot");
if (tv_verdict == NULL) {
ThreadVars *tv_detect2 = TmThreadCreate("Detect2","stream-queue1","simple","packetpool","packetpool","1slot");
if (tv_detect2 == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(1);
}
tm_module = TmModuleGetByName("VerdictNFQ");
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
printf("ERROR: TmModuleGetByName Detect failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_verdict,tm_module);
Tm1SlotSetFunc(tv_detect2,tm_module,(void *)g_de_ctx);
if (TmThreadSpawn(tv_verdict) != 0) {
if (TmThreadSpawn(tv_detect2) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
*/
/*
ThreadVars *tv_rreject = TmThreadCreate("RespondReject","respond-queue","simple","alert-queue1","simple","1slot");
if (tv_rreject == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
@ -798,7 +669,7 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName for RespondReject failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_rreject,tm_module);
Tm1SlotSetFunc(tv_rreject,tm_module,NULL);
if (TmThreadSpawn(tv_rreject) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
@ -815,21 +686,20 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName for AlertFastlog failed\n");
exit(1);
}
Tm2SlotSetFunc1(tv_alert,tm_module);
Tm2SlotSetFunc1(tv_alert,tm_module,NULL);
tm_module = TmModuleGetByName("LogHttplog");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed\n");
exit(1);
}
Tm2SlotSetFunc2(tv_alert,tm_module);
Tm2SlotSetFunc2(tv_alert,tm_module,NULL);
if (TmThreadSpawn(tv_alert) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
//ThreadVars *tv_unified = TmThreadCreate("AlertUnifiedLog","alert-queue2","simple","packetpool","packetpool","2slot");
ThreadVars *tv_unified = TmThreadCreate("AlertUnifiedLog","alert-queue2","simple","alert-queue3","simple","2slot");
if (tv_unified == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
@ -841,21 +711,20 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n");
exit(1);
}
Tm2SlotSetFunc1(tv_unified,tm_module);
Tm2SlotSetFunc1(tv_unified,tm_module,NULL);
tm_module = TmModuleGetByName("AlertUnifiedAlert");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n");
exit(1);
}
Tm2SlotSetFunc2(tv_unified,tm_module);
Tm2SlotSetFunc2(tv_unified,tm_module,NULL);
if (TmThreadSpawn(tv_unified) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
ThreadVars *tv_debugalert = TmThreadCreate("AlertDebuglog","alert-queue3","simple","packetpool","packetpool","1slot");
if (tv_debugalert == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
@ -866,14 +735,121 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName failed\n");
exit(1);
}
Tm1SlotSetFunc(tv_debugalert,tm_module);
Tm1SlotSetFunc(tv_debugalert,tm_module,NULL);
if (TmThreadSpawn(tv_debugalert) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
*/
#endif /* PERF_THREADS */
return 0;
}
int main(int argc, char **argv)
{
int rc;
sigset_t set;
sigaddset(&set, SIGINT);
/* registering signals we use */
setup_signal_handler(SIGINT, handle_sigint);
setup_signal_handler(SIGTERM, handle_sigterm);
setup_signal_handler(SIGHUP, handle_sighup);
//pthread_sigmask(SIG_BLOCK, &set, 0);
/* create table for O(1) lowercase conversion lookup */
u_int8_t c = 0;
for ( ; c < 255; c++) {
if (c >= 'A' && c <= 'Z')
g_u8_lowercasetable[c] = (c + ('a' - 'A'));
else
g_u8_lowercasetable[c] = c;
}
/* hardcoded initialization code */
MpmTableSetup(); /* load the pattern matchers */
SigTableSetup(); /* load the rule keywords */
TmqhSetup();
BinSearchInit();
CIDRInit();
SigParsePrepare();
PatternMatchPrepare(mpm_ctx);
TmModuleReceiveNFQRegister();
TmModuleVerdictNFQRegister();
TmModuleDecodeNFQRegister();
TmModuleReceivePcapRegister();
TmModuleDecodePcapRegister();
TmModuleReceivePcapFileRegister();
TmModuleDecodePcapFileRegister();
TmModuleDetectRegister();
TmModuleAlertFastlogRegister();
TmModuleAlertDebuglogRegister();
TmModuleRespondRejectRegister();
TmModuleAlertFastlogIPv4Register();
TmModuleAlertFastlogIPv6Register();
TmModuleAlertUnifiedLogRegister();
TmModuleAlertUnifiedAlertRegister();
TmModuleLogHttplogRegister();
TmModuleLogHttplogIPv4Register();
TmModuleLogHttplogIPv6Register();
TmModuleStreamTcpRegister();
TmModuleDebugList();
/* test and initialize the unittesting subsystem */
UtRunSelftest(); /* inits and cleans up again */
UtInitialize();
TmModuleRegisterTests();
SigTableRegisterTests();
HashTableRegisterTests();
HashListTableRegisterTests();
BloomFilterRegisterTests();
BloomFilterCountingRegisterTests();
PoolRegisterTests();
MpmRegisterTests();
FlowBitRegisterTests();
SigRegisterTests();
//UtRunTests();
UtCleanup();
//exit(1);
//LoadConfig();
//exit(1);
/* initialize packet queues */
memset(&packet_q,0,sizeof(packet_q));
memset(&trans_q, 0,sizeof(trans_q));
/* pre allocate packets */
printf("Preallocating packets... packet size %u\n", sizeof(Packet));
int i = 0;
for (i = 0; i < MAX_PENDING; i++) {
/* XXX pkt alloc function */
Packet *p = malloc(sizeof(Packet));
if (p == NULL) {
printf("ERROR: malloc failed: %s\n", strerror(errno));
exit(1);
}
memset(p, 0, sizeof(Packet));
PacketEnqueue(&packet_q,p);
}
printf("Preallocating packets... done\n");
FlowInitConfig();
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
SigLoadSignatures();
struct timeval start_time;
memset(&start_time, 0, sizeof(start_time));
gettimeofday(&start_time, NULL);
//RunModeIpsNFQ();
//RunModeIdsPcap(argv[1]);
RunModeFilePcap(argv[1]);
ThreadVars tv_flowmgr;
memset(&tv_flowmgr, 0, sizeof(ThreadVars));
@ -891,10 +867,38 @@ int main(int argc, char **argv)
if (sigflags) {
printf("signal received\n");
if (sigflags & VIPS_SIGINT) printf ("SIGINT\n");
if (sigflags & VIPS_SIGINT || sigflags & VIPS_STOP) {
printf ("SIGINT or EngineStop received\n");
/* Stop the engine so it quits after processing the pcap file
* but first make sure all packets are processed by all other
* threads. */
char done = 0;
do {
if (sigflags & VIPS_SIGTERM || sigflags & VIPS_KILL)
break;
mutex_lock(&mutex_pending);
if (pending == 0)
done = 1;
mutex_unlock(&mutex_pending);
if (done == 0) {
usleep(100);
}
} while (done == 0);
printf("main: all packets processed by threads, stopping engine\n");
}
if (sigflags & VIPS_SIGHUP) printf ("SIGHUP\n");
if (sigflags & VIPS_SIGTERM) printf ("SIGTERM\n");
struct timeval end_time;
memset(&end_time, 0, sizeof(end_time));
gettimeofday(&end_time, NULL);
printf("time elapsed %lus\n", end_time.tv_sec - start_time.tv_sec);
TmThreadKillThreads();
#if 0
#ifdef DBG_PERF
@ -918,7 +922,7 @@ int main(int argc, char **argv)
break;//pthread_exit(NULL);
}
sleep(1);
usleep(100);
}
FlowShutdown();

@ -14,7 +14,7 @@
/* maximum number of simultanious threads. */
#define NUM_THREADS 256
/* max packets processed simultaniously */
#define MAX_PENDING 512
#define MAX_PENDING 50
#define TRUE 1
#define FALSE 0

Loading…
Cancel
Save