Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7c5285e
doc/userguide: explain isdataat absolute vs relative difference
victorjulien Jan 21, 2026
2d66253
doc/userguide: add example with non-zero offset for relative isdataat
Jan 31, 2026
a0cc534
doc/userguide: fix table showing example payload
Feb 18, 2026
1246f1c
doc/userguide: add link to differences-from-snort
Feb 18, 2026
b84ae80
affinity: address coverity warning
victorjulien Feb 18, 2026
e7c9be0
af-xdp: add missing unlock in error path
victorjulien Feb 18, 2026
5edb5a5
build-scopes: add QA_SIMULATION mode
jufajardini Feb 10, 2026
dc4d805
exceptions: s/DEBUG/QA_SIMULATION build flag
jufajardini Feb 10, 2026
723aa21
misc: update copyright years
jufajardini Feb 10, 2026
278da4b
npdi: fix null pointer deref in detect keywords
victorjulien Feb 19, 2026
28ba93e
ndpi: minor optimization
victorjulien Feb 19, 2026
23032eb
detect/ike: move ike spi keywords to rust
catenacyber Feb 19, 2026
841fe44
detect/ike: move ike.exchtype keyword to rust
catenacyber Feb 19, 2026
e85bf5b
detect/ike: move ike.key_exchange_payload_length keyword to rust
catenacyber Feb 19, 2026
f23169c
detect/ike: move ike.nonce_payload_length keyword to rust
catenacyber Feb 19, 2026
d1213e4
detect/ike: move ike.key_exchange_payload keyword to rust
catenacyber Feb 19, 2026
14edd66
detect/ike: move ike.nonce_payload keyword to rust
catenacyber Feb 19, 2026
55333a6
detect/ike: move ike.vendor keyword to rust
catenacyber Feb 19, 2026
d5ea973
detect/ike: move ike.ike.chosen_sa_attribute keyword to rust
catenacyber Feb 19, 2026
926fde8
userguide: fix Deprecations, warn about syslog
jufajardini Feb 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,14 @@
])
AM_CONDITIONAL([DEBUG_VALIDATION], [test "x$enable_debug_validation" = "xyes"])

# enable qa-simulation mode -- disabled by default
AC_ARG_ENABLE(qa-simulation,
AS_HELP_STRING([--enable-qa-simulation], [Enable qa-simulation mode]))
AS_IF([test "x$enable_qa_simulation" = "xyes"], [
AC_DEFINE([QA_SIMULATION],[1],[Enable qa-simulation mode])
])
AM_CONDITIONAL([QA_SIMULATION], [test "x$enable_qa_simulation" = "xyes"])

# profiling support
AC_ARG_ENABLE(profiling,
AS_HELP_STRING([--enable-profiling], [Enable performance profiling]),[enable_profiling=$enableval],[enable_profiling=no])
Expand Down Expand Up @@ -2642,6 +2650,7 @@ Development settings:
Unit tests enabled: ${enable_unittests}
Debug output enabled: ${enable_debug}
Debug validation enabled: ${enable_debug_validation}
QA-simulation enabled: ${enable_qa_simulation}
Fuzz targets enabled: ${enable_fuzztargets}

Generic build parameters:
Expand Down
4 changes: 4 additions & 0 deletions doc/userguide/output/syslog-alerting-comp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Suricata can alert via syslog which is a very handy feature for central log coll

However, there are different syslog daemons and there can be parsing issues with the syslog format a SIEM expects and what syslog format Suricata sends. The syslog format from Suricata is dependent on the syslog daemon running on the Suricata sensor but often the format it sends is not the format the SIEM expects and cannot parse it properly.

.. attention:: The syslog output is deprecated in Suricata 8.0 and
will be removed in Suricata 9.0. Please migrate to the
``eve`` output which has the ability to send to syslog.

Popular syslog daemons
----------------------

Expand Down
1 change: 1 addition & 0 deletions doc/userguide/rules/ike-keywords.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Match on an attribute value of the chosen Security Association (SA) by the Respo
IKEv2 supports ``alg_enc``, ``alg_auth``, ``alg_prf`` and ``alg_dh``.

If there is more than one chosen SA the event ``MultipleServerProposal`` is set. The attributes of the first SA are used for this keyword.
You can also use other modes than equality, as in :ref:`integer keywords <rules-integer-keywords>`.


Examples::
Expand Down
64 changes: 64 additions & 0 deletions doc/userguide/rules/payload-keywords.rst
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,70 @@ You can also use the negation (!) before isdataat.

.. image:: payload-keywords/isdataat1.png

absolute vs relative values
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The absolute ``isdataat`` checks will succeed if the offset used is
**less than** the size of the inspection buffer.

For *relative* ``isdataat`` checks, there is a **1 byte difference** vs
the absolute handling.

Matching will succeed if the relative offset is **less than or equal to**
the size of the inspection buffer. This is different from absolute
``isdataat`` checks.

As an example, consider a 32 byte payload:

+---------------------------+--------+
| rule statement | Match? |
+---------------------------+--------+
| ``isdataat:31;`` | Yes |
+---------------------------+--------+
| ``isdataat:32;`` | No |
+---------------------------+--------+
| ``isdataat:31,relative;`` | Yes |
+---------------------------+--------+
| ``isdataat:32,relative;`` | Yes |
+---------------------------+--------+
| ``isdataat:33,relative;`` | No |
+---------------------------+--------+

Another example, consider the following payload:

+-------+---+---+---+---+---+---+---+---+
| Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+-------+---+---+---+---+---+---+---+---+
| Value | a | b | c | d | e | f | g | h |
+-------+---+---+---+---+---+---+---+---+

Then the following rules match the payload as follows:

