• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 22550934724

01 Mar 2026 07:34PM UTC coverage: 75.853% (+2.2%) from 73.687%
22550934724

Pull #14923

github

web-flow
github-actions: bump github/codeql-action from 4.32.3 to 4.32.4

Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.32.3 to 4.32.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v4.32.3...v4.32.4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.32.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #14923: github-actions: bump github/codeql-action from 4.32.3 to 4.32.4

240804 of 317461 relevant lines covered (75.85%)

2441195.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.93
/src/detect-app-layer-protocol.c
1
/* Copyright (C) 2007-2025 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 * \file
20
 *
21
 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
22
 */
23

24
#include "suricata-common.h"
25
#include "detect-engine.h"
26
#include "detect-engine-build.h"
27
#include "detect-engine-prefilter.h"
28
#include "detect-engine-prefilter-common.h"
29
#include "detect-parse.h"
30
#include "detect-app-layer-protocol.h"
31
#include "app-layer.h"
32
#include "app-layer-parser.h"
33
#include "util-debug.h"
34
#include "util-unittest.h"
35
#include "util-unittest-helper.h"
36

37
#ifdef UNITTESTS
38
static void DetectAppLayerProtocolRegisterTests(void);
39
#endif
40

41
enum {
42
    DETECT_ALPROTO_DIRECTION = 0,
43
    DETECT_ALPROTO_FINAL = 1,
44
    DETECT_ALPROTO_EITHER = 2,
45
    DETECT_ALPROTO_TOSERVER = 3,
46
    DETECT_ALPROTO_TOCLIENT = 4,
47
    DETECT_ALPROTO_ORIG = 5,
48
};
49

50
typedef struct DetectAppLayerProtocolData_ {
51
    AppProto alproto;
52
    uint8_t negated;
53
    uint8_t mode;
54
} DetectAppLayerProtocolData;
55

56
static int DetectAppLayerProtocolPacketMatch(
57
        DetectEngineThreadCtx *det_ctx,
58
        Packet *p, const Signature *s, const SigMatchCtx *ctx)
