|
|
@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
/* Copyright (c) 2009 Victor Julien */
|
|
|
|
|
|
|
|
|
|
|
|
#include "eidps.h"
|
|
|
|
#include "eidps.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "decode.h"
|
|
|
|
#include "decode.h"
|
|
|
@ -16,12 +18,9 @@
|
|
|
|
#define PROTO_FTP 2
|
|
|
|
#define PROTO_FTP 2
|
|
|
|
#define PROTO_SMTP 3
|
|
|
|
#define PROTO_SMTP 3
|
|
|
|
|
|
|
|
|
|
|
|
#define TYPE_PROTO 0
|
|
|
|
static u_int8_t l7_proto_id = 0;
|
|
|
|
#define TYPE_BUF 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* XXX type can be 1 bit, 7 bit for proto */
|
|
|
|
|
|
|
|
typedef struct _L7AppDetectDataProto {
|
|
|
|
typedef struct _L7AppDetectDataProto {
|
|
|
|
u_int8_t type;
|
|
|
|
|
|
|
|
u_int8_t proto;
|
|
|
|
u_int8_t proto;
|
|
|
|
} L7AppDetectDataProto;
|
|
|
|
} L7AppDetectDataProto;
|
|
|
|
|
|
|
|
|
|
|
@ -33,15 +32,14 @@ void *L7AppDetectProtoAlloc(void *null) {
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
d->type = TYPE_PROTO;
|
|
|
|
|
|
|
|
d->proto = PROTO_UNKNOWN;
|
|
|
|
d->proto = PROTO_UNKNOWN;
|
|
|
|
return d;
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#define L7AppDetectProtoFree free
|
|
|
|
#define L7AppDetectProtoFree free
|
|
|
|
|
|
|
|
|
|
|
|
void L7AppDetectThreadInit(void) {
|
|
|
|
void L7AppDetectThreadInit(void) {
|
|
|
|
/* allocate 2 pools, 1 for proto objects, 1 for bufs. Normal stream will
|
|
|
|
l7_proto_id = StreamL7RegisterModule();
|
|
|
|
* jump straigth to protos so we alloc a lot less bufs */
|
|
|
|
|
|
|
|
l7appdetect_proto_pool = PoolInit(262144, 32768, L7AppDetectProtoAlloc, NULL, L7AppDetectProtoFree);
|
|
|
|
l7appdetect_proto_pool = PoolInit(262144, 32768, L7AppDetectProtoAlloc, NULL, L7AppDetectProtoFree);
|
|
|
|
if (l7appdetect_proto_pool == NULL) {
|
|
|
|
if (l7appdetect_proto_pool == NULL) {
|
|
|
|
exit(1);
|
|
|
|
exit(1);
|
|
|
@ -61,17 +59,17 @@ void *L7AppDetectThread(void *td)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ThreadVars *tv = (ThreadVars *)td;
|
|
|
|
ThreadVars *tv = (ThreadVars *)td;
|
|
|
|
char run = TRUE;
|
|
|
|
char run = TRUE;
|
|
|
|
u_int8_t l7_data_id = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* get the stream msg queue for this thread */
|
|
|
|
/* get the stream msg queue for this thread */
|
|
|
|
StreamMsgQueue *stream_q = StreamMsgQueueGetByPort(0);
|
|
|
|
StreamMsgQueue *stream_q = StreamMsgQueueGetByPort(0);
|
|
|
|
StreamMsgQueueSetMinInitChunkLen(stream_q, INSPECT_BYTES);
|
|
|
|
/* set the minimum size we expect */
|
|
|
|
|
|
|
|
StreamMsgQueueSetMinInitChunkLen(stream_q, FLOW_PKT_TOSERVER, INSPECT_BYTES);
|
|
|
|
|
|
|
|
StreamMsgQueueSetMinInitChunkLen(stream_q, FLOW_PKT_TOCLIENT, INSPECT_BYTES);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* main loop */
|
|
|
|
while(run) {
|
|
|
|
while(run) {
|
|
|
|
/* grab a msg, can return NULL on signals */
|
|
|
|
/* grab a msg, can return NULL on signals */
|
|
|
|
StreamMsg *smsg = StreamMsgGetFromQueue(stream_q);
|
|
|
|
StreamMsg *smsg = StreamMsgGetFromQueue(stream_q);
|
|
|
|
//printf("L7AppDetectThread: smsg %p\n", smsg);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (smsg != NULL) {
|
|
|
|
if (smsg != NULL) {
|
|
|
|
/* keep the flow locked during operation.
|
|
|
|
/* keep the flow locked during operation.
|
|
|
|
* XXX we may be better off adding a mutex
|
|
|
|
* XXX we may be better off adding a mutex
|
|
|
@ -81,10 +79,11 @@ void *L7AppDetectThread(void *td)
|
|
|
|
TcpSession *ssn = smsg->flow->stream;
|
|
|
|
TcpSession *ssn = smsg->flow->stream;
|
|
|
|
if (ssn != NULL) {
|
|
|
|
if (ssn != NULL) {
|
|
|
|
if (ssn->l7data == NULL) {
|
|
|
|
if (ssn->l7data == NULL) {
|
|
|
|
StreamL7DataPtrInit(ssn,1); /* XXX we can use a pool here,
|
|
|
|
/* XXX we can use a pool here,
|
|
|
|
or make it part of the stream setup */
|
|
|
|
or make it part of the stream setup */
|
|
|
|
|
|
|
|
StreamL7DataPtrInit(ssn,StreamL7GetStorageSize());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void *l7_data_ptr = ssn->l7data[l7_data_id];
|
|
|
|
void *l7_data_ptr = ssn->l7data[l7_proto_id];
|
|
|
|
|
|
|
|
|
|
|
|
if (smsg->flags & STREAM_START) {
|
|
|
|
if (smsg->flags & STREAM_START) {
|
|
|
|
//printf("L7AppDetectThread: stream initializer (len %u (%u))\n", smsg->init.data_len, MSG_INIT_DATA_SIZE);
|
|
|
|
//printf("L7AppDetectThread: stream initializer (len %u (%u))\n", smsg->init.data_len, MSG_INIT_DATA_SIZE);
|
|
|
@ -96,15 +95,19 @@ void *L7AppDetectThread(void *td)
|
|
|
|
if (l7_data_ptr == NULL) {
|
|
|
|
if (l7_data_ptr == NULL) {
|
|
|
|
L7AppDetectDataProto *l7proto = (L7AppDetectDataProto *)PoolGet(l7appdetect_proto_pool);
|
|
|
|
L7AppDetectDataProto *l7proto = (L7AppDetectDataProto *)PoolGet(l7appdetect_proto_pool);
|
|
|
|
if (l7proto != NULL) {
|
|
|
|
if (l7proto != NULL) {
|
|
|
|
l7proto->type = TYPE_PROTO;
|
|
|
|
|
|
|
|
l7proto->proto = L7AppDetectGetProto(smsg->data.data, smsg->data.data_len);
|
|
|
|
l7proto->proto = L7AppDetectGetProto(smsg->data.data, smsg->data.data_len);
|
|
|
|
|
|
|
|
|
|
|
|
ssn->l7data[l7_data_id] = (void *)l7proto;
|
|
|
|
/* store */
|
|
|
|
|
|
|
|
ssn->l7data[l7_proto_id] = (void *)l7proto;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
//printf("L7AppDetectThread: stream data (len %u (%u))\n", smsg->data.data_len, MSG_DATA_SIZE);
|
|
|
|
//printf("L7AppDetectThread: stream data (len %u (%u))\n", smsg->data.data_len, MSG_DATA_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//printf("=> Stream Data -- start\n");
|
|
|
|
|
|
|
|
//PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len);
|
|
|
|
|
|
|
|
//printf("=> Stream Data -- end\n");
|
|
|
|
|
|
|
|
|
|
|
|
/* if we don't have a data object here we are not getting it
|
|
|
|
/* if we don't have a data object here we are not getting it
|
|
|
|
* a start msg should have gotten us one */
|
|
|
|
* a start msg should have gotten us one */
|
|
|
|
if (l7_data_ptr != NULL) {
|
|
|
|
if (l7_data_ptr != NULL) {
|
|
|
@ -113,13 +116,12 @@ void *L7AppDetectThread(void *td)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
printf("L7AppDetectThread: smsg not start, but no l7 data? Weird\n");
|
|
|
|
printf("L7AppDetectThread: smsg not start, but no l7 data? Weird\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//printf("=> Stream Data -- start\n");
|
|
|
|
|
|
|
|
//PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len);
|
|
|
|
|
|
|
|
//printf("=> Stream Data -- end\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mutex_unlock(&smsg->flow->m);
|
|
|
|
mutex_unlock(&smsg->flow->m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* return the used message to the queue */
|
|
|
|
StreamMsgReturnToPool(smsg);
|
|
|
|
StreamMsgReturnToPool(smsg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|