This may happen in some situations if the app-layer parser only sees
unknown messages and sets an event: there will be an empty transaction,
but nothing to log.
pgsql/parser: always use fn for parsing PDU length
Some inner parsers were using it, some weren't. Better to standardize
this. Also take the time to avoid magic numbers for representing the
expected lengths for pgsql PDUs.
Also throwing PgsqlParseError and allowing for incomplete results.
Jason Ish [Fri, 24 Jan 2025 15:56:58 +0000 (09:56 -0600)]
rust: add bindings to SCPlugin.* to sys crate
Also disable bindgen's generated layout tests. They are valid for the
platform generating the tests, but may not be valid for other
platforms. For example, if the tests are generated on a 64 bit
platform the tests will not be valid when run on a 32 bit platform as
pointers are a different size.
However, the generating bindings are valid for both platform.
Jason Ish [Fri, 24 Jan 2025 15:05:03 +0000 (09:05 -0600)]
rust: add auto-generated header to sys.rs
We don't keep bindgen's autogenerated do not edit line as it contains
the bindgen version which could break the CI check for out of date
bindings. So add our own do not edit line.
Jason Ish [Thu, 23 Jan 2025 22:26:25 +0000 (16:26 -0600)]
rust: integrate bindgen to generate Rust bindings to C
Bindgen works by processing a header file which includes all other
header files it should generate bindings for. For this I've created
bindgen.h which just includes app-layer-protos.h for now as an
example.
These bindings are then generated and saved in the "suricata-sys"
crate and become availale as "suricata_sys::sys".
Jason Ish [Thu, 23 Jan 2025 22:19:09 +0000 (16:19 -0600)]
rust/sys: stub in suricata-sys crate for Rust bindings to C
Follow Rust convention of using a "sys" crate for bindings to C
functions. The bindings don't exist yet, but will be generated by
bindgen and put into this crate.
Victor Julien [Thu, 13 Feb 2025 13:30:39 +0000 (14:30 +0100)]
tls: more permissive empty data eof check
If not all data is ACK'd during the FIN session shutdown, the last calls
to the parser can be with a non-NULL data pointer, but a input length of
0. This wasn't considered by the EOF check, which then lead to it being
seen as an error. No event was raised, but the tls error stats were
incremented.
In a recent warning reported by scan-build, datasets were found to be
using a blocking call in a critical section.
datasets.c:187:12: warning: Call to blocking function 'fgets' inside of critical section [unix.BlockInCriticalSection]
187 | while (fgets(line, (int)sizeof(line), fp) != NULL) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
datasets.c:292:12: warning: Call to blocking function 'fgets' inside of critical section [unix.BlockInCriticalSection]
292 | while (fgets(line, (int)sizeof(line), fp) != NULL) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
datasets.c:368:12: warning: Call to blocking function 'fgets' inside of critical section [unix.BlockInCriticalSection]
368 | while (fgets(line, (int)sizeof(line), fp) != NULL) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
datasets.c:442:12: warning: Call to blocking function 'fgets' inside of critical section [unix.BlockInCriticalSection]
442 | while (fgets(line, (int)sizeof(line), fp) != NULL) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
datasets.c:512:12: warning: Call to blocking function 'fgets' inside of critical section [unix.BlockInCriticalSection]
512 | while (fgets(line, (int)sizeof(line), fp) != NULL) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
These calls are blocking in the multi tenant mode where several tenants
may be trying to load the same dataset in parallel.
In a single tenant mode, this operation is performed as a part of a
single thread before the engine startup.
In order to evade the warning and simplify the code, the initial file
reading is moved to Rust with this commit with a much simpler handling
of dataset and datarep.
Jason Ish [Tue, 11 Feb 2025 22:26:39 +0000 (16:26 -0600)]
output-lua: lua module search path configuration
By default, use an empty search path. This gives us a predictable
default. If a user needs access to external modules, the search path
must be set in the configuration file.
Jason Ish [Thu, 30 Jan 2025 16:49:37 +0000 (10:49 -0600)]
base64: expose no padding and padding optional variants
A no padding option is provided as a mode, as its a variant suitable
for encoding and decoding.
A padding optional function is added that is indifferent to padding
when decoding. This can be useful when you're not sure if padding
exists, and don't really care.
Victor Julien [Tue, 21 Jan 2025 19:03:17 +0000 (20:03 +0100)]
lua: add initial suricata.packet lib
Example:
```
local packet = require "suricata.packet"
function init (args)
local needs = {}
return needs
end
function match (args)
p = packet.get()
payload = p:payload()
ts = p:timestring()
for line in payload:gmatch("([^\r\n]*)[\r\n]+") do
if line == "GET /index.html HTTP/1.0" then
ipver, srcip, dstip, proto, sp, dp = p:tuple()
SCLogNotice(string.format("%s %s->%s %d->%d (pcap_cnt:%d) match! %s", ts, srcip, dstip, sp, dp, p:pcap_cnt(), line));
return 1
end
end
return 0
end
```
Methods:
`get` creates the packet object.
`payload` returns the packet payload as a buffer
`packet` returns the whole packet (includes headers)
`pcap_cnt` returns the `pcap_cnt` (pcap file mode only)
`tuple` returns various fields: srcip, dstip, proto, sp, dp
`sp` returns source port
`dp` returns destination port
`timestamp` returns time as 2 numbers: seconds and microseconds
`timestring_legacy` returns a timestamp as a string (like fastlog)
`timestring_iso8601` returns a iso8601 compat timestring (like eve)
Adam Kiripolsky [Tue, 14 Jan 2025 11:58:47 +0000 (12:58 +0100)]
dpdk/rss: add rte_flow rss support for mlx5
The configuration of this rule is the same as for ixgbe driver except
the hash function is not RTE_ETH_HASH_FUNCTION_DEFAULT but
RTE_ETH_HASH_FUNCTION_TOEPLITZ.
The syntax in dpdk-testpmd for this rule with attributes:
port index == 0
used rx queue indices == 0 1 2 3
<hash_key> == 6d5a symmetric hash key
is as follows:
"flow create 0 ingress pattern eth / end actions rss types ipv4 ipv6
end queues 0 1 2 3 end key <hash_key> key_len 40 func toeplitz / end"
Adam Kiripolsky [Tue, 10 Dec 2024 15:27:23 +0000 (16:27 +0100)]
dpdk/rss: add rte_flow rss support for ice
ice driver requires 2 rte_flow rules for matching and
redistributing incoming traffic with RSS.
The rules set up by iceDeviceSetRSSFlowIPv4() and
iceDeviceSetRSSFlowIPv6() are different only in the pattern
("pattern eth / ipv4 / end" or "pattern eth / ipv6 / end"
in dpdk-testpmd syntax) and in the hash type (ipv4 src dst / ipv6 src
dst). ice will match all ipv4 or ipv6 traffic independently of
following l4 protocol. The rules can not have queues configured,
implicitly they will use all queues available.
The hash function is set to RTE_ETH_HASH_FUNCTION_TOEPLITZ.
The hash key can not be set.
The syntax in dpdk-testpmd for rule to match all ipv4 traffic
with attributes:
port index == 0
is as follows:
"flow create 0 ingress pattern eth / ipv4 / end actions rss types ipv4
end queues end func toeplitz / end"
(queues need to be set to NULL)
Adam Kiripolsky [Tue, 10 Dec 2024 15:26:49 +0000 (16:26 +0100)]
dpdk/rss: add rte_flow rss support for ixgbe
ixgbe driver requires different configuration of RSS rte_flow
rule than i40e, with just one generic rule matching all traffic.
The generic rule configured by DeviceCreateRSSFlowGeneric() has pattern
equivalent to "pattern eth / end" in dpdk-testpmd syntax. The rule must
have rx queues configured. The rule hashes traffic to different queues
based on ipv4 and ipv6 hash types (ipv4 src dst / ipv6 src dst).
The hash key is 40 bytes long symmetric hash key. ixgbe does not
support any other hash function than RTE_ETH_HASH_FUNCTION_DEFAULT.
The syntax in dpdk-testpmd for this rule with attributes:
port index == 0
used rx queue indices == 0 1 2 3
<hash_key> == 6d5a symmetric hash key
is as follows:
"flow create 0 ingress pattern eth / end actions rss types ipv4 ipv6
end queues 0 1 2 3 end key <hash_key> key_len 40 func default / end"
Adam Kiripolsky [Thu, 12 Dec 2024 12:28:02 +0000 (13:28 +0100)]
dpdk/rss: move and change rss rte_flow functions
Move and adjust the base of RSS configuration from util-dpdk-i40e.c to
a new file that can be later utilized by other cards.
RSS configuration can be configured via rte_flow rules. This is useful
for possible future features such as specific header offload
(vxlan, nvgre) also implemented via rte_flow rules, as rte_flow
rules can be chained via groups and priorities.
i40e uses multiple different rte_flow rules to setup RSS. At first,
function DeviceSetRSSFlowQueues() is used to setup rx queues.
This rule matches all types of traffic, so the equivalent
to dpdk-testpmd pattern would be "pattern end"
This rule can not contain hash types (ipv4, ipv6 etc.) nor hash key.
The hash function used here is RTE_ETH_HASH_FUNCTION_DEFAULT.
The syntax in dpdk-testpmd for this rule with attributes:
port index == 0
used rx queue indices == 0 1 2 3
is as follows:
"flow create 0 ingress pattern end actions rss queues 0 1 2 3 end
func default / end"
The other rules configured by i40eDeviceSetRSSFlowIPv4() and
i40eDeviceSetRSSFlowIPv6() match specific type of traffic by l4 protocol
(none, TCP, UDP, SCTP). For example, pattern to match l3 ipv4 with l4
tcp traffic in dpdk-testpmd syntax would be equivalent of
"pattern eth / ipv4 / tcp / end".
These rules can not have rx queues configured, but have hash types
(l3 src and dst address). This means that the traffic distribution
is affected only by l3 addresses, independent of the l4 specifics.
Also these pattern matching rules have symmetric 6d5a
hash key configured. The length of the key is dependent on DPDK version.
The hash function (either RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ or
RTE_ETH_HASH_FUNCTION_TOEPLITZ, depending on DPKD version) used
in these rules hashes symmetricaly due to the symmetric hash key.
The syntax in dpdk-testpmd for rule to match ipv4-tcp traffic with
attributes:
port index == 0
<hash_key> == 52 bytes long 6d5a symmetric hash key
is as follows:
"flow create 0 ingress pattern eth / ipv4 / tcp / end actions rss types
ipv4-tcp l3-src-only l3-dst-only end queues end key <hash_key>
key_len 52 func toeplitz / end"
(queues need to be set to NULL)
Victor Julien [Wed, 22 Nov 2023 09:41:47 +0000 (10:41 +0100)]
af-packet: clean up IPS config check
Don't emmit generic error statements on things that are not errors. Instead,
for cases where (part of) the config is missing, use the defaults and log
only a more detailed explanation at the 'config' level.
protodetect: simplify code since DCERPC UDP detection is improved
Protocol detection code is simplified. Removed dependency on explicit
alproto constants from the common part of code that must not be aware of
the each specific protocol features.
Frames of the following types have been added for toserver direction:
1. Pdu: The entire Protocol Data Unit
2. Hdr: Header of the request
3. Data: PDU data
With the introduction of AppLayerResult::incomplete API, fragmented data
is no longer handled fully in the dcerpc code. Given that these code
paths are already covered by the following s-v tests, these tests can now be
safely removed.
- dce-gap-handling
- dcerpc-dce-iface-*
Instead of own internal mechanism of buffering in case of fragmented
data, use AppLayerResult::incomplete API to let the AppLayer Parser take
care of it. This makes the memory use more efficient.
Remove any unneeded variables and code with the introduction of this
API.
TCP data can be presented to the protocol parser in any way e.g. one
byte at a time, single complete PDU, fragmented PDU, multiple PDUs at
once. A limit of 1MB can be easily reached in some of such scenarios.
Remove the check that rejects data that is more than 1MB.
Shivani Bhardwaj [Thu, 23 Jan 2025 05:39:46 +0000 (11:09 +0530)]
app-layer: update flow counter if an alproto is detected
If alproto for the current direction was not detected but the opposite
side was successfully detected, if the Pattern Matching and Pattern
Probing on the flow was also successfully done and the current
direction's alproto is still unknown, a decoder event is set to indicate
that the protocol detection only happened in one direction.
This event is set after having sent the current data to the applayer
parser. Now, the respective applayer parser may or may not successfully
parse the data. However, the alproto on flow is already set from the
other direction so there will be a flow event generated by Suricata. In
order to keep this consistent with the stats, also make sure to
increment the flow counter when the decode event is set so that the flow
counter is incremented irrespective of the parsing status reported by
the applayer parser.
This patch makes stats for several specific applayer flow count equal to
the number of flow events logged for those specific applayer protocols.
Victor Julien [Thu, 23 Jan 2025 15:07:08 +0000 (16:07 +0100)]
detect/iponly: use flow first flags
Instead of ip-only specific flags, reuse the FLOW_PKT_TOSERVER_FIRST and
FLOW_PKT_TOCLIENT_FIRST flags.
Fixes false positives on one sided streams that trigger a opposing flow
timeout packet at the flow's end. That pseudo packet would trigger a
match even though it shouldn't.
Eric Leblond [Fri, 29 Nov 2024 17:46:11 +0000 (18:46 +0100)]
util/debug: increase max length of message
When a signature is incorrect, its full content is logged in a
message with some other information such as rules file name. As
a result, the log message must be longer than a maximum signature
length which is 8192.