Now supports accepting port addresses as strings, like the ones accepted in our rules. As a consequence we now accept port range, and other such combination. Support PP for ports based on ipproto as well.

pull/567/head
Anoop Saldanha 12 years ago
parent 48b5513ed9
commit d9686fae57

@ -244,8 +244,8 @@ void AlpProtoTestDestroy(AlpProtoDetectCtx *ctx) {
AlpProtoFreeSignature(ctx->head);
AppLayerFreeProbingParsers(ctx->probing_parsers);
ctx->probing_parsers = NULL;
AppLayerFreeProbingParsersInfo(ctx->probing_parsers_info);
ctx->probing_parsers_info = NULL;
return;
}
#endif
@ -256,8 +256,7 @@ void AlpProtoDestroy() {
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;
}
@ -490,15 +489,14 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
uint8_t *buf, uint32_t buflen,
uint8_t flags, uint8_t ipproto)
{
AppLayerProbingParserPort *pp_port = NULL;
AppLayerProbingParserElement *pe = NULL;
AppLayerProbingParser *probing_parsers = ctx->probing_parsers;
AppLayerProbingParser *pp = NULL;
uint32_t *al_proto_masks;
if (flags & STREAM_TOSERVER) {
pp = AppLayerGetProbingParsers(probing_parsers, ipproto, f->dp);
pp_port = AppLayerGetProbingParsers(ctx->probing_parsers, ipproto, f->dp);
al_proto_masks = &f->probing_parser_toserver_al_proto_masks;
if (pp == NULL) {
if (pp_port == NULL) {
SCLogDebug("toserver-No probing parser registered for port %"PRIu16,
f->dp);
if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) {
@ -508,11 +506,11 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
f->flags |= FLOW_TS_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
pe = pp->toserver;
pe = pp_port->toserver;
} else {
pp = AppLayerGetProbingParsers(probing_parsers, ipproto, f->sp);
pp_port = AppLayerGetProbingParsers(ctx->probing_parsers, ipproto, f->sp);
al_proto_masks = &f->probing_parser_toclient_al_proto_masks;
if (pp == NULL) {
if (pp_port == NULL) {
SCLogDebug("toclient-No probing parser registered for port %"PRIu16,
f->sp);
if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) {
@ -522,7 +520,7 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
f->flags |= FLOW_TC_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN;
}
pe = pp->toclient;
pe = pp_port->toclient;
}
@ -533,7 +531,7 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
continue;
}
int alproto = pe->ProbingParser(buf, buflen);
int alproto = pe->ProbingParser(buf, buflen, NULL);
if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED)
return alproto;
if (alproto == ALPROTO_FAILED ||
@ -544,7 +542,7 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
}
if (flags & STREAM_TOSERVER) {
if (al_proto_masks[0] == pp->toserver_al_proto_mask) {
if (al_proto_masks[0] == pp_port->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;
@ -553,7 +551,7 @@ uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f,
return ALPROTO_UNKNOWN;
}
} else {
if (al_proto_masks[0] == pp->toclient_al_proto_mask) {
if (al_proto_masks[0] == pp_port->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;

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

@ -540,7 +540,7 @@ bad_data:
SCReturnInt(-1);
}
static uint16_t DNSTcpProbingParser(uint8_t *input, uint32_t ilen)
static uint16_t DNSTcpProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset)
{
if (ilen == 0 || ilen < sizeof(DNSTcpHeader)) {
SCLogDebug("ilen too small, hoped for at least %"PRIuMAX, (uintmax_t)sizeof(DNSTcpHeader));
@ -600,13 +600,12 @@ void RegisterDNSTCPParsers(void) {
DNSGetAlstateProgressCompletionStatus);
AppLayerRegisterProbingParser(&alp_proto_ctx,
53,
IPPROTO_TCP,
"53",
proto_name,
ALPROTO_DNS_TCP,
0, sizeof(DNSTcpHeader),
STREAM_TOSERVER,
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
DNSTcpProbingParser);
DNSAppLayerDecoderEventsRegister(ALPROTO_DNS_TCP);

@ -280,7 +280,7 @@ insufficient_data:
SCReturnInt(-1);
}
static uint16_t DNSUdpProbingParser(uint8_t *input, uint32_t ilen)
static uint16_t DNSUdpProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset)
{
if (ilen == 0 || ilen < sizeof(DNSHeader)) {
SCLogDebug("ilen too small, hoped for at least %"PRIuMAX, (uintmax_t)sizeof(DNSHeader));
@ -320,13 +320,12 @@ void RegisterDNSUDPParsers(void) {
DNSGetAlstateProgressCompletionStatus);
AppLayerRegisterProbingParser(&alp_proto_ctx,
53,
IPPROTO_UDP,
"53",
proto_name,
ALPROTO_DNS_UDP,
0, sizeof(DNSHeader),
STREAM_TOSERVER,
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
DNSUdpProbingParser);
DNSAppLayerDecoderEventsRegister(ALPROTO_DNS_UDP);

File diff suppressed because it is too large Load Diff

@ -150,26 +150,27 @@ typedef struct AppLayerParserTableElement_ {
} AppLayerParserTableElement;
typedef struct AppLayerProbingParserElement_ {
const char *al_proto_name;
char *al_proto_name;
uint16_t al_proto;
/* \todo don't really need it. See if you can get rid of it */
uint16_t port;
uint16_t ip_proto;
uint8_t priority;
uint8_t top;
/* \todo calculate at runtime and get rid of this var */
uint32_t al_proto_mask;
/* \todo check if we can reduce the bottom 2 vars to uint16_t */
/* 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);
uint16_t (*ProbingParser)(uint8_t *input, uint32_t input_len, uint32_t *offset);
struct AppLayerProbingParserElement_ *next;
} AppLayerProbingParserElement;
typedef struct AppLayerProbingParser_ {
typedef struct AppLayerProbingParserPort_ {
/* the port no for which probing parser(s) are invoked */
uint16_t port;
uint32_t toserver_al_proto_mask;
uint32_t toclient_al_proto_mask;
/* the max depth for all the probing parsers registered for this port */
@ -179,54 +180,44 @@ typedef struct AppLayerProbingParser_ {
AppLayerProbingParserElement *toserver;
AppLayerProbingParserElement *toclient;
struct AppLayerProbingParser_ *next;
} AppLayerProbingParser;
struct AppLayerProbingParserPort_ *next;
} AppLayerProbingParserPort;
typedef struct AppLayerProbingParserInfo_ {
const char *al_proto_name;
typedef struct AppLayerProbingParser_ {
uint16_t ip_proto;
uint16_t al_proto;
uint16_t (*ProbingParser)(uint8_t *input, uint32_t input_len);
struct AppLayerProbingParserInfo_ *next;
} AppLayerProbingParserInfo;
AppLayerProbingParserPort *port;
#define APP_LAYER_PROBING_PARSER_PRIORITY_HIGH 1
#define APP_LAYER_PROBING_PARSER_PRIORITY_MEDIUM 2
#define APP_LAYER_PROBING_PARSER_PRIORITY_LOW 3
struct AppLayerProbingParser_ *next;
} AppLayerProbingParser;
extern AppLayerProto al_proto_table[];
static inline
AppLayerProbingParser *AppLayerGetProbingParsers(AppLayerProbingParser *probing_parsers,
uint16_t ip_proto,
uint16_t port)
AppLayerProbingParserPort *AppLayerGetProbingParsers(AppLayerProbingParser *pp,
uint16_t ip_proto,
uint16_t port)
{
if (probing_parsers == NULL)
return NULL;
AppLayerProbingParser *pp = probing_parsers;
while (pp != NULL) {
if (pp->port == port || pp->port == 0) {
if (pp->ip_proto == ip_proto)
break;
}
pp = pp->next;
}
return pp;
}
if (pp == NULL)
return NULL;
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;
AppLayerProbingParserPort *pp_port = pp->port;
while (pp_port != NULL) {
if (pp_port->port == port || pp_port->port == 0) {
break;
}
pp_port = pp_port->next;
}
return NULL;
return pp_port;
}
struct AlpProtoDetectCtx_;
/* prototypes */
@ -248,11 +239,13 @@ int AppLayerRegisterParser(char *name, uint16_t proto, uint16_t parser_id,
void *local_data,
AppLayerParserResult *output),
char *dependency);
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));
void AppLayerRegisterProbingParser(struct AlpProtoDetectCtx_ *,
uint16_t ip_proto,
char *portstr,
char *al_proto_name, uint16_t al_proto,
uint16_t min_depth, uint16_t max_depth,
uint8_t flags,
uint16_t (*ProbingParser)(uint8_t *input, uint32_t input_len, uint32_t *offset));
#ifdef UNITTESTS
void AppLayerRegisterUnittests(uint16_t proto, void (*RegisterUnittests)(void));
#endif
@ -340,7 +333,6 @@ void AppLayerSetEOF(Flow *);
void AppLayerParserCleanupState(Flow *);
void AppLayerFreeProbingParsers(AppLayerProbingParser *);
void AppLayerFreeProbingParsersInfo(AppLayerProbingParserInfo *);
void AppLayerPrintProbingParsers(AppLayerProbingParser *);
void AppLayerListSupportedProtocols(void);

@ -1356,7 +1356,7 @@ static void SMBStateFree(void *s) {
#define SMB_PROBING_PARSER_MIN_DEPTH 8
static uint16_t SMBProbingParser(uint8_t *input, uint32_t ilen)
static uint16_t SMBProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset)
{
int32_t len;
int32_t input_len = ilen;
@ -1411,13 +1411,12 @@ void RegisterSMBParsers(void) {
AppLayerRegisterStateFuncs(ALPROTO_SMB, SMBStateAlloc, SMBStateFree);
AppLayerRegisterProbingParser(&alp_proto_ctx,
139,
IPPROTO_TCP,
"139",
"smb",
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
SMBProbingParser);
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_SMB, SMBParserRegisterTests);
@ -2044,13 +2043,12 @@ int SMBParserTest05(void)
AlpProtoAdd(&ctx, "smb2", IPPROTO_TCP, ALPROTO_SMB2, "|fe|SMB", 8, 4, STREAM_TOSERVER);
AppLayerRegisterProbingParser(&ctx,
f.dp,
IPPROTO_TCP,
"139",
"smb",
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
SMBProbingParser);
@ -2128,16 +2126,14 @@ int SMBParserTest06(void)
AlpProtoAdd(&ctx, "smb2", IPPROTO_TCP, ALPROTO_SMB2, "|fe|SMB", 8, 4, STREAM_TOSERVER);
AppLayerRegisterProbingParser(&ctx,
f.dp,
IPPROTO_TCP,
"139",
"smb",
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
SMBProbingParser);
AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx);

@ -971,7 +971,7 @@ void SSLStateFree(void *p)
return;
}
static uint16_t SSLProbingParser(uint8_t *input, uint32_t ilen)
static uint16_t SSLProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset)
{
/* probably a rst/fin sending an eof */
if (ilen == 0)
@ -1025,13 +1025,12 @@ void RegisterSSLParsers(void)
AppLayerRegisterStateFuncs(ALPROTO_TLS, SSLStateAlloc, SSLStateFree);
AppLayerRegisterProbingParser(&alp_proto_ctx,
443,
IPPROTO_TCP,
"443",
proto_name,
ALPROTO_TLS,
0, 3,
STREAM_TOSERVER,
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
SSLProbingParser);
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_TLS, SSLParserRegisterTests);