59
{
17,878✔
60
    SCEnter();
17,878✔
61

62
    bool r = false;
17,878✔
63
    const DetectAppLayerProtocolData *data = (const DetectAppLayerProtocolData *)ctx;
17,878✔
64

65
    /* if the sig is PD-only we only match when PD packet flags are set */
66
    if (s->type == SIG_TYPE_PDONLY &&
17,878✔
67
            (p->flags & (PKT_PROTO_DETECT_TS_DONE | PKT_PROTO_DETECT_TC_DONE)) == 0) {
17,878✔
68
        SCLogDebug("packet %" PRIu64 ": flags not set", PcapPacketCntGet(p));
16,278✔
69
        SCReturnInt(0);
16,278✔
70
    }
16,278✔
71

72
    const Flow *f = p->flow;
1,600✔
73
    if (f == NULL) {
1,600✔
74
        SCLogDebug("packet %" PRIu64 ": no flow", PcapPacketCntGet(p));
×
75
        SCReturnInt(0);
×
76
    }
×
77

78
    switch (data->mode) {
1,600✔
79
        case DETECT_ALPROTO_DIRECTION:
1,476✔
80
            if (data->negated) {
1,476✔
81
                if (p->flowflags & FLOW_PKT_TOSERVER) {
1,295✔
82
                    if (f->alproto_ts == ALPROTO_UNKNOWN)
828✔
83
                        SCReturnInt(0);
96✔
84
                    r = AppProtoEquals(data->alproto, f->alproto_ts);
732✔
85
                } else {
732✔
86
                    if (f->alproto_tc == ALPROTO_UNKNOWN)
467✔
87
                        SCReturnInt(0);
79✔
88
                    r = AppProtoEquals(data->alproto, f->alproto_tc);
388✔
89
                }
388✔
90
            } else {
1,295✔
91
                if (p->flowflags & FLOW_PKT_TOSERVER) {
181✔
92
                    r = AppProtoEquals(data->alproto, f->alproto_ts);
102✔
93
                } else {
102✔
94
                    r = AppProtoEquals(data->alproto, f->alproto_tc);
79✔
95
                }
79✔
96
            }
181✔
97
            break;
1,301✔
98
        case DETECT_ALPROTO_ORIG:
1,301✔
99
            if (data->negated) {
×
100
                if (f->alproto_orig == ALPROTO_UNKNOWN)
×
101
                    SCReturnInt(0);
×
102
                r = AppProtoEquals(data->alproto, f->alproto_orig);
×
103
            } else {
×
104
                r = AppProtoEquals(data->alproto, f->alproto_orig);
×
105
            }
×
106
            break;
×
107
        case DETECT_ALPROTO_FINAL:
29✔
108
            if (data->negated) {
29✔
109
                if (f->alproto == ALPROTO_UNKNOWN)
29✔
110
                    SCReturnInt(0);
×
111
                r = AppProtoEquals(data->alproto, f->alproto);
29✔
112
            } else {
29✔
113
                r = AppProtoEquals(data->alproto, f->alproto);
×
114
            }
×
115
            break;
29✔
116
        case DETECT_ALPROTO_TOSERVER:
29✔
117
            if (data->negated) {
×
118
                if (f->alproto_ts == ALPROTO_UNKNOWN)
×
119
                    SCReturnInt(0);
×
120
                r = AppProtoEquals(data->alproto, f->alproto_ts);
×
121
            } else {
×
122
                r = AppProtoEquals(data->alproto, f->alproto_ts);
×
123
            }
×
124
            break;
×
125
        case DETECT_ALPROTO_TOCLIENT:
×
126
            if (data->negated) {
×
127
                if (f->alproto_tc == ALPROTO_UNKNOWN)
×
128
                    SCReturnInt(0);
×
129
                r = AppProtoEquals(data->alproto, f->alproto_tc);
×
130
            } else {
×
131
                r = AppProtoEquals(data->alproto, f->alproto_tc);
×
132
            }
×
133
            break;
×
134
        case DETECT_ALPROTO_EITHER:
95✔
135
            if (data->negated) {
95✔
136
                if (f->alproto_ts == ALPROTO_UNKNOWN && f->alproto_tc == ALPROTO_UNKNOWN)
95✔
137
                    SCReturnInt(0);
65✔
138
                r = AppProtoEquals(data->alproto, f->alproto_tc) ||
30✔
139
                    AppProtoEquals(data->alproto, f->alproto_ts);
30✔
140
            } else {
30✔
141
                r = AppProtoEquals(data->alproto, f->alproto_tc) ||
×
142
                    AppProtoEquals(data->alproto, f->alproto_ts);
×
143
            }
×
144
            break;
30✔
145
    }
1,600✔
146
    r = r ^ data->negated;
1,360✔
147
    if (r) {
1,360✔
148
        SCReturnInt(1);
692✔
149
    }
692✔
150
    SCReturnInt(0);
1,360✔
151
}
1,360✔
152