+----------------------------------------+--------+
| Rule statement | Match? |
+----------------------------------------+--------+
| ``isdataat:7;`` | Yes |
+----------------------------------------+--------+
| ``isdataat:8;`` | No |
+----------------------------------------+--------+
| ``isdataat:7,relative;`` | Yes |
+----------------------------------------+--------+
| ``isdataat:8,relative;`` | Yes |
+----------------------------------------+--------+
| ``isdataat:9,relative;`` | No |
+----------------------------------------+--------+
| ``payload:"c"; isdataat:4,relative;`` | Yes |
+----------------------------------------+--------+
| ``payload:"c"; isdataat:5,relative;`` | Yes |
+----------------------------------------+--------+
| ``payload:"c"; isdataat:6,relative;`` | No |
+----------------------------------------+--------+

These differences are also discussed in :doc:`differences-from-snort`.

A discussion of this difference can be found at
https://redmine.openinfosecfoundation.org/issues/8031

absent
------

Expand Down
2 changes: 1 addition & 1 deletion doc/userguide/upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ Deprecations
- The ``tls-log`` output is now deprecated and will be removed in Suricata 9.0.
- The ``syslog`` output is now deprecated and will be removed in
Suricata 9.0. Note that this is the standalone ``syslog`` output and
does affect the ``eve`` outputs ability to send to syslog.
does **not** affect the ``eve`` outputs ability to send to syslog.
- The ``default`` option in ``app-layer.protocols.tls.encryption-handling`` is
now deprecated and will be removed in Suricata 9.0. The ``track-only`` option
should be used instead.
Expand Down
54 changes: 32 additions & 22 deletions plugins/ndpi/ndpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,21 +92,21 @@ static void OnFlowInit(ThreadVars *tv, Flow *f, const Packet *p, void *_data)

static void OnFlowUpdate(ThreadVars *tv, Flow *f, Packet *p, void *_data)
{
struct NdpiThreadContext *threadctx = ThreadGetStorageById(tv, thread_storage_id);
struct NdpiFlowContext *flowctx = FlowGetStorageById(f, flow_storage_id);
/* Ignore packets that have a different protocol than the
* flow. This can happen with ICMP unreachable packets. */
if (p->proto != f->proto) {
return;
}

uint16_t ip_len = 0;
void *ip_ptr = NULL;
struct NdpiThreadContext *threadctx = ThreadGetStorageById(tv, thread_storage_id);
struct NdpiFlowContext *flowctx = FlowGetStorageById(f, flow_storage_id);

if (!threadctx->ndpi || !flowctx->ndpi_flow) {
return;
}

/* Ignore packets that have a different protocol than the
* flow. This can happen with ICMP unreachable packets. */
if (p->proto != f->proto) {
return;
}

if (PacketIsIPv4(p)) {
const IPV4Hdr *ip4h = PacketGetIPv4(p);
ip_len = IPV4_GET_RAW_IPLEN(ip4h);
Expand Down Expand Up @@ -181,11 +181,21 @@ static void OnThreadInit(ThreadVars *tv, void *_data)
static int DetectnDPIProtocolPacketMatch(
DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
SCEnter();

const Flow *f = p->flow;
if (f == NULL) {
SCLogDebug("packet %" PRIu64 ": no flow", PcapPacketCntGet(p));
SCReturnInt(0);
}

struct NdpiFlowContext *flowctx = FlowGetStorageById(f, flow_storage_id);
const DetectnDPIProtocolData *data = (const DetectnDPIProtocolData *)ctx;
if (flowctx == NULL) {
SCLogDebug("packet %" PRIu64 ": no flowctx", PcapPacketCntGet(p));
SCReturnInt(0);
}

SCEnter();
const DetectnDPIProtocolData *data = (const DetectnDPIProtocolData *)ctx;

/* if the sig is PD-only we only match when PD packet flags are set */
/*
Expand All @@ -201,11 +211,6 @@ static int DetectnDPIProtocolPacketMatch(
SCReturnInt(0);
}

if (f == NULL) {
SCLogDebug("packet %" PRIu64 ": no flow", PcapPacketCntGet(p));
SCReturnInt(0);
}

bool r = ndpi_is_proto_equals(flowctx->detected_l7_protocol.proto, data->l7_protocol, false);
r = r ^ data->negated;

Expand Down Expand Up @@ -311,22 +316,27 @@ static void DetectnDPIProtocolFree(DetectEngineCtx *de_ctx, void *ptr)
static int DetectnDPIRiskPacketMatch(
DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
SCEnter();

const Flow *f = p->flow;
if (f == NULL) {
SCLogDebug("packet %" PRIu64 ": no flow", PcapPacketCntGet(p));
SCReturnInt(0);
}

struct NdpiFlowContext *flowctx = FlowGetStorageById(f, flow_storage_id);
const DetectnDPIRiskData *data = (const DetectnDPIRiskData *)ctx;
if (flowctx == NULL) {
SCLogDebug("packet %" PRIu64 ": no flowctx", PcapPacketCntGet(p));
SCReturnInt(0);
}

SCEnter();
const DetectnDPIRiskData *data = (const DetectnDPIRiskData *)ctx;

if (!flowctx->detection_completed) {
SCLogDebug("packet %" PRIu64 ": ndpi risks not yet detected", PcapPacketCntGet(p));
SCReturnInt(0);
}

if (f == NULL) {
SCLogDebug("packet %" PRIu64 ": no flow", PcapPacketCntGet(p));
SCReturnInt(0);
}

bool r = ((flowctx->ndpi_flow->risk & data->risk_mask) == data->risk_mask);
r = r ^ data->negated;

Expand Down
Loading
Loading