Update rule engine relationship with regard to setting ip protocol between specifying protocol after action, ip_proto and app-layer-protocol.

Now we can specify alproto, ip_proto combinations this way

alert dns (ip_proto:[tcp/udp];)
alert ip (app-layer-protocol:dns;)
alert ip (app-layer-protocol:dns; ip_proto:tcp;)
alert tcp (app-layer-protocol:dns:)

so on.  Neater than using dnstcp/dnsudp.

This is related to feature #424.
pull/567/head
Anoop Saldanha 12 years ago
parent 6eb8f66f0a
commit d0c5f51293

@ -584,12 +584,12 @@ void RegisterDNSTCPParsers(void) {
IPPROTO_TCP,
"53",
proto_name,
ALPROTO_DNS_TCP,
ALPROTO_DNS,
0, sizeof(DNSTcpHeader),
STREAM_TOSERVER,
DNSTcpProbingParser);
} else {
AppLayerParseProbingParserPorts(proto_name, ALPROTO_DNS_TCP,
AppLayerParseProbingParserPorts(proto_name, ALPROTO_DNS,
0, sizeof(DNSTcpHeader),
DNSTcpProbingParser);
}

@ -304,14 +304,14 @@ void RegisterDNSUDPParsers(void) {
IPPROTO_UDP,
"53",
proto_name,
ALPROTO_DNS_UDP,
ALPROTO_DNS,
0, sizeof(DNSHeader),
STREAM_TOSERVER,
DNSUdpProbingParser);
} else {
AppLayerParseProbingParserPorts(proto_name, ALPROTO_DNS_UDP,
0, sizeof(DNSHeader),
DNSUdpProbingParser);
AppLayerParseProbingParserPorts(proto_name, ALPROTO_DNS,
0, sizeof(DNSHeader),
DNSUdpProbingParser);
}
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol.",

@ -71,11 +71,15 @@ static DetectAppLayerProtocolData *DetectAppLayerProtocolParse(const char *arg)
while (*arg != '\0' && isspace((unsigned char)*arg))
arg++;
alproto = AppLayerGetProtoByName(arg);
if (alproto == ALPROTO_UNKNOWN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-protocol "
"keyword supplied with unknown protocol \"%s\"", arg);
return NULL;
if (strcasecmp(arg, "dns") == 0) {
alproto = ALPROTO_DNS;
} else {
alproto = AppLayerGetProtoByName(arg);
if (alproto == ALPROTO_UNKNOWN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-protocol "
"keyword supplied with unknown protocol \"%s\"", arg);
return NULL;
}
}
data = SCMalloc(sizeof(DetectAppLayerProtocolData));

@ -90,6 +90,7 @@ void DetectDnsQueryRegister (void) {
static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, char *str)
{
s->list = DETECT_SM_LIST_DNSQUERY_MATCH;
s->alproto = ALPROTO_DNS;
return 0;
}

File diff suppressed because it is too large Load Diff