153
#define MAX_ALPROTO_NAME 50
152✔
154
static DetectAppLayerProtocolData *DetectAppLayerProtocolParse(const char *arg, bool negate)
155
{
5,702✔
156
    DetectAppLayerProtocolData *data;
5,702✔
157
    AppProto alproto = ALPROTO_UNKNOWN;
5,702✔
158

159
    char alproto_copy[MAX_ALPROTO_NAME];
5,702✔
160
    char *sep = strchr(arg, ',');
5,702✔
161
    char *alproto_name;
5,702✔
162
    if (sep && sep - arg < MAX_ALPROTO_NAME) {
5,702✔
163
        strlcpy(alproto_copy, arg, sep - arg + 1);
124✔
164
        alproto_name = alproto_copy;
124✔
165
    } else {
5,578✔
166
        alproto_name = (char *)arg;
5,578✔
167
    }
5,578✔
168
    if (strcmp(alproto_name, "failed") == 0) {
5,702✔
169
        alproto = ALPROTO_FAILED;
35✔
170
    } else if (strcmp(alproto_name, "unknown") == 0) {
5,667✔
171
        if (negate) {
3✔
172
            SCLogError("app-layer-protocol "
×
173
                       "keyword can't use negation with protocol 'unknown'");
×
174
            return NULL;
×
175
        }
×
176
        alproto = ALPROTO_UNKNOWN;
3✔
177
    } else {
5,664✔
178
        alproto = AppLayerGetProtoByName(alproto_name);
5,664✔
179
        if (alproto == ALPROTO_UNKNOWN) {
5,664✔
180
            SCLogError("app-layer-protocol "
359✔
181
                       "keyword supplied with unknown protocol \"%s\"",
359✔
182
                    alproto_name);
359✔
183
            return NULL;
359✔
184
        }
359✔
185
    }
5,664✔
186
    uint8_t mode = DETECT_ALPROTO_DIRECTION;
5,343✔
187
    if (sep) {
5,343✔
188
        if (strcmp(sep + 1, "final") == 0) {
117✔
189
            mode = DETECT_ALPROTO_FINAL;
50✔
190
        } else if (strcmp(sep + 1, "original") == 0) {
67✔
191
            mode = DETECT_ALPROTO_ORIG;
8✔
192
        } else if (strcmp(sep + 1, "either") == 0) {
59✔
193
            mode = DETECT_ALPROTO_EITHER;
32✔
194
        } else if (strcmp(sep + 1, "to_server") == 0) {
32✔
195
            mode = DETECT_ALPROTO_TOSERVER;
3✔
196
        } else if (strcmp(sep + 1, "to_client") == 0) {
24✔
197
            mode = DETECT_ALPROTO_TOCLIENT;
4✔
198
        } else if (strcmp(sep + 1, "direction") == 0) {
20✔
199
            mode = DETECT_ALPROTO_DIRECTION;
3✔
200
        } else {
17✔
201
            SCLogError("app-layer-protocol "
17✔
202
                       "keyword supplied with unknown mode \"%s\"",
17✔
203
                    sep + 1);
17✔
204
            return NULL;
17✔
205
        }
17✔
206
    }
117✔
207

208
    data = SCMalloc(sizeof(DetectAppLayerProtocolData));
5,326✔
209
    if (unlikely(data == NULL))
5,326✔
210
        return NULL;
×
211
    data->alproto = alproto;
5,326✔
212
    data->negated = negate;
5,326✔
213
    data->mode = mode;
5,326✔
214

215
    return data;
5,326✔
216
}
5,326✔
217

218
static bool HasConflicts(const DetectAppLayerProtocolData *us,
219
                          const DetectAppLayerProtocolData *them)
220
{
1,086✔
221
    /* mixing negated and non negated is illegal */
222
    if ((them->negated ^ us->negated) && them->mode == us->mode)
1,086✔
223
        return true;
604✔
224
    /* multiple non-negated is illegal */
225
    if (!us->negated && them->mode == us->mode)
482✔
226
        return true;
3✔
227
    /* duplicate option */
228
    if (us->alproto == them->alproto && them->mode == us->mode)
479✔
229
        return true;
8✔
230

231
    /* all good */
232
    return false;
471✔
233
}
479✔
234

235
static int DetectAppLayerProtocolSetup(DetectEngineCtx *de_ctx,
236
        Signature *s, const char *arg)
237
{
5,732✔
238
    DetectAppLayerProtocolData *data = NULL;
5,732✔
239

240
    if (s->alproto != ALPROTO_UNKNOWN) {
5,732✔
241
        SCLogError("Either we already "
34✔
242
                   "have the rule match on an app layer protocol set through "
34✔
243
                   "other keywords that match on this protocol, or have "
34✔
244
                   "already seen a non-negated app-layer-protocol.");
34✔
245
        goto error;
34✔
246
    }
34✔
247

248
    data = DetectAppLayerProtocolParse(arg, s->init_data->negated);
5,698✔
249
    if (data == NULL)
5,698✔
250
        goto error;
376✔
251

252
    SigMatch *tsm = s->init_data->smlists[DETECT_SM_LIST_MATCH];
5,322✔
253
    for ( ; tsm != NULL; tsm = tsm->next) {
6,738✔
254
        if (tsm->type == DETECT_APP_LAYER_PROTOCOL) {
2,031✔
255
            const DetectAppLayerProtocolData *them = (const DetectAppLayerProtocolData *)tsm->ctx;
1,086✔
256

257
            if (HasConflicts(data, them)) {
1,086✔
258
                SCLogError("can't mix "
615✔
259
                           "positive app-layer-protocol match with negated "
615✔
260
                           "match or match for 'failed'.");
615✔
261
                goto error;
615✔
262
            }
615✔
263
        }
1,086✔
264
    }
2,031✔
265

266
    if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_APP_LAYER_PROTOCOL, (SigMatchCtx *)data,
4,707✔
267
                DETECT_SM_LIST_MATCH) == NULL) {
4,707✔
268
        goto error;
×
269
    }
×
270
    return 0;
