Fixes incorrect variable in ticket #2207
In app-layer-dns-tcp.c in the DNSTCPResponseParse function
a variable is set to last_req when it should be last_resp.
This makes it consistent with UDP DNS response parsing.
Set flags by default:
-Wmissing-prototypes
-Wmissing-declarations
-Wstrict-prototypes
-Wwrite-strings
-Wcast-align
-Wbad-function-cast
-Wformat-security
-Wno-format-nonliteral
-Wmissing-format-attribute
-funsigned-char
Fix minor compiler warnings for these new flags on gcc and clang.
CID 1374306 (#1 of 1): Dereference before null check (REVERSE_INULL)
check_after_deref: Null-checking dns_state suggests that it may be null,
but it has already been dereferenced on all paths leading to the check.
585 if (dns_state != NULL && f != NULL) {
586 dns_state->last_req = f->lastts;
587 }
CID 1374305 (#1 of 1): Dereference before null check (REVERSE_INULL)
check_after_deref: Null-checking dns_state suggests that it may be null,
but it has already been dereferenced on all paths leading to the check.
366 if (dns_state != NULL && f != NULL) {
367 dns_state->last_req = f->lastts;
368 }
When registering a probing parser allow to_server and
to_client parsers to be registered. Previously the
probing parser may be called for both directions which
in some cases works OK, but in others can cause
the to_client side to be detected as failed.
Address the issue where a DNS response would not be logged when
the traffic is like:
- Request 1
- Request 2
- Response 1
- Response 2
which can happen on dual stack machines where the request for A
and AAAA are sent out at the same time on the same UDP "session".
A "window" is used to set the maximum number of outstanding
responses before considering the olders lost.
The advancement through the buffer was not taking into account
the size of the length field resulting in the second request
being detected as bad data.
Change AppLayerParserRegisterGetStateProgressCompletionStatus to
only store one ProgressCompletionStatus callback function for each
alproto, instead of storing one for each ipproto.
This enables us to use AppLayerParserGetStateProgressCompletionStatus
in functions where we do not know the ipproto used.
Without support for OPT RR from RFC6891 (Extension mechanisms for DNS)
values of RCODE above 15 are not possible. Remove dead code which will
never match.
packets. Where rcode isn't "no error" this is displayed in both DNS and
JSON logs.
Note that this changes the current "No such domain" to "NXDOMAIN" in DNS
logs. This could be fixed if desired to maintain compatibility with
anybody crazy enough to parse the DNS log.
When the rcode is not "no error" (for example NXDOMAIN or SERVFAIL) it
is unlikely that there will be answer RRs. Therefore the rname from the
query is used.
Because the rcode applies to a whole answer packet (not individual
queries) it is impossible to determine which query RR caused the error.
Because of this most DNS servers currently reject multiple queries per
packet. Therefore each query RR is output instead with the relevant
error code, likely to be FORMERR if queries > 1.
The probing parser detection ports yaml settings of the TCP part
of the DNS parser accidentally used udp as protocol string, causing
the wrong part of the YAML to be evaluated.
Add memuse tracking and memcap checking to the DNS parsers. Memuse
is tracked globally and per flow (state).
Memcaps are also checked per flow and globally before memory allocs
are done.
For AppLayerThreadCtx, AppLayerParserState, AppLayerParserThreadCtx
and AppLayerProtoDetectThreadCtx, use opaque pointers instead of
void pointers.
AppLayerParserState is declared in flow.h as it's part of the Flow
structure.
AppLayerThreadCtx is declared in decode.h, as it's part of the
DecodeThreadVars structure.
app-layer.[ch], app-layer-detect-proto.[ch] and app-layer-parser.[ch].
Things addressed in this commit:
- Brings out a proper separation between protocol detection phase and the
parser phase.
- The dns app layer now is registered such that we don't use "dnstcp" and
"dnsudp" in the rules. A user who previously wrote a rule like this -
"alert dnstcp....." or
"alert dnsudp....."
would now have to use,
alert dns (ipproto:tcp;) or
alert udp (app-layer-protocol:dns;) or
alert ip (ipproto:udp; app-layer-protocol:dns;)
The same rules extend to other another such protocol, dcerpc.
- The app layer parser api now takes in the ipproto while registering
callbacks.
- The app inspection/detection engine also takes an ipproto.
- All app layer parser functions now take direction as STREAM_TOSERVER or
STREAM_TOCLIENT, as opposed to 0 or 1, which was taken by some of the
functions.
- FlowInitialize() and FlowRecycle() now resets proto to 0. This is
needed by unittests, which would try to clean the flow, and that would
call the api, AppLayerParserCleanupParserState(), which would try to
clean the app state, but the app layer now needs an ipproto to figure
out which api to internally call to clean the state, and if the ipproto
is 0, it would return without trying to clean the state.
- A lot of unittests are now updated where if they are using a flow and
they need to use the app layer, we would set a flow ipproto.
- The "app-layer" section in the yaml conf has also been updated as well.
These were only used if debug is enabled.
app-layer-dns-tcp.c:407:13: warning: Value stored to 'length' is never read
length = *data;
app-layer-dns-udp.c:236:13: warning: Value stored to 'length' is never read
length = *data;
In the case where DNS requests are sent over the same flow w/o a
reply being received, we now set an event in the flow and refuse
to add more transactions to the state. This protects the DNS
handling from getting overloaded slowing down everything.
A new option to configure this behaviour was added:
app-layer:
protocols:
dnsudp:
enabled: yes
detection-ports:
udp:
toserver: 53
request-flood: 750
The request-flood parameter can be 0 (disabling this feature) or a
positive integer. It defaults to 500.
This means that if 500 unreplied requests are seen in a row an event
is set. Rule 2240007 was added to dns-events.rules to match on this.
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.
1. Proto detection
2. Parsers
For app layer protocols.
libhtp has now been moved to the section under app-layer.protocols.http,
but we still provide backward compatibility with older conf files.
Also, update StateTransactionFree to take an u64 tx id, so it's
consistant with the rest of the engine.
To reflect these changes, AppLayerRegisterTransactionIdFuncs has
been renamed to AppLayerRegisterTxFreeFunc.
HTP, DNS, SMB, DCERPC parsers updated.
Per TX decoder events resulted in significant overhead to the
detection engine, as it walked all TX' all the time to check
if decoder events were available.
This commit introduces a new API call StateHasEvents, which speeds
up this process, at the expense of keeping a counter in the state.
Implement this for DNS as well.