@ -601,33 +601,44 @@ int SigParseProto(Signature *s, const char *protostr) {
}
als = als->next;
}
/** VJ since our dns parser uses only pp, this is required to set
* ipprotos */
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);
}
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);
AppLayerProbingParser *pp = alp_proto_ctx.probing_parsers;
while (pp != NULL) {
AppLayerProbingParserPort *pp_port = pp->port;
while (pp_port != NULL) {
AppLayerProbingParserElement *pp_pe = pp_port->toserver;
while (pp_pe != NULL) {
if (strcasecmp(pp_pe->al_proto_name, protostr) == 0) {
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = pp_pe->al_proto;
s->proto.proto[pp->ip_proto / 8] |= 1 << (pp->ip_proto % 8);
}
pp_pe = pp_pe->next;
}
pp_pe = pp_port->toclient;
while (pp_pe != NULL) {
if (strcasecmp(pp_pe->al_proto_name, protostr) == 0) {
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = pp_pe->al_proto;
s->proto.proto[pp->ip_proto / 8] |= 1 << (pp->ip_proto % 8);
}
pp_pe = pp_pe->next;
}
pp_port = pp_port->next;
}
pp = pp->next;
}
SCLogError(SC_ERR_UNKNOWN_PROTOCOL, "protocol \"%s\" cannot be used "
"in a signature", protostr);
SCReturnInt(-1);
if (s->alproto == ALPROTO_UNKNOWN) {
SCLogError(SC_ERR_UNKNOWN_PROTOCOL, "protocol \"%s\" cannot be used "
"in a signature", protostr);
SCReturnInt(-1);
}
}
/* if any of these flags are set they are set in a mutually exclusive

Loading…
Cancel
Save