4,707✔
271

272
error:
1,025✔
273
    if (data != NULL)
1,025✔
274
        SCFree(data);
615✔
275
    return -1;
1,025✔
276
}
4,707✔
277

278
static void DetectAppLayerProtocolFree(DetectEngineCtx *de_ctx, void *ptr)
279
{
4,711✔
280
    SCFree(ptr);
4,711✔
281
}
4,711✔
282

283
/** \internal
284
 *  \brief prefilter function for protocol detect matching
285
 */
286
static void
287
PrefilterPacketAppProtoMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
288
{
293✔
289
    const PrefilterPacketHeaderCtx *ctx = pectx;
293✔
290

291
    if (!PrefilterPacketHeaderExtraMatch(ctx, p)) {
293✔
292
        SCLogDebug("packet %" PRIu64 ": extra match failed", PcapPacketCntGet(p));
×
293
        SCReturn;
×
294
    }
×
295

296
    if (p->flow == NULL) {
293✔
297
        SCLogDebug("packet %" PRIu64 ": no flow, no alproto", PcapPacketCntGet(p));
×
298
        SCReturn;
×
299
    }
×
300

301
    if ((p->flags & (PKT_PROTO_DETECT_TS_DONE|PKT_PROTO_DETECT_TC_DONE)) == 0) {
293✔
302
        SCLogDebug("packet %" PRIu64 ": flags not set", PcapPacketCntGet(p));
273✔
303
        SCReturn;
273✔
304
    }
273✔
305

306
    Flow *f = p->flow;
20✔
307
    AppProto alproto = ALPROTO_UNKNOWN;
20✔
308
    bool negated = (bool)ctx->v1.u8[2];
20✔
309
    switch (ctx->v1.u8[3]) {
20✔
310
        case DETECT_ALPROTO_DIRECTION:
20✔
311
            if (p->flowflags & FLOW_PKT_TOSERVER) {
20✔
312
                alproto = f->alproto_ts;
12✔
313
            } else {
12✔
314
                alproto = f->alproto_tc;
8✔
315
            }
8✔
316
            break;
20✔
317
        case DETECT_ALPROTO_ORIG:
×
318
            alproto = f->alproto_orig;
×
319
            break;
×
320
        case DETECT_ALPROTO_FINAL:
×
321
            alproto = f->alproto;
×
322
            break;
×
323
        case DETECT_ALPROTO_TOSERVER:
×
324
            alproto = f->alproto_ts;
×
325
            break;
×
326
        case DETECT_ALPROTO_TOCLIENT:
×
327
            alproto = f->alproto_tc;
×
328
            break;
×
329
        case DETECT_ALPROTO_EITHER:
×
330
            // check if either protocol toclient or toserver matches
331
            // the one in the signature ctx
332
            if (negated) {
×
333
                if (f->alproto_tc != ALPROTO_UNKNOWN &&
×
334
                        !AppProtoEquals(ctx->v1.u16[0], f->alproto_tc)) {
×
335
                    PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
×
336
                } else if (f->alproto_ts != ALPROTO_UNKNOWN &&
×
337
                           !AppProtoEquals(ctx->v1.u16[0], f->alproto_ts)) {
×
338
                    PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
×
339
                }
×
340
            } else {
×
341
                if (AppProtoEquals(ctx->v1.u16[0], f->alproto_tc) ||
×
342
                        AppProtoEquals(ctx->v1.u16[0], f->alproto_ts)) {
×
343
                    PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
×
344
                }
×
345
            }
×
346
            // We return right away to avoid calling PrefilterAddSids again
347
            return;
×
348
    }
20✔
349

350
    if (negated) {
20✔
351
        if (alproto != ALPROTO_UNKNOWN) {
20✔
352
            if (!AppProtoEquals(ctx->v1.u16[0], alproto)) {
20✔
353
                PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
19✔
354
            }
19✔
355
        }
20✔
356
    } else {
20✔
357
        if (AppProtoEquals(ctx->v1.u16[0], alproto)) {
×
358
            PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
×
359
        }
×
360
    }
×
361
}
20✔
362

363
static void
364
PrefilterPacketAppProtoSet(PrefilterPacketHeaderValue *v, void *smctx)
365
{
280✔
366
    const DetectAppLayerProtocolData *a = smctx;
280✔
367
    v->u16[0] = a->alproto;
280✔
368
    v->u8[2] = (uint8_t)a->negated;
280✔
369
    v->u8[3] = a->mode;
280✔
370
}
280✔
371