@ -585,56 +585,33 @@ error:
int SigParseProto(Signature *s, const char *protostr) {
SCEnter();
AppLayerProbingParser *pp;
AppLayerProbingParserPort *pp_port;
AppLayerProbingParserElement *pp_pe;
int r = DetectProtoParse(&s->proto, (char *)protostr);
if (r < 0) {
s->alproto = AppLayerGetProtoByName(protostr);
if (s->alproto != ALPROTO_UNKNOWN) {
/* indicate that the signature is app-layer */
/* indicate that the signature is app-layer */
if (s->alproto != ALPROTO_UNKNOWN)
s->flags |= SIG_FLAG_APPLAYER;
/* We are going to set ip proto from the
* registered applayer signatures for proto detection */
AlpProtoSignature *als = alp_proto_ctx.head;
while (als != NULL) {
if (als->proto == s->alproto) {
/* Set the ipproto that this AL proto detection sig needs
* Note that an AL proto can be present in more than one
* IP proto (over TCP, UDP..) */
s->proto.proto[als->ip_proto / 8] |= 1 << (als->ip_proto % 8);
for (pp = alp_proto_ctx.probing_parsers; pp != NULL; pp = pp->next) {
for (pp_port = pp->port; pp_port != NULL; pp_port = pp_port->next) {
for (pp_pe = pp_port->toserver; pp_pe != NULL; pp_pe = pp_pe->next) {
if (strcasecmp(pp_pe->al_proto_name, protostr) != 0)
continue;
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = pp_pe->al_proto;
}
als = als->next;
}
}
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;
for (pp_pe = pp_port->toclient; pp_pe != NULL; pp_pe = pp_pe->next) {
if (strcasecmp(pp_pe->al_proto_name, protostr) != 0)
continue;
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = pp_pe->al_proto;
}
pp_port = pp_port->next;
}
pp = pp->next;
}
if (s->alproto == ALPROTO_UNKNOWN) {
@ -832,18 +809,14 @@ static int SigParseBasics(Signature *s, char *sigstr, char ***result, uint8_t ad
if (IPOnlySigParseAddress(s, arr[CONFIG_DST], SIG_DIREC_DST ^ addrs_direction) < 0)
goto error;
/* For "ip" we parse the ports as well, even though they will be just "any".
* We do this for later sgh building for the tcp and udp protocols. */
if (DetectProtoContainsProto(&s->proto, IPPROTO_TCP) ||
DetectProtoContainsProto(&s->proto, IPPROTO_UDP) ||
DetectProtoContainsProto(&s->proto, IPPROTO_SCTP))
{
if (SigParsePort(s, arr[CONFIG_SP], SIG_DIREC_SRC ^ addrs_direction) < 0)
goto error;
if (SigParsePort(s, arr[CONFIG_DP], SIG_DIREC_DST ^ addrs_direction) < 0)
goto error;
}
/* By AWS - Traditionally we should be doing this only for tcp/udp/sctp,
* but we do it for regardless of ip proto, since the dns/dnstcp/dnsudp
* changes that we made sees to it that at this point of time we don't
* set the ip proto for the sig. We do it a bit later. */
if (SigParsePort(s, arr[CONFIG_SP], SIG_DIREC_SRC ^ addrs_direction) < 0)
goto error;
if (SigParsePort(s, arr[CONFIG_DP], SIG_DIREC_DST ^ addrs_direction) < 0)
goto error;
*result = (char **)arr;
return 0;
@ -1368,6 +1341,11 @@ int SigValidate(DetectEngineCtx *de_ctx, Signature *s) {
static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr,
uint8_t dir)
{
AlpProtoSignature *als;
AppLayerProbingParser *pp;
AppLayerProbingParserPort *pp_port;
AppLayerProbingParserElement *pp_pe;
SigMatch *sm;
Signature *sig = SigAlloc();
if (sig == NULL)
goto error;
@ -1385,7 +1363,48 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr,
sig->num = de_ctx->signum;
de_ctx->signum++;
SigMatch *sm;
if (sig->alproto != ALPROTO_UNKNOWN) {
int override_needed = 0;
if (sig->proto.flags & DETECT_PROTO_ANY) {
sig->proto.flags &= ~DETECT_PROTO_ANY;
memset(sig->proto.proto, 0x00, sizeof(sig->proto.proto));
override_needed = 1;
} else {
override_needed = 1;
size_t s = 0;
for (s = 0; s < sizeof(sig->proto.proto); s++) {
if (sig->proto.proto[s] != 0x00) {
override_needed = 0;
break;
}
}
}
/* at this point if we had alert ip and the ip proto was not
* overridden, we use the ip proto that has been configured
* against the app proto in use. */
if (override_needed) {
for (als = alp_proto_ctx.head; als != NULL; als = als->next) {
if (sig->alproto == als->proto)
sig->proto.proto[als->ip_proto / 8] |= 1 << (als->ip_proto % 8);
}
for (pp = alp_proto_ctx.probing_parsers; pp != NULL; pp = pp->next) {
for (pp_port = pp->port; pp_port != NULL; pp_port = pp_port->next) {
for (pp_pe = pp_port->toserver; pp_pe != NULL; pp_pe = pp_pe->next) {
if (sig->alproto == pp_pe->al_proto)
sig->proto.proto[pp->ip_proto / 8] |= 1 << (pp->ip_proto % 8);
}
for (pp_pe = pp_port->toclient; pp_pe != NULL; pp_pe = pp_pe->next) {
if (sig->alproto == pp_pe->al_proto)
sig->proto.proto[pp->ip_proto / 8] |= 1 << (pp->ip_proto % 8);
}
}
}
} /* if */
} /* if */
/* set mpm_content_len */
/* determine the length of the longest pattern in the sig */

@ -284,6 +284,7 @@ typedef struct DetectPort_ {
#define SIG_FLAG_INIT_FLOW (1<<2) /**< signature has a flow setting */
#define SIG_FLAG_INIT_BIDIREC (1<<3) /**< signature has bidirectional operator */
#define SIG_FLAG_INIT_PAYLOAD (1<<4) /**< signature is inspecting the packet payload */
#define SIG_FLAG_INIT_FIRST_IPPROTO_SEEN (1 << 5) /** < signature has seen the first ip_proto keyword */
/* signature mask flags */
#define SIG_MASK_REQUIRE_PAYLOAD (1<<0)

Loading…
Cancel
Save