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

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

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

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

File diff suppressed because it is too large Load Diff

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

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

@ -971,7 +971,7 @@ void SSLStateFree(void *p)
return; 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 */ /* probably a rst/fin sending an eof */
if (ilen == 0) if (ilen == 0)
@ -1025,13 +1025,12 @@ void RegisterSSLParsers(void)
AppLayerRegisterStateFuncs(ALPROTO_TLS, SSLStateAlloc, SSLStateFree); AppLayerRegisterStateFuncs(ALPROTO_TLS, SSLStateAlloc, SSLStateFree);
AppLayerRegisterProbingParser(&alp_proto_ctx, AppLayerRegisterProbingParser(&alp_proto_ctx,
443,
IPPROTO_TCP, IPPROTO_TCP,
"443",
proto_name, proto_name,
ALPROTO_TLS, ALPROTO_TLS,
0, 3, 0, 3,
STREAM_TOSERVER, STREAM_TOSERVER,
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
SSLProbingParser); SSLProbingParser);
#ifdef UNITTESTS #ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_TLS, SSLParserRegisterTests); AppLayerRegisterUnittests(ALPROTO_TLS, SSLParserRegisterTests);

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

Loading…
Cancel
Save