372
static bool
373
PrefilterPacketAppProtoCompare(PrefilterPacketHeaderValue v, void *smctx)
374
{
161✔
375
    const DetectAppLayerProtocolData *a = smctx;
161✔
376
    if (v.u16[0] == a->alproto && v.u8[2] == (uint8_t)a->negated && v.u8[3] == a->mode)
161✔
377
        return true;
143✔
378
    return false;
18✔
379
}
161✔
380

381
static int PrefilterSetupAppProto(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
382
{
195✔
383
    return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_APP_LAYER_PROTOCOL, SIG_MASK_REQUIRE_FLOW,
195✔
384
            PrefilterPacketAppProtoSet, PrefilterPacketAppProtoCompare,
195✔
385
            PrefilterPacketAppProtoMatch);
195✔
386
}
195✔
387

388
static bool PrefilterAppProtoIsPrefilterable(const Signature *s)
389
{
×
390
    if (s->type == SIG_TYPE_PDONLY) {
×
391
        SCLogDebug("prefilter on PD %u", s->id);
×
392
        return true;
×
393
    }
×
394
    return false;
×
395
}
×
396

397
void DetectAppLayerProtocolRegister(void)
398
{
13✔
399
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].name = "app-layer-protocol";
13✔
400
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].desc = "match on the detected app-layer protocol";
13✔
401
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].url = "/rules/app-layer.html#app-layer-protocol";
13✔
402
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].Match = DetectAppLayerProtocolPacketMatch;
13✔
403
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].Setup = DetectAppLayerProtocolSetup;
13✔
404
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].Free = DetectAppLayerProtocolFree;
13✔
405
#ifdef UNITTESTS
3✔
406
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].RegisterTests = DetectAppLayerProtocolRegisterTests;
3✔
407
#endif
3✔
408
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].flags =
13✔
409
            (SIGMATCH_QUOTES_OPTIONAL | SIGMATCH_HANDLE_NEGATION | SIGMATCH_SUPPORT_FIREWALL);
13✔
410

411
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].SetupPrefilter = PrefilterSetupAppProto;
13✔
412
    sigmatch_table[DETECT_APP_LAYER_PROTOCOL].SupportsPrefilter = PrefilterAppProtoIsPrefilterable;
13✔
413
}
13✔
414

415
/**********************************Unittests***********************************/
416

417
#ifdef UNITTESTS
418

419
static int DetectAppLayerProtocolTest01(void)
420
{
1✔
421
    DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", false);
1✔
422
    FAIL_IF_NULL(data);
1✔
423
    FAIL_IF(data->alproto != ALPROTO_HTTP);
1✔
424
    FAIL_IF(data->negated != 0);
1✔
425
    DetectAppLayerProtocolFree(NULL, data);
1✔
426
    PASS;
1✔
427
}
1✔
428

429
static int DetectAppLayerProtocolTest02(void)
430
{
1✔
431
    DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", true);
1✔
432
    FAIL_IF_NULL(data);
1✔
433
    FAIL_IF(data->alproto != ALPROTO_HTTP);
1✔
434
    FAIL_IF(data->negated == 0);
1✔
435
    DetectAppLayerProtocolFree(NULL, data);
1✔
436
    PASS;
1✔
437
}
1✔
438

439
static int DetectAppLayerProtocolTest03(void)
440
{
1✔
441
    Signature *s = NULL;
1✔
442
    DetectAppLayerProtocolData *data = NULL;
1✔
443
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
444
    FAIL_IF_NULL(de_ctx);
1✔
445
    de_ctx->flags |= DE_QUIET;
1✔
446

447
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
448
            "(app-layer-protocol:http; sid:1;)");
1✔
449
    FAIL_IF_NULL(s);
1✔
450

451
    FAIL_IF(s->alproto != ALPROTO_UNKNOWN);
1✔
452

453
    FAIL_IF_NULL(s->init_data->smlists[DETECT_SM_LIST_MATCH]);
1✔
454
    FAIL_IF_NULL(s->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx);
1✔
455

456
    data = (DetectAppLayerProtocolData *)s->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx;
1✔
457
    FAIL_IF(data->alproto != ALPROTO_HTTP);
1✔
458
    FAIL_IF(data->negated);
