app layer probing parser updates

remotes/origin/master-1.1.x
Anoop Saldanha 14 years ago committed by Victor Julien
parent d68f182ebd
commit 432c3317d2

@ -247,6 +247,9 @@ void AlpProtoTestDestroy(AlpProtoDetectCtx *ctx) {
mpm_table[ctx->toclient.mpm_ctx.mpm_type].DestroyCtx(&ctx->toclient.mpm_ctx);
AlpProtoFreeSignature(ctx->head);
AppLayerFreeProbingParsers(ctx->probing_parsers);
ctx->probing_parsers = NULL;
AppLayerFreeProbingParsersInfo(ctx->probing_parsers_info);
ctx->probing_parsers_info = NULL;
}
#endif
@ -256,6 +259,9 @@ void AlpProtoDestroy() {
mpm_table[alp_proto_ctx.toclient.mpm_ctx.mpm_type].DestroyCtx(&alp_proto_ctx.toclient.mpm_ctx);
MpmPatternIdTableFreeHash(alp_proto_ctx.mpm_pattern_id_store);
AppLayerFreeProbingParsers(alp_proto_ctx.probing_parsers);
alp_proto_ctx.probing_parsers = NULL;
AppLayerFreeProbingParsersInfo(alp_proto_ctx.probing_parsers_info);
alp_proto_ctx.probing_parsers_info = NULL;
SCReturn;
}
@ -515,9 +521,11 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
AppLayerProbingParserElement *pe = NULL;
AppLayerProbingParser *probing_parsers = ctx->probing_parsers;
AppLayerProbingParser *pp = NULL;
uint16_t *al_proto_masks;
if (flags & STREAM_TOSERVER) {
pp = AppLayerGetProbingParsers(probing_parsers, ipproto, f->dp);
al_proto_masks = &f->probing_parser_toserver_al_proto_masks;
if (pp == NULL) {
SCLogDebug("toserver-No probing parser registered for port %"PRIu16,
f->dp);
@ -528,17 +536,10 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
f->flags |= FLOW_TS_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
if (pp->toserver_max_depth != 0 && buflen > pp->toserver_max_depth) {
if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) {
f->flags |= FLOW_TS_PM_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
f->flags |= FLOW_TS_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
pe = pp->toserver;
} else {
pp = AppLayerGetProbingParsers(probing_parsers, ipproto, f->sp);
al_proto_masks = &f->probing_parser_toclient_al_proto_masks;
if (pp == NULL) {
SCLogDebug("toclient-No probing parser registered for port %"PRIu16,
f->sp);
@ -549,31 +550,46 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
f->flags |= FLOW_TC_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
if (pp->toclient_max_depth != 0 && buflen > pp->toclient_max_depth) {
if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) {
f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
f->flags |= FLOW_TC_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
pe = pp->toclient;
}
while (pe != NULL) {
if (buflen < pe->min_depth ||
(pe->max_depth != 0 && buflen > pe->max_depth)) {
if ((buflen < pe->min_depth) ||
al_proto_masks[0] & pe->al_proto_mask) {
pe = pe->next;
continue;
}
uint16_t alproto = pe->ProbingParser(buf, buflen);
if (alproto != ALPROTO_UNKNOWN)
int alproto = pe->ProbingParser(buf, buflen);
if (alproto > ALPROTO_UNKNOWN)
return alproto;
if (alproto == -1 || (pe->max_depth != 0 && buflen > pe->max_depth)) {
al_proto_masks[0] |= pe->al_proto_mask;
}
pe = pe->next;
}
if (flags & STREAM_TOSERVER) {
if (al_proto_masks[0] == pp->toserver_al_proto_mask) {
if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) {
f->flags |= FLOW_TS_PM_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
f->flags |= FLOW_TS_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
} else {
if (al_proto_masks[0] == pp->toclient_al_proto_mask) {
if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) {
f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
f->flags |= FLOW_TC_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
}
return ALPROTO_UNKNOWN;
}

@ -74,6 +74,7 @@ typedef struct AlpProtoDetectCtx_ {
AlpProtoSignature *head; /**< list of sigs */
AppLayerProbingParser *probing_parsers;
AppLayerProbingParserInfo *probing_parsers_info;
uint16_t sigs; /**< number of sigs */
} AlpProtoDetectCtx;

File diff suppressed because it is too large Load Diff

@ -139,14 +139,16 @@ typedef struct AppLayerProbingParserElement_ {
const char *al_proto_name;
uint16_t al_proto;
uint16_t port;
uint16_t ip_proto;
uint8_t priority;
uint8_t top;
uint16_t al_proto_mask;
/* the min length of data that has to be supplied to invoke the parser */
uint32_t min_depth;
/* the max length of data after which this parser won't be invoked */
uint32_t max_depth;
/* the probing parser function */
uint16_t (*ProbingParser)(uint8_t *input, uint32_t input_len);
int16_t (*ProbingParser)(uint8_t *input, int32_t input_len);
struct AppLayerProbingParserElement_ *next;
} AppLayerProbingParserElement;
@ -154,6 +156,8 @@ typedef struct AppLayerProbingParserElement_ {
typedef struct AppLayerProbingParser_ {
/* the port no for which probing parser(s) are invoked */
uint16_t port;
uint16_t toserver_al_proto_mask;
uint16_t toclient_al_proto_mask;
/* the max depth for all the probing parsers registered for this port */
uint16_t toserver_max_depth;
uint16_t toclient_max_depth;
@ -164,6 +168,14 @@ typedef struct AppLayerProbingParser_ {
struct AppLayerProbingParser_ *next;
} AppLayerProbingParser;
typedef struct AppLayerProbingParserInfo_ {
const char *al_proto_name;
uint16_t ip_proto;
uint16_t al_proto;
int16_t (*ProbingParser)(uint8_t *input, int32_t input_len);
struct AppLayerProbingParserInfo_ *next;
} AppLayerProbingParserInfo;
#define APP_LAYER_PROBING_PARSER_PRIORITY_HIGH 1
#define APP_LAYER_PROBING_PARSER_PRIORITY_MEDIUM 2
#define APP_LAYER_PROBING_PARSER_PRIORITY_LOW 3
@ -178,7 +190,7 @@ AppLayerProbingParser *AppLayerGetProbingParsers(AppLayerProbingParser *probing_
AppLayerProbingParser *pp = probing_parsers;
while (pp != NULL) {
if (pp->port == port) {
if (pp->port == port || pp->port == 0) {
break;
}
pp = pp->next;
@ -187,6 +199,19 @@ AppLayerProbingParser *AppLayerGetProbingParsers(AppLayerProbingParser *probing_
return pp;
}
static inline
AppLayerProbingParserInfo *AppLayerGetProbingParserInfo(AppLayerProbingParserInfo *ppi,
const char *al_proto_name)
{
while (ppi != NULL) {
if (strcmp(ppi->al_proto_name, al_proto_name) == 0)
return ppi;
ppi = ppi->next;
}
return NULL;
}
struct AlpProtoDetectCtx_;
/* prototypes */
@ -205,8 +230,8 @@ int AppLayerRegisterParser(char *name, uint16_t proto, uint16_t parser_id,
void AppLayerRegisterProbingParser(struct AlpProtoDetectCtx_ *, uint16_t, uint16_t,
const char *, uint16_t,
uint16_t, uint16_t, uint8_t, uint8_t,
uint8_t, uint16_t (*ProbingParser)
(uint8_t *, uint32_t));
uint8_t,
int16_t (*ProbingParser)(uint8_t *, int32_t));
void AppLayerRegisterStateFuncs(uint16_t proto, void *(*StateAlloc)(void),
void (*StateFree)(void *));
void AppLayerRegisterTransactionIdFuncs(uint16_t proto,
@ -243,8 +268,9 @@ void AppLayerParserCleanupState(Flow *);
uint8_t AppLayerRegisterModule(void);
uint8_t AppLayerGetStorageSize(void);
void AppLayerFreeProbingParsers(AppLayerProbingParser *);
void AppLayerFreeProbingParsersInfo(AppLayerProbingParserInfo *);
void AppLayerPrintProbingParsers(AppLayerProbingParser *);
uint16_t AppLayerGetStateVersion(Flow *f);
#endif /* __APP_LAYER_PARSER_H__ */

@ -38,6 +38,7 @@ enum {
ALPROTO_SMB2,
ALPROTO_DCERPC,
ALPROTO_DCERPC_UDP,
ALPROTO_IRC,
#ifdef UNITTESTS
ALPROTO_TEST,
#endif /* UNITESTS */

@ -1328,9 +1328,9 @@ void SMBUpdateTransactionId(void *state, uint16_t *id) {
#define SMB_PROBING_PARSER_MIN_DEPTH 8
static uint16_t SMBProbingParser(uint8_t *input, uint32_t input_len)
static int16_t SMBProbingParser(uint8_t *input, int32_t input_len)
{
uint32_t len;
int32_t len;
while (input_len >= SMB_PROBING_PARSER_MIN_DEPTH) {
switch (input[0]) {
@ -1350,7 +1350,10 @@ static uint16_t SMBProbingParser(uint8_t *input, uint32_t input_len)
len |= input[3];
break;
default:
return ALPROTO_UNKNOWN;
/* -1 indicates a stream where the probing parser would be
* unable to find nbss, even if it exists. This should
* prevent the probing parser from beig invoked henceforth */
return -1;
}
input_len -= 4;

@ -786,6 +786,16 @@ int SigParseProto(Signature *s, const char *protostr) {
}
SCReturnInt(0);
}
AppLayerProbingParserInfo *ppi =
AppLayerGetProbingParserInfo(alp_proto_ctx.probing_parsers_info,
protostr);
if (ppi != NULL) {
/* indicate that the signature is app-layer */
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ppi->al_proto;
s->proto.proto[ppi->ip_proto / 8] |= 1 << (ppi->ip_proto % 8);
SCReturnInt(0);
}
SCLogError(SC_ERR_UNKNOWN_PROTOCOL, "protocol \"%s\" cannot be used "
"in a signature", protostr);

@ -47,6 +47,8 @@
SCMutexInit(&(f)->m, NULL); \
(f)->protoctx = NULL; \
(f)->alproto = 0; \
(f)->probing_parser_toserver_al_proto_masks = 0; \
(f)->probing_parser_toclient_al_proto_masks = 0; \
(f)->aldata = NULL; \
(f)->de_state = NULL; \
(f)->sgh_toserver = NULL; \
@ -75,6 +77,8 @@
(f)->protoctx = NULL; \
FlowL7DataPtrFree(f); \
(f)->alproto = 0; \
(f)->probing_parser_toserver_al_proto_masks = 0; \
(f)->probing_parser_toclient_al_proto_masks = 0; \
if ((f)->de_state != NULL) { \
DetectEngineStateReset((f)->de_state); \
} \

@ -174,6 +174,9 @@ typedef struct Flow_
*/
SC_ATOMIC_DECLARE(unsigned short, use_cnt);
uint16_t probing_parser_toserver_al_proto_masks;
uint16_t probing_parser_toclient_al_proto_masks;
uint32_t flags;
/* ts of flow init and last update */

Loading…
Cancel
Save