1✔
459
    DetectEngineCtxFree(de_ctx);
1✔
460
    PASS;
1✔
461
}
1✔
462

463
static int DetectAppLayerProtocolTest04(void)
464
{
1✔
465
    Signature *s = NULL;
1✔
466
    DetectAppLayerProtocolData *data = NULL;
1✔
467
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
468
    FAIL_IF_NULL(de_ctx);
1✔
469
    de_ctx->flags |= DE_QUIET;
1✔
470

471
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
472
            "(app-layer-protocol:!http; sid:1;)");
1✔
473
    FAIL_IF_NULL(s);
1✔
474
    FAIL_IF(s->alproto != ALPROTO_UNKNOWN);
1✔
475
    FAIL_IF(s->flags & SIG_FLAG_APPLAYER);
1✔
476

477
    FAIL_IF_NULL(s->init_data->smlists[DETECT_SM_LIST_MATCH]);
1✔
478
    FAIL_IF_NULL(s->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx);
1✔
479

480
    data = (DetectAppLayerProtocolData *)s->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx;
1✔
481
    FAIL_IF_NULL(data);
1✔
482
    FAIL_IF(data->alproto != ALPROTO_HTTP);
1✔
483
    FAIL_IF(data->negated == 0);
1✔
484

485
    DetectEngineCtxFree(de_ctx);
1✔
486
    PASS;
1✔
487
}
1✔
488

489
static int DetectAppLayerProtocolTest05(void)
490
{
1✔
491
    Signature *s = NULL;
1✔
492
    DetectAppLayerProtocolData *data = NULL;
1✔
493
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
494
    FAIL_IF_NULL(de_ctx);
1✔
495
    de_ctx->flags |= DE_QUIET;
1✔
496

497
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
498
            "(app-layer-protocol:!http; app-layer-protocol:!smtp; sid:1;)");
1✔
499
    FAIL_IF_NULL(s);
1✔
500
    FAIL_IF(s->alproto != ALPROTO_UNKNOWN);
1✔
501
    FAIL_IF(s->flags & SIG_FLAG_APPLAYER);
1✔
502

503
    FAIL_IF_NULL(s->init_data->smlists[DETECT_SM_LIST_MATCH]);
1✔
504
    FAIL_IF_NULL(s->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx);
1✔
505

506
    data = (DetectAppLayerProtocolData *)s->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx;
1✔
507
    FAIL_IF_NULL(data);
1✔
508
    FAIL_IF(data->alproto != ALPROTO_HTTP);
1✔
509
    FAIL_IF(data->negated == 0);
1✔
510

511
    data = (DetectAppLayerProtocolData *)s->init_data->smlists[DETECT_SM_LIST_MATCH]->next->ctx;
1✔
512
    FAIL_IF_NULL(data);
1✔
513
    FAIL_IF(data->alproto != ALPROTO_SMTP);
1✔
514
    FAIL_IF(data->negated == 0);
1✔
515

516
    DetectEngineCtxFree(de_ctx);
1✔
517
    PASS;
1✔
518
}
1✔
519

520
static int DetectAppLayerProtocolTest06(void)
521
{
1✔
522
    Signature *s = NULL;
1✔
523
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
524
    FAIL_IF_NULL(de_ctx);
1✔
525
    de_ctx->flags |= DE_QUIET;
1✔
526

527
    s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1✔
528
            "(app-layer-protocol:smtp; sid:1;)");
1✔
529
    FAIL_IF_NOT_NULL(s);
1✔
530
    DetectEngineCtxFree(de_ctx);
1✔
531
    PASS;
1✔
532
}
1✔
533

534
static int DetectAppLayerProtocolTest07(void)
535
{
1✔
536
    Signature *s = NULL;
1✔
537
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
538
    FAIL_IF_NULL(de_ctx);
1✔
539
    de_ctx->flags |= DE_QUIET;
1✔
540

541
    s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
1✔
542
            "(app-layer-protocol:!smtp; sid:1;)");
1✔
543
    FAIL_IF_NOT_NULL(s);
1✔
544
    DetectEngineCtxFree(de_ctx);
1✔
545
    PASS;
1✔
546
}
1✔
547

548
static int DetectAppLayerProtocolTest08(void)
549
{
1✔
550
    Signature *s = NULL;
1✔
551
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
552
    FAIL_IF_NULL(de_ctx);
1✔
553
    de_ctx->flags |= DE_QUIET;
1✔
554

555
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
556
            "(app-layer-protocol:!smtp; app-layer-protocol:http; sid:1;)");
1✔
557
    FAIL_IF_NOT_NULL(s);
1✔
558
    DetectEngineCtxFree(de_ctx);
1✔
559
    PASS;
1✔
560
}
1✔
561

562
static int DetectAppLayerProtocolTest09(void)
563
{
1✔
564
    Signature *s = NULL;
1✔
565
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
566
    FAIL_IF_NULL(de_ctx);
1✔
567
    de_ctx->flags |= DE_QUIET;
1✔
568

569
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
570
            "(app-layer-protocol:http; app-layer-protocol:!smtp; sid:1;)");
1✔
571
    FAIL_IF_NOT_NULL(s);
1✔
572
    DetectEngineCtxFree(de_ctx);
1✔
573
    PASS;
1✔
574
}
1✔
575

576
static int DetectAppLayerProtocolTest10(void)
577
{
1✔
578
    Signature *s = NULL;
1✔
579
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
580
    FAIL_IF_NULL(de_ctx);
1✔
581
    de_ctx->flags |= DE_QUIET;
1✔
582

583
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
584
            "(app-layer-protocol:smtp; app-layer-protocol:!http; sid:1;)");
1✔
585
    FAIL_IF_NOT_NULL(s);
1✔
586
    DetectEngineCtxFree(de_ctx);
1✔
587
    PASS;
1✔
588
}
1✔
589

590
static int DetectAppLayerProtocolTest11(void)
591
{
1✔
592
    DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("failed", false);
1✔
593
    FAIL_IF_NULL(data);
1✔
594
    FAIL_IF(data->alproto != ALPROTO_FAILED);
1✔
595
    FAIL_IF(data->negated != 0);
1✔
596
    DetectAppLayerProtocolFree(NULL, data);
1✔
597
    PASS;
1✔
598
}
1✔
599

600
static int DetectAppLayerProtocolTest12(void)
601
{
1✔
602
    DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("failed", true);
1✔
603
    FAIL_IF_NULL(data);
1✔
604
    FAIL_IF(data->alproto != ALPROTO_FAILED);
1✔
605
    FAIL_IF(data->negated == 0);
1✔
606
    DetectAppLayerProtocolFree(NULL, data);
1✔
607
    PASS;
1✔
608
}
1✔
609

610
static int DetectAppLayerProtocolTest13(void)
611
{
1✔
612
    Signature *s = NULL;
1✔
613
    DetectAppLayerProtocolData *data = NULL;
1✔
614
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
615
    FAIL_IF_NULL(de_ctx);
1✔
616
    de_ctx->flags |= DE_QUIET;
1✔
617

618
    s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
619
            "(app-layer-protocol:failed; sid:1;)");
1✔
620
    FAIL_IF_NULL(s);
1✔
621

622
    FAIL_IF(s->alproto != ALPROTO_UNKNOWN);
1✔
623

624
    FAIL_IF_NULL(s->init_data->smlists[DETECT_SM_LIST_MATCH]);
1✔
625
    FAIL_IF_NULL(s->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx);
1✔
626

627
    data = (DetectAppLayerProtocolData *)s->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx;
1✔
628
    FAIL_IF(data->alproto != ALPROTO_FAILED);
1✔
629
    FAIL_IF(data->negated);
1✔
630
    DetectEngineCtxFree(de_ctx);
1✔
631
    PASS;
1✔
632
}
1✔
633

634
static int DetectAppLayerProtocolTest14(void)
635
{
1✔
636
    DetectAppLayerProtocolData *data = NULL;
1✔
637
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
638
    FAIL_IF_NULL(de_ctx);
1✔
639
    de_ctx->flags |= DE_QUIET;
1✔
640

641
    Signature *s1 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
642
            "(app-layer-protocol:http; flowbits:set,blah; sid:1;)");
1✔
643
    FAIL_IF_NULL(s1);
1✔
644
    FAIL_IF(s1->alproto != ALPROTO_UNKNOWN);
1✔
645
    FAIL_IF_NULL(s1->init_data->smlists[DETECT_SM_LIST_MATCH]);
1✔
646
    FAIL_IF_NULL(s1->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx);
1✔
647
    data = (DetectAppLayerProtocolData *)s1->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx;
1✔
648
    FAIL_IF(data->alproto != ALPROTO_HTTP);
1✔
649
    FAIL_IF(data->negated);
1✔
650

651
    Signature *s2 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
652
            "(app-layer-protocol:http; flow:to_client; sid:2;)");
1✔
653
    FAIL_IF_NULL(s2);
1✔
654
    FAIL_IF(s2->alproto != ALPROTO_UNKNOWN);
1✔
655
    FAIL_IF_NULL(s2->init_data->smlists[DETECT_SM_LIST_MATCH]);
1✔
656
    FAIL_IF_NULL(s2->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx);
1✔
657
    data = (DetectAppLayerProtocolData *)s2->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx;
1✔
658
    FAIL_IF(data->alproto != ALPROTO_HTTP);
1✔
659
    FAIL_IF(data->negated);
1✔
660

661
    /* flow:established and other options not supported for PD-only */
662
    Signature *s3 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
1✔
663
            "(app-layer-protocol:http; flow:to_client,established; sid:3;)");
1✔
664
    FAIL_IF_NULL(s3);
1✔
665
    FAIL_IF(s3->alproto != ALPROTO_UNKNOWN);
1✔
666
    FAIL_IF_NULL(s3->init_data->smlists[DETECT_SM_LIST_MATCH]);
1✔
667
    FAIL_IF_NULL(s3->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx);
1✔
668
    data = (DetectAppLayerProtocolData *)s3->init_data->smlists[DETECT_SM_LIST_MATCH]->ctx;
1✔
669
    FAIL_IF(data->alproto != ALPROTO_HTTP);
1✔
670
    FAIL_IF(data->negated);
1✔
671

672
    SigGroupBuild(de_ctx);
1✔
673
    FAIL_IF_NOT(s1->type == SIG_TYPE_PDONLY);
1✔
674
    FAIL_IF_NOT(s2->type == SIG_TYPE_PDONLY);
1✔
675
    FAIL_IF(s3->type == SIG_TYPE_PDONLY); // failure now
1✔
676

677
    DetectEngineCtxFree(de_ctx);
1✔
678
    PASS;
1✔
679
}
1✔
680

681

682
static void DetectAppLayerProtocolRegisterTests(void)
683
{
1✔
684
    UtRegisterTest("DetectAppLayerProtocolTest01",
1✔
685
                   DetectAppLayerProtocolTest01);
1✔
686
    UtRegisterTest("DetectAppLayerProtocolTest02",
1✔
687
                   DetectAppLayerProtocolTest02);
1✔
688
    UtRegisterTest("DetectAppLayerProtocolTest03",
1✔
689
                   DetectAppLayerProtocolTest03);
1✔
690
    UtRegisterTest("DetectAppLayerProtocolTest04",
1✔
691
                   DetectAppLayerProtocolTest04);
1✔
692
    UtRegisterTest("DetectAppLayerProtocolTest05",
1✔
693
                   DetectAppLayerProtocolTest05);
1✔
694
    UtRegisterTest("DetectAppLayerProtocolTest06",
1✔
695
                   DetectAppLayerProtocolTest06);
1✔
696
    UtRegisterTest("DetectAppLayerProtocolTest07",
1✔
697
                   DetectAppLayerProtocolTest07);
1✔
698
    UtRegisterTest("DetectAppLayerProtocolTest08",
1✔
699
                   DetectAppLayerProtocolTest08);
1✔
700
    UtRegisterTest("DetectAppLayerProtocolTest09",
1✔
701
                   DetectAppLayerProtocolTest09);
1✔
702
    UtRegisterTest("DetectAppLayerProtocolTest10",
1✔
703
                   DetectAppLayerProtocolTest10);
1✔
704
    UtRegisterTest("DetectAppLayerProtocolTest11",
1✔
705
                   DetectAppLayerProtocolTest11);
1✔
706
    UtRegisterTest("DetectAppLayerProtocolTest12",
1✔
707
                   DetectAppLayerProtocolTest12);
1✔
708
    UtRegisterTest("DetectAppLayerProtocolTest13",
1✔
709
                   DetectAppLayerProtocolTest13);
1✔
710
    UtRegisterTest("DetectAppLayerProtocolTest14",
1✔
711
                   DetectAppLayerProtocolTest14);
1✔
712
}
1✔
713
#endif /* UNITTESTS */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc