]>
Commit | Line | Data |
---|---|---|
429c6388 | 1 | /* Copyright (C) 2007-2014 Open Information Security Foundation |
ce019275 WM |
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 | */ | |
c957dc77 | 17 | |
429c6388 AS |
18 | /** |
19 | * \file | |
4369816c | 20 | * |
429c6388 AS |
21 | * \author Victor Julien <victor@inliniac.net> |
22 | * \author Anoop Saldanha <anoopsaldanha@gmail.com> | |
4369816c VJ |
23 | */ |
24 | ||
ecf86f9c | 25 | #include "suricata-common.h" |
1c2240cf VJ |
26 | #include "debug.h" |
27 | #include "decode.h" | |
28 | #include "threads.h" | |
53c21410 AS |
29 | #include "threadvars.h" |
30 | #include "tm-threads.h" | |
1c2240cf | 31 | |
4369816c | 32 | #include "detect.h" |
429c6388 | 33 | #include "detect-engine-port.h" |
c6e090f7 | 34 | #include "detect-parse.h" |
4369816c VJ |
35 | #include "detect-engine.h" |
36 | #include "detect-content.h" | |
999a200b | 37 | #include "detect-engine-mpm.h" |
c6e090f7 | 38 | #include "detect-engine-state.h" |
4369816c | 39 | |
1c2240cf VJ |
40 | #include "util-print.h" |
41 | #include "util-pool.h" | |
4369816c | 42 | #include "util-unittest.h" |
c6e090f7 PR |
43 | #include "util-unittest-helper.h" |
44 | ||
45 | #include "flow.h" | |
46 | #include "flow-util.h" | |
429c6388 | 47 | #include "flow-private.h" |
1c2240cf VJ |
48 | |
49 | #include "stream-tcp-private.h" | |
fa5939ca | 50 | #include "stream-tcp-reassemble.h" |
6a53ab9c | 51 | #include "stream-tcp.h" |
1c2240cf VJ |
52 | #include "stream.h" |
53 | ||
429c6388 | 54 | #include "app-layer.h" |
8e10844f | 55 | #include "app-layer-protos.h" |
fa5939ca | 56 | #include "app-layer-parser.h" |
41e6735b | 57 | #include "app-layer-detect-proto.h" |
1c2240cf | 58 | |
429c6388 AS |
59 | #include "conf.h" |
60 | #include "util-memcmp.h" | |
7a427ec7 | 61 | #include "util-spm.h" |
41e6735b | 62 | #include "util-cuda.h" |
3a28171f VJ |
63 | #include "util-debug.h" |
64 | ||
429c6388 AS |
65 | #include "runmodes.h" |
66 | ||
67 | typedef struct AppLayerProtoDetectProbingParserElement_ { | |
f5f14880 | 68 | AppProto alproto; |
429c6388 AS |
69 | /* \todo don't really need it. See if you can get rid of it */ |
70 | uint16_t port; | |
71 | /* \todo calculate at runtime and get rid of this var */ | |
72 | uint32_t alproto_mask; | |
73 | /* \todo check if we can reduce the bottom 2 vars to uint16_t */ | |
74 | /* the min length of data that has to be supplied to invoke the parser */ | |
75 | uint32_t min_depth; | |
76 | /* the max length of data after which this parser won't be invoked */ | |
77 | uint32_t max_depth; | |
78 | /* the probing parser function */ | |
79 | ProbingParserFPtr ProbingParser; | |
80 | ||
81 | struct AppLayerProtoDetectProbingParserElement_ *next; | |
82 | } AppLayerProtoDetectProbingParserElement; | |
83 | ||
84 | typedef struct AppLayerProtoDetectProbingParserPort_ { | |
85 | /* the port no for which probing parser(s) are invoked */ | |
86 | uint16_t port; | |
87 | ||
3df90447 | 88 | uint32_t alproto_mask; |
eae5b1ba | 89 | |
429c6388 | 90 | /* the max depth for all the probing parsers registered for this port */ |
eae5b1ba VJ |
91 | uint16_t dp_max_depth; |
92 | uint16_t sp_max_depth; | |
429c6388 | 93 | |
eae5b1ba VJ |
94 | AppLayerProtoDetectProbingParserElement *dp; |
95 | AppLayerProtoDetectProbingParserElement *sp; | |
429c6388 AS |
96 | |
97 | struct AppLayerProtoDetectProbingParserPort_ *next; | |
98 | } AppLayerProtoDetectProbingParserPort; | |
99 | ||
100 | typedef struct AppLayerProtoDetectProbingParser_ { | |
1f00ff6a | 101 | uint8_t ipproto; |
429c6388 AS |
102 | AppLayerProtoDetectProbingParserPort *port; |
103 | ||
104 | struct AppLayerProtoDetectProbingParser_ *next; | |
105 | } AppLayerProtoDetectProbingParser; | |
106 | ||
107 | typedef struct AppLayerProtoDetectPMSignature_ { | |
108 | AppProto alproto; | |
109 | /* \todo Change this into a non-pointer */ | |
110 | DetectContentData *cd; | |
111 | struct AppLayerProtoDetectPMSignature_ *next; | |
112 | } AppLayerProtoDetectPMSignature; | |
113 | ||
114 | typedef struct AppLayerProtoDetectPMCtx_ { | |
115 | uint16_t max_len; | |
116 | uint16_t min_len; | |
117 | MpmCtx mpm_ctx; | |
4369816c | 118 | |
429c6388 AS |
119 | /** Mapping between pattern id and signature. As each signature has a |
120 | * unique pattern with a unique id, we can lookup the signature by | |
121 | * the pattern id. */ | |
122 | AppLayerProtoDetectPMSignature **map; | |
123 | AppLayerProtoDetectPMSignature *head; | |
7a427ec7 | 124 | |
429c6388 AS |
125 | /* \todo we don't need this except at setup time. Get rid of it. */ |
126 | PatIntId max_pat_id; | |
127 | } AppLayerProtoDetectPMCtx; | |
7074ca37 | 128 | |
429c6388 AS |
129 | typedef struct AppLayerProtoDetectCtxIpproto_ { |
130 | /* 0 - toserver, 1 - toclient */ | |
131 | AppLayerProtoDetectPMCtx ctx_pm[2]; | |
132 | } AppLayerProtoDetectCtxIpproto; | |
4369816c | 133 | |
7a427ec7 | 134 | /** |
429c6388 | 135 | * \brief The app layer protocol detection context. |
7a427ec7 | 136 | */ |
429c6388 AS |
137 | typedef struct AppLayerProtoDetectCtx_ { |
138 | /* Context per ip_proto. | |
139 | * \todo Modify ctx_ipp to hold for only tcp and udp. The rest can be | |
140 | * implemented if needed. Waste of space otherwise. */ | |
141 | AppLayerProtoDetectCtxIpproto ctx_ipp[FLOW_PROTO_DEFAULT]; | |
7a427ec7 | 142 | |
429c6388 | 143 | AppLayerProtoDetectProbingParser *ctx_pp; |
4369816c | 144 | |
429c6388 AS |
145 | /* Indicates the protocols that have registered themselves |
146 | * for protocol detection. This table is independent of the | |
147 | * ipproto. */ | |
148 | char *alproto_names[ALPROTO_MAX]; | |
149 | } AppLayerProtoDetectCtx; | |
7a427ec7 | 150 | |
429c6388 AS |
151 | /** |
152 | * \brief The app layer protocol detection thread context. | |
153 | */ | |
446e68ad | 154 | struct AppLayerProtoDetectThreadCtx_ { |
429c6388 AS |
155 | PatternMatcherQueue pmq; |
156 | /* The value 2 is for direction(0 - toserver, 1 - toclient). */ | |
157 | MpmThreadCtx mpm_tctx[FLOW_PROTO_DEFAULT][2]; | |
446e68ad | 158 | }; |
7a427ec7 | 159 | |
429c6388 | 160 | /* The global app layer proto detection context. */ |
1f00ff6a | 161 | static AppLayerProtoDetectCtx alpd_ctx; |
7a427ec7 | 162 | |
429c6388 | 163 | /***** Static Internal Calls: Protocol Retrieval *****/ |
7a427ec7 | 164 | |
1f00ff6a VJ |
165 | /** \internal |
166 | * \brief Handle SPM search for Signature */ | |
167 | static AppProto AppLayerProtoDetectPMMatchSignature(const AppLayerProtoDetectPMSignature *s, | |
429c6388 | 168 | uint8_t *buf, uint16_t buflen, |
5cdeadb3 | 169 | uint8_t ipproto) |
5fe1dc1d GS |
170 | { |
171 | SCEnter(); | |
1f00ff6a | 172 | AppProto proto = ALPROTO_UNKNOWN; |
36bd4444 | 173 | uint8_t *found = NULL; |
7a427ec7 | 174 | |
429c6388 | 175 | if (s->cd->offset > buflen) { |
5fe1dc1d | 176 | SCLogDebug("s->co->offset (%"PRIu16") > buflen (%"PRIu16")", |
429c6388 | 177 | s->cd->offset, buflen); |
7a427ec7 | 178 | goto end; |
5fe1dc1d | 179 | } |
7a427ec7 | 180 | |
429c6388 | 181 | if (s->cd->depth > buflen) { |
5fe1dc1d | 182 | SCLogDebug("s->co->depth (%"PRIu16") > buflen (%"PRIu16")", |
429c6388 | 183 | s->cd->depth, buflen); |
7a427ec7 | 184 | goto end; |
5fe1dc1d | 185 | } |
7a427ec7 | 186 | |
429c6388 AS |
187 | uint8_t *sbuf = buf + s->cd->offset; |
188 | uint16_t sbuflen = s->cd->depth - s->cd->offset; | |
189 | SCLogDebug("s->co->offset (%"PRIu16") s->cd->depth (%"PRIu16")", | |
190 | s->cd->offset, s->cd->depth); | |
7a427ec7 | 191 | |
429c6388 | 192 | if (s->cd->flags & DETECT_CONTENT_NOCASE) |
967f7aef | 193 | found = BoyerMooreNocase(s->cd->content, s->cd->content_len, sbuf, sbuflen, s->cd->bm_ctx); |
36bd4444 | 194 | else |
967f7aef | 195 | found = BoyerMoore(s->cd->content, s->cd->content_len, sbuf, sbuflen, s->cd->bm_ctx); |
36bd4444 | 196 | if (found != NULL) |
429c6388 | 197 | proto = s->alproto; |
7a427ec7 | 198 | |
429c6388 | 199 | end: |
1f00ff6a | 200 | SCReturnUInt(proto); |
5c8d90af GS |
201 | } |
202 | ||
1f00ff6a VJ |
203 | /** \internal |
204 | * \brief Run Pattern Sigs against buffer | |
205 | * \param pm_results[out] AppProto array of size ALPROTO_MAX */ | |
206 | static AppProto AppLayerProtoDetectPMGetProto(AppLayerProtoDetectThreadCtx *tctx, | |
429c6388 AS |
207 | Flow *f, |
208 | uint8_t *buf, uint16_t buflen, | |
209 | uint8_t direction, | |
210 | uint8_t ipproto, | |
211 | AppProto *pm_results) | |
36bd4444 | 212 | { |
7deb4e9f | 213 | SCEnter(); |
4369816c | 214 | |
00f546e7 AS |
215 | pm_results[0] = ALPROTO_UNKNOWN; |
216 | ||
429c6388 AS |
217 | AppLayerProtoDetectPMCtx *pm_ctx; |
218 | MpmThreadCtx *mpm_tctx; | |
219 | uint16_t pm_matches = 0; | |
220 | uint8_t cnt; | |
221 | uint16_t searchlen; | |
7a427ec7 | 222 | |
634eb1d3 VJ |
223 | if (f->protomap >= FLOW_PROTO_DEFAULT) |
224 | return ALPROTO_UNKNOWN; | |
225 | ||
429c6388 | 226 | if (direction & STREAM_TOSERVER) { |
634eb1d3 VJ |
227 | pm_ctx = &alpd_ctx.ctx_ipp[f->protomap].ctx_pm[0]; |
228 | mpm_tctx = &tctx->mpm_tctx[f->protomap][0]; | |
4369816c | 229 | } else { |
634eb1d3 VJ |
230 | pm_ctx = &alpd_ctx.ctx_ipp[f->protomap].ctx_pm[1]; |
231 | mpm_tctx = &tctx->mpm_tctx[f->protomap][1]; | |
4369816c | 232 | } |
429c6388 | 233 | if (pm_ctx->mpm_ctx.pattern_cnt == 0) |
c044541b | 234 | goto end; |
1c2240cf | 235 | |
429c6388 AS |
236 | searchlen = buflen; |
237 | if (searchlen > pm_ctx->max_len) | |
238 | searchlen = pm_ctx->max_len; | |
5e8413ae | 239 | |
00f546e7 | 240 | uint32_t search_cnt = 0; |
7a427ec7 VJ |
241 | |
242 | /* do the mpm search */ | |
429c6388 AS |
243 | search_cnt = mpm_table[pm_ctx->mpm_ctx.mpm_type].Search(&pm_ctx->mpm_ctx, |
244 | mpm_tctx, | |
245 | &tctx->pmq, | |
246 | buf, searchlen); | |
00f546e7 | 247 | if (search_cnt == 0) |
7a427ec7 | 248 | goto end; |
5fe1dc1d | 249 | |
00f546e7 | 250 | /* alproto bit field */ |
429c6388 | 251 | uint8_t pm_results_bf[(ALPROTO_MAX / 8) + 1]; |
00f546e7 AS |
252 | memset(pm_results_bf, 0, sizeof(pm_results_bf)); |
253 | ||
9952db6d VJ |
254 | /* loop through unique pattern id's. Can't use search_cnt here, |
255 | * as that contains all matches, tctx->pmq.pattern_id_array_cnt | |
256 | * contains only *unique* matches. */ | |
257 | for (cnt = 0; cnt < tctx->pmq.pattern_id_array_cnt; cnt++) { | |
1f00ff6a | 258 | const AppLayerProtoDetectPMSignature *s = pm_ctx->map[tctx->pmq.pattern_id_array[cnt]]; |
00f546e7 | 259 | while (s != NULL) { |
1f00ff6a VJ |
260 | AppProto proto = AppLayerProtoDetectPMMatchSignature(s, |
261 | buf, searchlen, ipproto); | |
262 | ||
263 | /* store each unique proto once */ | |
429c6388 AS |
264 | if (proto != ALPROTO_UNKNOWN && |
265 | !(pm_results_bf[proto / 8] & (1 << (proto % 8))) ) | |
1f00ff6a VJ |
266 | { |
267 | pm_results[pm_matches++] = proto; | |
268 | pm_results_bf[proto / 8] |= 1 << (proto % 8); | |
269 | } | |
429c6388 | 270 | s = s->next; |
5fe1dc1d GS |
271 | } |
272 | } | |
4369816c | 273 | |
429c6388 AS |
274 | end: |
275 | PmqReset(&tctx->pmq); | |
276 | if (buflen >= pm_ctx->max_len) | |
277 | FLOW_SET_PM_DONE(f, direction); | |
278 | SCReturnUInt(pm_matches); | |
279 | } | |
4369816c | 280 | |
429c6388 | 281 | static AppLayerProtoDetectProbingParserPort *AppLayerProtoDetectGetProbingParsers(AppLayerProtoDetectProbingParser *pp, |
1f00ff6a | 282 | uint8_t ipproto, |
429c6388 AS |
283 | uint16_t port) |
284 | { | |
285 | AppLayerProtoDetectProbingParserPort *pp_port = NULL; | |
286 | ||
287 | while (pp != NULL) { | |
1f00ff6a | 288 | if (pp->ipproto == ipproto) |
73bdc8a5 | 289 | break; |
429c6388 AS |
290 | |
291 | pp = pp->next; | |
292 | } | |
293 | ||
294 | if (pp == NULL) | |
295 | goto end; | |
296 | ||
297 | pp_port = pp->port; | |
298 | while (pp_port != NULL) { | |
299 | if (pp_port->port == port || pp_port->port == 0) { | |
4369816c | 300 | break; |
429c6388 AS |
301 | } |
302 | pp_port = pp_port->next; | |
4369816c | 303 | } |
429c6388 AS |
304 | |
305 | end: | |
306 | SCReturnPtr(pp_port, "AppLayerProtoDetectProbingParserPort *"); | |
1c2240cf VJ |
307 | } |
308 | ||
7c31a232 | 309 | /** |
eae5b1ba VJ |
310 | * \brief Call the probing parser if it exists for this flow. |
311 | * | |
312 | * First we check the flow's dp as it's most likely to match. If that didn't | |
313 | * lead to a PP, we try the sp. | |
314 | * | |
7c31a232 | 315 | */ |
429c6388 AS |
316 | static AppProto AppLayerProtoDetectPPGetProto(Flow *f, |
317 | uint8_t *buf, uint32_t buflen, | |
318 | uint8_t ipproto, uint8_t direction) | |
7c31a232 | 319 | { |
8252416c VJ |
320 | const AppLayerProtoDetectProbingParserPort *pp_port_dp = NULL; |
321 | const AppLayerProtoDetectProbingParserPort *pp_port_sp = NULL; | |
1f00ff6a | 322 | const AppLayerProtoDetectProbingParserElement *pe = NULL; |
8252416c VJ |
323 | const AppLayerProtoDetectProbingParserElement *pe1 = NULL; |
324 | const AppLayerProtoDetectProbingParserElement *pe2 = NULL; | |
429c6388 AS |
325 | AppProto alproto = ALPROTO_UNKNOWN; |
326 | uint32_t *alproto_masks; | |
8252416c | 327 | uint32_t mask = 0; |
429c6388 AS |
328 | |
329 | if (direction & STREAM_TOSERVER) { | |
eae5b1ba | 330 | /* first try the destination port */ |
8252416c | 331 | pp_port_dp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->dp); |
429c6388 | 332 | alproto_masks = &f->probing_parser_toserver_alproto_masks; |
8252416c VJ |
333 | if (pp_port_dp != NULL) { |
334 | SCLogDebug("toserver - Probing parser found for destination port %"PRIu16, f->dp); | |
335 | ||
336 | /* found based on destination port, so use dp registration */ | |
337 | pe1 = pp_port_dp->dp; | |
338 | } else { | |
eae5b1ba | 339 | SCLogDebug("toserver - No probing parser registered for dest port %"PRIu16, |
7c31a232 | 340 | f->dp); |
8252416c | 341 | } |
eae5b1ba | 342 | |
8252416c VJ |
343 | pp_port_sp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->sp); |
344 | if (pp_port_sp != NULL) { | |
345 | SCLogDebug("toserver - Probing parser found for source port %"PRIu16, f->sp); | |
346 | ||
347 | /* found based on source port, so use sp registration */ | |
348 | pe2 = pp_port_sp->sp; | |
349 | } else { | |
350 | SCLogDebug("toserver - No probing parser registered for source port %"PRIu16, | |
351 | f->sp); | |
7c31a232 | 352 | } |
7c31a232 | 353 | } else { |
eae5b1ba | 354 | /* first try the destination port */ |
8252416c | 355 | pp_port_dp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->dp); |
429c6388 | 356 | alproto_masks = &f->probing_parser_toclient_alproto_masks; |
8252416c VJ |
357 | if (pp_port_dp != NULL) { |
358 | SCLogDebug("toclient - Probing parser found for destination port %"PRIu16, f->dp); | |
359 | ||
360 | /* found based on destination port, so use dp registration */ | |
361 | pe1 = pp_port_dp->dp; | |
362 | } else { | |
eae5b1ba VJ |
363 | SCLogDebug("toclient - No probing parser registered for dest port %"PRIu16, |
364 | f->dp); | |
8252416c | 365 | } |
eae5b1ba | 366 | |
8252416c VJ |
367 | pp_port_sp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->sp); |
368 | if (pp_port_sp != NULL) { | |
369 | SCLogDebug("toclient - Probing parser found for source port %"PRIu16, f->sp); | |
eae5b1ba | 370 | |
8252416c VJ |
371 | pe2 = pp_port_sp->sp; |
372 | } else { | |
373 | SCLogDebug("toclient - No probing parser registered for source port %"PRIu16, | |
374 | f->sp); | |
7c31a232 | 375 | } |
8252416c VJ |
376 | } |
377 | ||
378 | if (pe1 == NULL && pe2 == NULL) { | |
379 | SCLogDebug("%s - No probing parsers found for either port", | |
380 | (direction & STREAM_TOSERVER) ? "toserver":"toclient"); | |
381 | FLOW_SET_PP_DONE(f, direction); | |
382 | goto end; | |
7c31a232 AS |
383 | } |
384 | ||
eae5b1ba | 385 | /* run the parser(s) */ |
8252416c | 386 | pe = pe1; |
7c31a232 | 387 | while (pe != NULL) { |
432c3317 | 388 | if ((buflen < pe->min_depth) || |
429c6388 | 389 | (alproto_masks[0] & pe->alproto_mask)) { |
7c31a232 AS |
390 | pe = pe->next; |
391 | continue; | |
392 | } | |
393 | ||
429c6388 | 394 | alproto = pe->ProbingParser(buf, buflen, NULL); |
d3989e7c | 395 | if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED) |
429c6388 | 396 | goto end; |
d3989e7c AS |
397 | if (alproto == ALPROTO_FAILED || |
398 | (pe->max_depth != 0 && buflen > pe->max_depth)) { | |
429c6388 | 399 | alproto_masks[0] |= pe->alproto_mask; |
432c3317 | 400 | } |
7c31a232 AS |
401 | pe = pe->next; |
402 | } | |
8252416c VJ |
403 | pe = pe2; |
404 | while (pe != NULL) { | |
405 | if ((buflen < pe->min_depth) || | |
406 | (alproto_masks[0] & pe->alproto_mask)) { | |
407 | pe = pe->next; | |
408 | continue; | |
409 | } | |
7c31a232 | 410 | |
8252416c VJ |
411 | alproto = pe->ProbingParser(buf, buflen, NULL); |
412 | if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED) | |
429c6388 | 413 | goto end; |
8252416c VJ |
414 | if (alproto == ALPROTO_FAILED || |
415 | (pe->max_depth != 0 && buflen > pe->max_depth)) { | |
416 | alproto_masks[0] |= pe->alproto_mask; | |
432c3317 | 417 | } |
8252416c VJ |
418 | pe = pe->next; |
419 | } | |
420 | ||
421 | /* get the mask we need for this direction */ | |
422 | if (pp_port_dp && pp_port_sp) | |
3df90447 | 423 | mask = pp_port_dp->alproto_mask|pp_port_sp->alproto_mask; |
8252416c | 424 | else if (pp_port_dp) |
3df90447 | 425 | mask = pp_port_dp->alproto_mask; |
8252416c | 426 | else if (pp_port_sp) |
3df90447 | 427 | mask = pp_port_sp->alproto_mask; |
8252416c VJ |
428 | else |
429 | mask = 0; | |
430 | ||
431 | if (alproto_masks[0] == mask) { | |
432 | FLOW_SET_PP_DONE(f, direction); | |
433 | SCLogDebug("%s, mask is now %08x, needed %08x, so done", | |
434 | (direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0], mask); | |
432c3317 | 435 | } else { |
8252416c VJ |
436 | SCLogDebug("%s, mask is now %08x, need %08x", |
437 | (direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0], mask); | |
432c3317 AS |
438 | } |
439 | ||
429c6388 | 440 | end: |
8252416c VJ |
441 | SCLogDebug("%s, mask is now %08x", |
442 | (direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0]); | |
443 | SCReturnUInt(alproto); | |
7c31a232 AS |
444 | } |
445 | ||
429c6388 AS |
446 | /***** Static Internal Calls: PP registration *****/ |
447 | ||
448 | static void AppLayerProtoDetectPPGetIpprotos(AppProto alproto, | |
449 | uint8_t *ipprotos) | |
450 | { | |
451 | SCEnter(); | |
452 | ||
1f00ff6a VJ |
453 | const AppLayerProtoDetectProbingParser *pp; |
454 | const AppLayerProtoDetectProbingParserPort *pp_port; | |
455 | const AppLayerProtoDetectProbingParserElement *pp_pe; | |
0d7159b5 | 456 | |
429c6388 AS |
457 | for (pp = alpd_ctx.ctx_pp; pp != NULL; pp = pp->next) { |
458 | for (pp_port = pp->port; pp_port != NULL; pp_port = pp_port->next) { | |
eae5b1ba | 459 | for (pp_pe = pp_port->dp; pp_pe != NULL; pp_pe = pp_pe->next) { |
429c6388 | 460 | if (alproto == pp_pe->alproto) |
1f00ff6a | 461 | ipprotos[pp->ipproto / 8] |= 1 << (pp->ipproto % 8); |
429c6388 | 462 | } |
eae5b1ba | 463 | for (pp_pe = pp_port->sp; pp_pe != NULL; pp_pe = pp_pe->next) { |
429c6388 | 464 | if (alproto == pp_pe->alproto) |
1f00ff6a | 465 | ipprotos[pp->ipproto / 8] |= 1 << (pp->ipproto % 8); |
429c6388 | 466 | } |
7c31a232 | 467 | } |
7c31a232 | 468 | } |
1c2240cf | 469 | |
429c6388 AS |
470 | SCReturn; |
471 | } | |
4369816c | 472 | |
f5f14880 | 473 | static uint32_t AppLayerProtoDetectProbingParserGetMask(AppProto alproto) |
429c6388 AS |
474 | { |
475 | SCEnter(); | |
4369816c | 476 | |
429c6388 AS |
477 | if (!(alproto > ALPROTO_UNKNOWN && alproto < ALPROTO_FAILED)) { |
478 | SCLogError(SC_ERR_ALPARSER, "Unknown protocol detected - %"PRIu16, | |
479 | alproto); | |
480 | exit(EXIT_FAILURE); | |
481 | } | |
4369816c | 482 | |
429c6388 AS |
483 | SCReturnUInt(1 << alproto); |
484 | } | |
4369816c | 485 | |
1f00ff6a | 486 | static AppLayerProtoDetectProbingParserElement *AppLayerProtoDetectProbingParserElementAlloc(void) |
429c6388 AS |
487 | { |
488 | SCEnter(); | |
4369816c | 489 | |
429c6388 AS |
490 | AppLayerProtoDetectProbingParserElement *p = SCMalloc(sizeof(AppLayerProtoDetectProbingParserElement)); |
491 | if (unlikely(p == NULL)) { | |
492 | exit(EXIT_FAILURE); | |
4369816c | 493 | } |
429c6388 | 494 | memset(p, 0, sizeof(AppLayerProtoDetectProbingParserElement)); |
4369816c | 495 | |
429c6388 | 496 | SCReturnPtr(p, "AppLayerProtoDetectProbingParserElement"); |
4369816c VJ |
497 | } |
498 | ||
4369816c | 499 | |
1f00ff6a | 500 | static void AppLayerProtoDetectProbingParserElementFree(AppLayerProtoDetectProbingParserElement *p) |
429c6388 AS |
501 | { |
502 | SCEnter(); | |
503 | SCFree(p); | |
504 | SCReturn; | |
505 | } | |
4369816c | 506 | |
1f00ff6a | 507 | static AppLayerProtoDetectProbingParserPort *AppLayerProtoDetectProbingParserPortAlloc(void) |
429c6388 AS |
508 | { |
509 | SCEnter(); | |
4369816c | 510 | |
429c6388 AS |
511 | AppLayerProtoDetectProbingParserPort *p = SCMalloc(sizeof(AppLayerProtoDetectProbingParserPort)); |
512 | if (unlikely(p == NULL)) { | |
513 | exit(EXIT_FAILURE); | |
4369816c | 514 | } |
429c6388 | 515 | memset(p, 0, sizeof(AppLayerProtoDetectProbingParserPort)); |
4369816c | 516 | |
429c6388 AS |
517 | SCReturnPtr(p, "AppLayerProtoDetectProbingParserPort"); |
518 | } | |
519 | ||
1f00ff6a | 520 | static void AppLayerProtoDetectProbingParserPortFree(AppLayerProtoDetectProbingParserPort *p) |
429c6388 AS |
521 | { |
522 | SCEnter(); | |
4369816c | 523 | |
429c6388 | 524 | AppLayerProtoDetectProbingParserElement *e; |
4369816c | 525 | |
eae5b1ba | 526 | e = p->dp; |
429c6388 AS |
527 | while (e != NULL) { |
528 | AppLayerProtoDetectProbingParserElement *e_next = e->next; | |
1f00ff6a | 529 | AppLayerProtoDetectProbingParserElementFree(e); |
429c6388 | 530 | e = e_next; |
4369816c VJ |
531 | } |
532 | ||
eae5b1ba | 533 | e = p->sp; |
429c6388 AS |
534 | while (e != NULL) { |
535 | AppLayerProtoDetectProbingParserElement *e_next = e->next; | |
1f00ff6a | 536 | AppLayerProtoDetectProbingParserElementFree(e); |
429c6388 | 537 | e = e_next; |
4369816c VJ |
538 | } |
539 | ||
429c6388 | 540 | SCFree(p); |
41e6735b | 541 | |
429c6388 | 542 | SCReturn; |
4369816c VJ |
543 | } |
544 | ||
1f00ff6a | 545 | static AppLayerProtoDetectProbingParser *AppLayerProtoDetectProbingParserAlloc(void) |
429c6388 AS |
546 | { |
547 | SCEnter(); | |
4369816c | 548 | |
429c6388 AS |
549 | AppLayerProtoDetectProbingParser *p = SCMalloc(sizeof(AppLayerProtoDetectProbingParser)); |
550 | if (unlikely(p == NULL)) { | |
551 | exit(EXIT_FAILURE); | |
552 | } | |
553 | memset(p, 0, sizeof(AppLayerProtoDetectProbingParser)); | |
4369816c | 554 | |
429c6388 AS |
555 | SCReturnPtr(p, "AppLayerProtoDetectProbingParser"); |
556 | } | |
4369816c | 557 | |
1f00ff6a | 558 | static void AppLayerProtoDetectProbingParserFree(AppLayerProtoDetectProbingParser *p) |
429c6388 AS |
559 | { |
560 | SCEnter(); | |
4369816c | 561 | |
429c6388 AS |
562 | AppLayerProtoDetectProbingParserPort *pt = p->port; |
563 | while (pt != NULL) { | |
564 | AppLayerProtoDetectProbingParserPort *pt_next = pt->next; | |
1f00ff6a | 565 | AppLayerProtoDetectProbingParserPortFree(pt); |
429c6388 | 566 | pt = pt_next; |
4369816c VJ |
567 | } |
568 | ||
429c6388 | 569 | SCFree(p); |
4369816c | 570 | |
429c6388 AS |
571 | SCReturn; |
572 | } | |
4369816c | 573 | |
429c6388 | 574 | static AppLayerProtoDetectProbingParserElement * |
1f00ff6a VJ |
575 | AppLayerProtoDetectProbingParserElementCreate(AppProto alproto, |
576 | uint16_t port, | |
577 | uint16_t min_depth, | |
578 | uint16_t max_depth, | |
579 | uint16_t (*AppLayerProtoDetectProbingParser) | |
580 | (uint8_t *input, uint32_t input_len, uint32_t *offset)) | |
429c6388 | 581 | { |
1f00ff6a | 582 | AppLayerProtoDetectProbingParserElement *pe = AppLayerProtoDetectProbingParserElementAlloc(); |
429c6388 AS |
583 | |
584 | pe->alproto = alproto; | |
585 | pe->port = port; | |
586 | pe->alproto_mask = AppLayerProtoDetectProbingParserGetMask(alproto); | |
587 | pe->min_depth = min_depth; | |
588 | pe->max_depth = max_depth; | |
589 | pe->ProbingParser = AppLayerProtoDetectProbingParser; | |
590 | pe->next = NULL; | |
591 | ||
592 | if (max_depth != 0 && min_depth >= max_depth) { | |
593 | SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to " | |
594 | "register the probing parser. min_depth >= max_depth"); | |
595 | goto error; | |
596 | } | |
597 | if (alproto <= ALPROTO_UNKNOWN || alproto >= ALPROTO_MAX) { | |
598 | SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to register " | |
599 | "the probing parser. Invalid alproto - %d", alproto); | |
600 | goto error; | |
601 | } | |
602 | if (AppLayerProtoDetectProbingParser == NULL) { | |
603 | SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to " | |
604 | "register the probing parser. Probing parser func NULL"); | |
605 | goto error; | |
606 | } | |
607 | ||
608 | SCReturnPtr(pe, "AppLayerProtoDetectProbingParserElement"); | |
609 | error: | |
1f00ff6a | 610 | AppLayerProtoDetectProbingParserElementFree(pe); |
429c6388 AS |
611 | SCReturnPtr(NULL, "AppLayerProtoDetectProbingParserElement"); |
612 | } | |
4369816c | 613 | |
429c6388 | 614 | static AppLayerProtoDetectProbingParserElement * |
1f00ff6a | 615 | AppLayerProtoDetectProbingParserElementDuplicate(AppLayerProtoDetectProbingParserElement *pe) |
429c6388 AS |
616 | { |
617 | SCEnter(); | |
4369816c | 618 | |
1f00ff6a | 619 | AppLayerProtoDetectProbingParserElement *new_pe = AppLayerProtoDetectProbingParserElementAlloc(); |
4369816c | 620 | |
429c6388 AS |
621 | new_pe->alproto = pe->alproto; |
622 | new_pe->port = pe->port; | |
623 | new_pe->alproto_mask = pe->alproto_mask; | |
624 | new_pe->min_depth = pe->min_depth; | |
625 | new_pe->max_depth = pe->max_depth; | |
626 | new_pe->ProbingParser = pe->ProbingParser; | |
627 | new_pe->next = NULL; | |
41e6735b | 628 | |
429c6388 | 629 | SCReturnPtr(new_pe, "AppLayerProtoDetectProbingParserElement"); |
4369816c VJ |
630 | } |
631 | ||
429c6388 AS |
632 | void AppLayerProtoDetectPrintProbingParsers(AppLayerProtoDetectProbingParser *pp) |
633 | { | |
634 | SCEnter(); | |
4369816c | 635 | |
429c6388 AS |
636 | AppLayerProtoDetectProbingParserPort *pp_port = NULL; |
637 | AppLayerProtoDetectProbingParserElement *pp_pe = NULL; | |
638 | ||
eae5b1ba | 639 | printf("\nProtocol Detection Configuration\n"); |
429c6388 AS |
640 | |
641 | for ( ; pp != NULL; pp = pp->next) { | |
642 | /* print ip protocol */ | |
1f00ff6a | 643 | if (pp->ipproto == IPPROTO_TCP) |
429c6388 | 644 | printf("IPProto: TCP\n"); |
1f00ff6a | 645 | else if (pp->ipproto == IPPROTO_UDP) |
429c6388 AS |
646 | printf("IPProto: UDP\n"); |
647 | else | |
1f00ff6a | 648 | printf("IPProto: %"PRIu16"\n", pp->ipproto); |
429c6388 AS |
649 | |
650 | pp_port = pp->port; | |
651 | for ( ; pp_port != NULL; pp_port = pp_port->next) { | |
eae5b1ba VJ |
652 | if (pp_port->dp != NULL) { |
653 | printf(" Port: %"PRIu16 "\n", pp_port->port); | |
654 | ||
655 | printf(" Destination port: (max-depth: %"PRIu16 ", " | |
656 | "mask - %"PRIu32")\n", | |
657 | pp_port->dp_max_depth, | |
3df90447 | 658 | pp_port->alproto_mask); |
eae5b1ba VJ |
659 | pp_pe = pp_port->dp; |
660 | for ( ; pp_pe != NULL; pp_pe = pp_pe->next) { | |
661 | ||
662 | if (pp_pe->alproto == ALPROTO_HTTP) | |
663 | printf(" alproto: ALPROTO_HTTP\n"); | |
664 | else if (pp_pe->alproto == ALPROTO_FTP) | |
665 | printf(" alproto: ALPROTO_FTP\n"); | |
666 | else if (pp_pe->alproto == ALPROTO_SMTP) | |
667 | printf(" alproto: ALPROTO_SMTP\n"); | |
668 | else if (pp_pe->alproto == ALPROTO_TLS) | |
669 | printf(" alproto: ALPROTO_TLS\n"); | |
670 | else if (pp_pe->alproto == ALPROTO_SSH) | |
671 | printf(" alproto: ALPROTO_SSH\n"); | |
672 | else if (pp_pe->alproto == ALPROTO_IMAP) | |
673 | printf(" alproto: ALPROTO_IMAP\n"); | |
674 | else if (pp_pe->alproto == ALPROTO_MSN) | |
675 | printf(" alproto: ALPROTO_MSN\n"); | |
676 | else if (pp_pe->alproto == ALPROTO_JABBER) | |
677 | printf(" alproto: ALPROTO_JABBER\n"); | |
678 | else if (pp_pe->alproto == ALPROTO_SMB) | |
679 | printf(" alproto: ALPROTO_SMB\n"); | |
680 | else if (pp_pe->alproto == ALPROTO_SMB2) | |
681 | printf(" alproto: ALPROTO_SMB2\n"); | |
682 | else if (pp_pe->alproto == ALPROTO_DCERPC) | |
683 | printf(" alproto: ALPROTO_DCERPC\n"); | |
684 | else if (pp_pe->alproto == ALPROTO_IRC) | |
685 | printf(" alproto: ALPROTO_IRC\n"); | |
686 | else if (pp_pe->alproto == ALPROTO_DNS) | |
687 | printf(" alproto: ALPROTO_DNS\n"); | |
688 | else | |
689 | printf("impossible\n"); | |
690 | ||
691 | printf(" port: %"PRIu16 "\n", pp_pe->port); | |
692 | printf(" mask: %"PRIu32 "\n", pp_pe->alproto_mask); | |
693 | printf(" min_depth: %"PRIu32 "\n", pp_pe->min_depth); | |
694 | printf(" max_depth: %"PRIu32 "\n", pp_pe->max_depth); | |
695 | ||
696 | printf("\n"); | |
697 | } | |
429c6388 | 698 | } |
4369816c | 699 | |
eae5b1ba | 700 | if (pp_port->sp == NULL) { |
429c6388 AS |
701 | continue; |
702 | } | |
4369816c | 703 | |
eae5b1ba | 704 | printf(" Source port: (max-depth: %"PRIu16 ", " |
429c6388 | 705 | "mask - %"PRIu32")\n", |
eae5b1ba | 706 | pp_port->sp_max_depth, |
3df90447 | 707 | pp_port->alproto_mask); |
eae5b1ba | 708 | pp_pe = pp_port->sp; |
429c6388 AS |
709 | for ( ; pp_pe != NULL; pp_pe = pp_pe->next) { |
710 | ||
711 | if (pp_pe->alproto == ALPROTO_HTTP) | |
712 | printf(" alproto: ALPROTO_HTTP\n"); | |
713 | else if (pp_pe->alproto == ALPROTO_FTP) | |
714 | printf(" alproto: ALPROTO_FTP\n"); | |
715 | else if (pp_pe->alproto == ALPROTO_SMTP) | |
716 | printf(" alproto: ALPROTO_SMTP\n"); | |
717 | else if (pp_pe->alproto == ALPROTO_TLS) | |
718 | printf(" alproto: ALPROTO_TLS\n"); | |
719 | else if (pp_pe->alproto == ALPROTO_SSH) | |
720 | printf(" alproto: ALPROTO_SSH\n"); | |
721 | else if (pp_pe->alproto == ALPROTO_IMAP) | |
722 | printf(" alproto: ALPROTO_IMAP\n"); | |
723 | else if (pp_pe->alproto == ALPROTO_MSN) | |
724 | printf(" alproto: ALPROTO_MSN\n"); | |
725 | else if (pp_pe->alproto == ALPROTO_JABBER) | |
726 | printf(" alproto: ALPROTO_JABBER\n"); | |
727 | else if (pp_pe->alproto == ALPROTO_SMB) | |
728 | printf(" alproto: ALPROTO_SMB\n"); | |
729 | else if (pp_pe->alproto == ALPROTO_SMB2) | |
730 | printf(" alproto: ALPROTO_SMB2\n"); | |
731 | else if (pp_pe->alproto == ALPROTO_DCERPC) | |
732 | printf(" alproto: ALPROTO_DCERPC\n"); | |
733 | else if (pp_pe->alproto == ALPROTO_IRC) | |
734 | printf(" alproto: ALPROTO_IRC\n"); | |
eae5b1ba VJ |
735 | else if (pp_pe->alproto == ALPROTO_DNS) |
736 | printf(" alproto: ALPROTO_DNS\n"); | |
429c6388 AS |
737 | else |
738 | printf("impossible\n"); | |
739 | ||
740 | printf(" port: %"PRIu16 "\n", pp_pe->port); | |
741 | printf(" mask: %"PRIu32 "\n", pp_pe->alproto_mask); | |
742 | printf(" min_depth: %"PRIu32 "\n", pp_pe->min_depth); | |
743 | printf(" max_depth: %"PRIu32 "\n", pp_pe->max_depth); | |
744 | ||
745 | printf("\n"); | |
746 | } | |
747 | } | |
4369816c VJ |
748 | } |
749 | ||
429c6388 AS |
750 | SCReturn; |
751 | } | |
4369816c | 752 | |
1f00ff6a VJ |
753 | static void AppLayerProtoDetectProbingParserElementAppend(AppLayerProtoDetectProbingParserElement **head_pe, |
754 | AppLayerProtoDetectProbingParserElement *new_pe) | |
429c6388 AS |
755 | { |
756 | SCEnter(); | |
4369816c | 757 | |
429c6388 AS |
758 | if (*head_pe == NULL) { |
759 | *head_pe = new_pe; | |
760 | goto end; | |
4369816c VJ |
761 | } |
762 | ||
429c6388 AS |
763 | if ((*head_pe)->port == 0) { |
764 | if (new_pe->port != 0) { | |
765 | new_pe->next = *head_pe; | |
766 | *head_pe = new_pe; | |
767 | } else { | |
768 | AppLayerProtoDetectProbingParserElement *temp_pe = *head_pe; | |
769 | while (temp_pe->next != NULL) | |
770 | temp_pe = temp_pe->next; | |
771 | temp_pe->next = new_pe; | |
772 | } | |
773 | } else { | |
774 | AppLayerProtoDetectProbingParserElement *temp_pe = *head_pe; | |
775 | if (new_pe->port == 0) { | |
776 | while (temp_pe->next != NULL) | |
777 | temp_pe = temp_pe->next; | |
778 | temp_pe->next = new_pe; | |
779 | } else { | |
780 | while (temp_pe->next != NULL && temp_pe->next->port != 0) | |
781 | temp_pe = temp_pe->next; | |
782 | new_pe->next = temp_pe->next; | |
783 | temp_pe->next = new_pe; | |
41e6735b | 784 | |
429c6388 AS |
785 | } |
786 | } | |
787 | ||
788 | end: | |
789 | SCReturn; | |
4369816c VJ |
790 | } |
791 | ||
1f00ff6a VJ |
792 | static void AppLayerProtoDetectProbingParserAppend(AppLayerProtoDetectProbingParser **head_pp, |
793 | AppLayerProtoDetectProbingParser *new_pp) | |
429c6388 AS |
794 | { |
795 | SCEnter(); | |
796 | ||
797 | if (*head_pp == NULL) { | |
798 | *head_pp = new_pp; | |
799 | goto end; | |
800 | } | |
801 | ||
802 | AppLayerProtoDetectProbingParser *temp_pp = *head_pp; | |
803 | while (temp_pp->next != NULL) | |
804 | temp_pp = temp_pp->next; | |
805 | temp_pp->next = new_pp; | |
4369816c | 806 | |
429c6388 AS |
807 | end: |
808 | SCReturn; | |
809 | } | |
4369816c | 810 | |
1f00ff6a VJ |
811 | static void AppLayerProtoDetectProbingParserPortAppend(AppLayerProtoDetectProbingParserPort **head_port, |
812 | AppLayerProtoDetectProbingParserPort *new_port) | |
429c6388 AS |
813 | { |
814 | SCEnter(); | |
4369816c | 815 | |
429c6388 AS |
816 | if (*head_port == NULL) { |
817 | *head_port = new_port; | |
818 | goto end; | |
819 | } | |
4369816c | 820 | |
429c6388 AS |
821 | if ((*head_port)->port == 0) { |
822 | new_port->next = *head_port; | |
823 | *head_port = new_port; | |
824 | } else { | |
825 | AppLayerProtoDetectProbingParserPort *temp_port = *head_port; | |
826 | while (temp_port->next != NULL && temp_port->next->port != 0) { | |
827 | temp_port = temp_port->next; | |
828 | } | |
829 | new_port->next = temp_port->next; | |
830 | temp_port->next = new_port; | |
4369816c VJ |
831 | } |
832 | ||
429c6388 AS |
833 | end: |
834 | SCReturn; | |
835 | } | |
836 | ||
1f00ff6a VJ |
837 | static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbingParser **pp, |
838 | uint8_t ipproto, | |
429c6388 | 839 | uint16_t port, |
f5f14880 | 840 | AppProto alproto, |
429c6388 AS |
841 | uint16_t min_depth, uint16_t max_depth, |
842 | uint8_t direction, | |
843 | ProbingParserFPtr ProbingParser) | |
844 | { | |
845 | SCEnter(); | |
846 | ||
847 | /* get the top level ipproto pp */ | |
848 | AppLayerProtoDetectProbingParser *curr_pp = *pp; | |
849 | while (curr_pp != NULL) { | |
1f00ff6a | 850 | if (curr_pp->ipproto == ipproto) |
429c6388 AS |
851 | break; |
852 | curr_pp = curr_pp->next; | |
853 | } | |
854 | if (curr_pp == NULL) { | |
1f00ff6a VJ |
855 | AppLayerProtoDetectProbingParser *new_pp = AppLayerProtoDetectProbingParserAlloc(); |
856 | new_pp->ipproto = ipproto; | |
857 | AppLayerProtoDetectProbingParserAppend(pp, new_pp); | |
429c6388 | 858 | curr_pp = new_pp; |
4369816c VJ |
859 | } |
860 | ||
429c6388 AS |
861 | /* get the top level port pp */ |
862 | AppLayerProtoDetectProbingParserPort *curr_port = curr_pp->port; | |
863 | while (curr_port != NULL) { | |
864 | if (curr_port->port == port) | |
865 | break; | |
866 | curr_port = curr_port->next; | |
867 | } | |
868 | if (curr_port == NULL) { | |
1f00ff6a | 869 | AppLayerProtoDetectProbingParserPort *new_port = AppLayerProtoDetectProbingParserPortAlloc(); |
429c6388 | 870 | new_port->port = port; |
1f00ff6a | 871 | AppLayerProtoDetectProbingParserPortAppend(&curr_pp->port, new_port); |
429c6388 AS |
872 | curr_port = new_port; |
873 | if (direction & STREAM_TOSERVER) { | |
eae5b1ba | 874 | curr_port->dp_max_depth = max_depth; |
429c6388 | 875 | } else { |
eae5b1ba | 876 | curr_port->sp_max_depth = max_depth; |
429c6388 AS |
877 | } |
878 | ||
879 | AppLayerProtoDetectProbingParserPort *zero_port; | |
880 | ||
881 | zero_port = curr_pp->port; | |
882 | while (zero_port != NULL && zero_port->port != 0) { | |
883 | zero_port = zero_port->next; | |
884 | } | |
885 | if (zero_port != NULL) { | |
886 | AppLayerProtoDetectProbingParserElement *zero_pe; | |
887 | ||
eae5b1ba | 888 | zero_pe = zero_port->dp; |
429c6388 | 889 | for ( ; zero_pe != NULL; zero_pe = zero_pe->next) { |
eae5b1ba VJ |
890 | if (curr_port->dp == NULL) |
891 | curr_port->dp_max_depth = zero_pe->max_depth; | |
429c6388 | 892 | if (zero_pe->max_depth == 0) |
eae5b1ba VJ |
893 | curr_port->dp_max_depth = zero_pe->max_depth; |
894 | if (curr_port->dp_max_depth != 0 && | |
895 | curr_port->dp_max_depth < zero_pe->max_depth) { | |
896 | curr_port->dp_max_depth = zero_pe->max_depth; | |
429c6388 AS |
897 | } |
898 | ||
899 | AppLayerProtoDetectProbingParserElement *dup_pe = | |
1f00ff6a | 900 | AppLayerProtoDetectProbingParserElementDuplicate(zero_pe); |
eae5b1ba | 901 | AppLayerProtoDetectProbingParserElementAppend(&curr_port->dp, dup_pe); |
3df90447 | 902 | curr_port->alproto_mask |= dup_pe->alproto_mask; |
429c6388 AS |
903 | } |
904 | ||
eae5b1ba | 905 | zero_pe = zero_port->sp; |
429c6388 | 906 | for ( ; zero_pe != NULL; zero_pe = zero_pe->next) { |
eae5b1ba VJ |
907 | if (curr_port->sp == NULL) |
908 | curr_port->sp_max_depth = zero_pe->max_depth; | |
429c6388 | 909 | if (zero_pe->max_depth == 0) |
eae5b1ba VJ |
910 | curr_port->sp_max_depth = zero_pe->max_depth; |
911 | if (curr_port->sp_max_depth != 0 && | |
912 | curr_port->sp_max_depth < zero_pe->max_depth) { | |
913 | curr_port->sp_max_depth = zero_pe->max_depth; | |
429c6388 AS |
914 | } |
915 | ||
916 | AppLayerProtoDetectProbingParserElement *dup_pe = | |
1f00ff6a | 917 | AppLayerProtoDetectProbingParserElementDuplicate(zero_pe); |
eae5b1ba | 918 | AppLayerProtoDetectProbingParserElementAppend(&curr_port->sp, dup_pe); |
3df90447 | 919 | curr_port->alproto_mask |= dup_pe->alproto_mask; |
429c6388 AS |
920 | } |
921 | } /* if (zero_port != NULL) */ | |
922 | } /* if (curr_port == NULL) */ | |
923 | ||
924 | /* insert the pe_pp */ | |
925 | AppLayerProtoDetectProbingParserElement *curr_pe; | |
926 | if (direction & STREAM_TOSERVER) | |
eae5b1ba | 927 | curr_pe = curr_port->dp; |
429c6388 | 928 | else |
eae5b1ba | 929 | curr_pe = curr_port->sp; |
429c6388 AS |
930 | while (curr_pe != NULL) { |
931 | if (curr_pe->alproto == alproto) { | |
932 | SCLogError(SC_ERR_ALPARSER, "Duplicate pp registered - " | |
1f00ff6a | 933 | "ipproto - %"PRIu16" Port - %"PRIu16" " |
429c6388 AS |
934 | "App Protocol - NULL, App Protocol(ID) - " |
935 | "%"PRIu16" min_depth - %"PRIu16" " | |
936 | "max_dept - %"PRIu16".", | |
1f00ff6a | 937 | ipproto, port, alproto, |
429c6388 AS |
938 | min_depth, max_depth); |
939 | goto error; | |
940 | } | |
941 | curr_pe = curr_pe->next; | |
942 | } | |
943 | /* Get a new parser element */ | |
944 | AppLayerProtoDetectProbingParserElement *new_pe = | |
1f00ff6a VJ |
945 | AppLayerProtoDetectProbingParserElementCreate(alproto, |
946 | curr_port->port, | |
947 | min_depth, max_depth, | |
948 | ProbingParser); | |
429c6388 AS |
949 | if (new_pe == NULL) |
950 | goto error; | |
951 | curr_pe = new_pe; | |
952 | AppLayerProtoDetectProbingParserElement **head_pe; | |
953 | if (direction & STREAM_TOSERVER) { | |
eae5b1ba VJ |
954 | if (curr_port->dp == NULL) |
955 | curr_port->dp_max_depth = new_pe->max_depth; | |
429c6388 | 956 | if (new_pe->max_depth == 0) |
eae5b1ba VJ |
957 | curr_port->dp_max_depth = new_pe->max_depth; |
958 | if (curr_port->dp_max_depth != 0 && | |
959 | curr_port->dp_max_depth < new_pe->max_depth) { | |
960 | curr_port->dp_max_depth = new_pe->max_depth; | |
429c6388 | 961 | } |
3df90447 | 962 | curr_port->alproto_mask |= new_pe->alproto_mask; |
eae5b1ba | 963 | head_pe = &curr_port->dp; |
429c6388 | 964 | } else { |
eae5b1ba VJ |
965 | if (curr_port->sp == NULL) |
966 | curr_port->sp_max_depth = new_pe->max_depth; | |
429c6388 | 967 | if (new_pe->max_depth == 0) |
eae5b1ba VJ |
968 | curr_port->sp_max_depth = new_pe->max_depth; |
969 | if (curr_port->sp_max_depth != 0 && | |
970 | curr_port->sp_max_depth < new_pe->max_depth) { | |
971 | curr_port->sp_max_depth = new_pe->max_depth; | |
429c6388 | 972 | } |
3df90447 | 973 | curr_port->alproto_mask |= new_pe->alproto_mask; |
eae5b1ba | 974 | head_pe = &curr_port->sp; |
429c6388 | 975 | } |
1f00ff6a | 976 | AppLayerProtoDetectProbingParserElementAppend(head_pe, new_pe); |
429c6388 AS |
977 | |
978 | if (curr_port->port == 0) { | |
979 | AppLayerProtoDetectProbingParserPort *temp_port = curr_pp->port; | |
980 | while (temp_port != NULL && temp_port->port != 0) { | |
981 | if (direction & STREAM_TOSERVER) { | |
eae5b1ba VJ |
982 | if (temp_port->dp == NULL) |
983 | temp_port->dp_max_depth = curr_pe->max_depth; | |
429c6388 | 984 | if (curr_pe->max_depth == 0) |
eae5b1ba VJ |
985 | temp_port->dp_max_depth = curr_pe->max_depth; |
986 | if (temp_port->dp_max_depth != 0 && | |
987 | temp_port->dp_max_depth < curr_pe->max_depth) { | |
988 | temp_port->dp_max_depth = curr_pe->max_depth; | |
429c6388 | 989 | } |
eae5b1ba | 990 | AppLayerProtoDetectProbingParserElementAppend(&temp_port->dp, |
1f00ff6a | 991 | AppLayerProtoDetectProbingParserElementDuplicate(curr_pe)); |
3df90447 | 992 | temp_port->alproto_mask |= curr_pe->alproto_mask; |
429c6388 | 993 | } else { |
eae5b1ba VJ |
994 | if (temp_port->sp == NULL) |
995 | temp_port->sp_max_depth = curr_pe->max_depth; | |
429c6388 | 996 | if (curr_pe->max_depth == 0) |
eae5b1ba VJ |
997 | temp_port->sp_max_depth = curr_pe->max_depth; |
998 | if (temp_port->sp_max_depth != 0 && | |
999 | temp_port->sp_max_depth < curr_pe->max_depth) { | |
1000 | temp_port->sp_max_depth = curr_pe->max_depth; | |
429c6388 | 1001 | } |
eae5b1ba | 1002 | AppLayerProtoDetectProbingParserElementAppend(&temp_port->sp, |
1f00ff6a | 1003 | AppLayerProtoDetectProbingParserElementDuplicate(curr_pe)); |
3df90447 | 1004 | temp_port->alproto_mask |= curr_pe->alproto_mask; |
429c6388 AS |
1005 | } |
1006 | temp_port = temp_port->next; | |
1007 | } /* while */ | |
1008 | } /* if */ | |
1009 | ||
1010 | error: | |
1011 | SCReturn; | |
1012 | } | |
1013 | ||
1014 | /***** Static Internal Calls: PM registration *****/ | |
1015 | ||
1016 | static void AppLayerProtoDetectPMGetIpprotos(AppProto alproto, | |
1017 | uint8_t *ipprotos) | |
1018 | { | |
1019 | SCEnter(); | |
1020 | ||
1f00ff6a | 1021 | const AppLayerProtoDetectPMSignature *s = NULL; |
429c6388 AS |
1022 | int pat_id, max_pat_id; |
1023 | ||
1024 | int i, j; | |
5cdeadb3 | 1025 | uint8_t ipproto; |
429c6388 AS |
1026 | |
1027 | for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { | |
1028 | ipproto = FlowGetReverseProtoMapping(i); | |
1029 | for (j = 0; j < 2; j++) { | |
1030 | AppLayerProtoDetectPMCtx *pm_ctx = &alpd_ctx.ctx_ipp[i].ctx_pm[j]; | |
1031 | max_pat_id = pm_ctx->max_pat_id; | |
1032 | ||
1033 | for (pat_id = 0; pat_id < max_pat_id; pat_id++) { | |
1034 | s = pm_ctx->map[pat_id]; | |
1035 | while (s != NULL) { | |
1036 | if (s->alproto == alproto) | |
1037 | ipprotos[ipproto / 8] |= 1 << (ipproto % 8); | |
1038 | s = s->next; | |
1039 | } | |
1040 | } | |
1041 | } | |
1042 | } | |
1043 | ||
1044 | SCReturn; | |
1045 | } | |
1046 | ||
1047 | static int AppLayerProtoDetectPMSetContentIDs(AppLayerProtoDetectPMCtx *ctx) | |
1048 | { | |
1049 | SCEnter(); | |
1050 | ||
1051 | typedef struct TempContainer_ { | |
1052 | PatIntId id; | |
1053 | uint16_t content_len; | |
1054 | uint8_t *content; | |
1055 | } TempContainer; | |
1056 | ||
1057 | AppLayerProtoDetectPMSignature *s = NULL; | |
1058 | uint32_t struct_total_size = 0; | |
1059 | uint32_t content_total_size = 0; | |
1060 | /* array hash buffer */ | |
1061 | uint8_t *ahb = NULL; | |
1062 | uint8_t *content = NULL; | |
1063 | uint8_t content_len = 0; | |
1064 | PatIntId max_id = 0; | |
1065 | TempContainer *struct_offset = NULL; | |
1066 | uint8_t *content_offset = NULL; | |
1067 | TempContainer *dup = NULL; | |
1068 | int ret = 0; | |
1069 | ||
1070 | if (ctx->head == NULL) | |
1071 | goto end; | |
1072 | ||
1073 | for (s = ctx->head; s != NULL; s = s->next) { | |
1074 | struct_total_size += sizeof(TempContainer); | |
1075 | content_total_size += s->cd->content_len; | |
1076 | } | |
1077 | ||
1078 | ahb = SCMalloc(sizeof(uint8_t) * (struct_total_size + content_total_size)); | |
1079 | if (unlikely(ahb == NULL)) | |
1080 | goto error; | |
1081 | ||
1082 | struct_offset = (TempContainer *)ahb; | |
1083 | content_offset = ahb + struct_total_size; | |
1084 | for (s = ctx->head; s != NULL; s = s->next) { | |
1085 | dup = (TempContainer *)ahb; | |
1086 | content = s->cd->content; | |
1087 | content_len = s->cd->content_len; | |
1088 | ||
1089 | for (; dup != struct_offset; dup++) { | |
1090 | if (dup->content_len != content_len || | |
1091 | SCMemcmp(dup->content, content, dup->content_len) != 0) | |
1f00ff6a VJ |
1092 | { |
1093 | continue; | |
1094 | } | |
429c6388 AS |
1095 | break; |
1096 | } | |
1097 | ||
1098 | if (dup != struct_offset) { | |
1099 | s->cd->id = dup->id; | |
1100 | continue; | |
1101 | } | |
1102 | ||
1103 | struct_offset->content_len = content_len; | |
1104 | struct_offset->content = content_offset; | |
1105 | content_offset += content_len; | |
1106 | memcpy(struct_offset->content, content, content_len); | |
1107 | struct_offset->id = max_id++; | |
1108 | s->cd->id = struct_offset->id; | |
1109 | ||
1110 | struct_offset++; | |
1111 | } | |
1112 | ||
1113 | ctx->max_pat_id = max_id; | |
1114 | ||
1115 | goto end; | |
1116 | error: | |
1117 | ret = -1; | |
1118 | end: | |
1119 | if (ahb != NULL) | |
1120 | SCFree(ahb); | |
1121 | SCReturnInt(ret); | |
1122 | } | |
1123 | ||
1124 | static int AppLayerProtoDetectPMMapSignatures(AppLayerProtoDetectPMCtx *ctx) | |
1125 | { | |
1126 | SCEnter(); | |
1127 | ||
1128 | int ret = 0; | |
1129 | PatIntId max_pat_id = 0, tmp_pat_id; | |
1130 | AppLayerProtoDetectPMSignature *s, *next_s; | |
429c6388 AS |
1131 | int mpm_ret; |
1132 | ||
1133 | max_pat_id = ctx->max_pat_id; | |
1134 | ||
4f1f395b | 1135 | ctx->map = SCMalloc((max_pat_id) * sizeof(AppLayerProtoDetectPMSignature *)); |
429c6388 AS |
1136 | if (ctx->map == NULL) |
1137 | goto error; | |
4f1f395b | 1138 | memset(ctx->map, 0, (max_pat_id) * sizeof(AppLayerProtoDetectPMSignature *)); |
429c6388 | 1139 | |
a456bd81 | 1140 | /* add an array indexed by pattern id to look up the sig */ |
429c6388 AS |
1141 | for (s = ctx->head; s != NULL;) { |
1142 | next_s = s->next; | |
1143 | s->next = ctx->map[s->cd->id]; | |
1144 | ctx->map[s->cd->id] = s; | |
429c6388 AS |
1145 | s = next_s; |
1146 | } | |
1147 | ctx->head = NULL; | |
1148 | ||
a456bd81 | 1149 | |
429c6388 | 1150 | for (tmp_pat_id = 0; tmp_pat_id < max_pat_id; tmp_pat_id++) { |
a456bd81 | 1151 | s = NULL; |
429c6388 AS |
1152 | for (s = ctx->map[tmp_pat_id]; s != NULL; s = s->next) { |
1153 | if (s->cd->flags & DETECT_CONTENT_NOCASE) { | |
429c6388 AS |
1154 | break; |
1155 | } | |
1156 | } | |
a456bd81 VJ |
1157 | /* if s != NULL now, it's CI. If NULL, CS */ |
1158 | ||
1159 | if (s != NULL) { | |
429c6388 AS |
1160 | mpm_ret = MpmAddPatternCI(&ctx->mpm_ctx, |
1161 | s->cd->content, s->cd->content_len, | |
1f00ff6a | 1162 | 0, 0, tmp_pat_id, 0, 0); |
429c6388 AS |
1163 | if (mpm_ret < 0) |
1164 | goto error; | |
1165 | } else { | |
1166 | s = ctx->map[tmp_pat_id]; | |
a456bd81 VJ |
1167 | if (s == NULL) |
1168 | goto error; | |
1169 | ||
429c6388 AS |
1170 | mpm_ret = MpmAddPatternCS(&ctx->mpm_ctx, |
1171 | s->cd->content, s->cd->content_len, | |
1f00ff6a | 1172 | 0, 0, tmp_pat_id, 0, 0); |
429c6388 AS |
1173 | if (mpm_ret < 0) |
1174 | goto error; | |
1175 | } | |
1176 | } | |
1177 | ||
1178 | goto end; | |
1179 | error: | |
1180 | ret = -1; | |
1181 | end: | |
1182 | SCReturnInt(ret); | |
1183 | } | |
1184 | ||
1185 | static int AppLayerProtoDetectPMPrepareMpm(AppLayerProtoDetectPMCtx *ctx) | |
1186 | { | |
1187 | SCEnter(); | |
1188 | ||
1189 | int ret = 0; | |
1190 | MpmCtx *mpm_ctx = &ctx->mpm_ctx; | |
1191 | ||
1192 | if (mpm_table[mpm_ctx->mpm_type].Prepare(mpm_ctx) < 0) | |
1193 | goto error; | |
1194 | ||
1195 | goto end; | |
1196 | error: | |
1197 | ret = -1; | |
1198 | end: | |
1199 | SCReturnInt(ret); | |
1200 | } | |
1201 | ||
1202 | static void AppLayerProtoDetectPMFreeSignature(AppLayerProtoDetectPMSignature *sig) | |
1203 | { | |
1204 | SCEnter(); | |
67053e6e VJ |
1205 | if (sig == NULL) |
1206 | SCReturn; | |
1207 | if (sig->cd) | |
1208 | DetectContentFree(sig->cd); | |
429c6388 AS |
1209 | SCFree(sig); |
1210 | SCReturn; | |
1211 | } | |
1212 | ||
1213 | static int AppLayerProtoDetectPMAddSignature(AppLayerProtoDetectPMCtx *ctx, DetectContentData *cd, | |
1214 | AppProto alproto) | |
1215 | { | |
1216 | SCEnter(); | |
1217 | ||
1218 | int ret = 0; | |
1219 | AppLayerProtoDetectPMSignature *s = SCMalloc(sizeof(*s)); | |
1220 | if (unlikely(s == NULL)) | |
1221 | goto error; | |
1222 | memset(s, 0, sizeof(*s)); | |
1223 | ||
1224 | s->alproto = alproto; | |
1225 | s->cd = cd; | |
1226 | ||
1227 | /* prepend to the list */ | |
1228 | s->next = ctx->head; | |
1229 | ctx->head = s; | |
1230 | ||
1231 | goto end; | |
1232 | error: | |
1233 | ret = -1; | |
1234 | end: | |
1235 | SCReturnInt(ret); | |
1236 | } | |
1237 | ||
f5f14880 | 1238 | static int AppLayerProtoDetectPMRegisterPattern(uint8_t ipproto, AppProto alproto, |
429c6388 AS |
1239 | char *pattern, |
1240 | uint16_t depth, uint16_t offset, | |
1241 | uint8_t direction, | |
1242 | uint8_t is_cs) | |
1243 | { | |
1244 | SCEnter(); | |
1245 | ||
1246 | AppLayerProtoDetectCtxIpproto *ctx_ipp = &alpd_ctx.ctx_ipp[FlowGetProtoMapping(ipproto)]; | |
1247 | AppLayerProtoDetectPMCtx *ctx_pm = NULL; | |
1248 | DetectContentData *cd; | |
1249 | int ret = 0; | |
1250 | ||
1251 | cd = DetectContentParseEncloseQuotes(pattern); | |
1252 | if (cd == NULL) | |
1253 | goto error; | |
1254 | cd->depth = depth; | |
1255 | cd->offset = offset; | |
ba1e2ed6 KS |
1256 | if (!is_cs) { |
1257 | BoyerMooreCtxToNocase(cd->bm_ctx, cd->content, cd->content_len); | |
429c6388 | 1258 | cd->flags |= DETECT_CONTENT_NOCASE; |
ba1e2ed6 | 1259 | } |
429c6388 AS |
1260 | if (depth < cd->content_len) |
1261 | goto error; | |
1262 | ||
1263 | if (direction & STREAM_TOSERVER) | |
1264 | ctx_pm = (AppLayerProtoDetectPMCtx *)&ctx_ipp->ctx_pm[0]; | |
1265 | else | |
1266 | ctx_pm = (AppLayerProtoDetectPMCtx *)&ctx_ipp->ctx_pm[1]; | |
1267 | ||
1268 | if (depth > ctx_pm->max_len) | |
1269 | ctx_pm->max_len = depth; | |
1270 | if (depth < ctx_pm->min_len) | |
1271 | ctx_pm->min_len = depth; | |
1272 | ||
1273 | /* Finally turn it into a signature and add to the ctx. */ | |
1274 | AppLayerProtoDetectPMAddSignature(ctx_pm, cd, alproto); | |
1275 | ||
1276 | goto end; | |
1277 | error: | |
1278 | ret = -1; | |
1279 | end: | |
1280 | SCReturnInt(ret); | |
1281 | } | |
1282 | ||
1283 | /***** Protocol Retrieval *****/ | |
1284 | ||
3b8e9ffb | 1285 | AppProto AppLayerProtoDetectGetProto(AppLayerProtoDetectThreadCtx *tctx, |
429c6388 AS |
1286 | Flow *f, |
1287 | uint8_t *buf, uint32_t buflen, | |
1288 | uint8_t ipproto, uint8_t direction) | |
1289 | { | |
1290 | SCEnter(); | |
1291 | ||
1292 | AppProto alproto = ALPROTO_UNKNOWN; | |
1f00ff6a | 1293 | AppProto pm_results[ALPROTO_MAX]; |
429c6388 AS |
1294 | uint16_t pm_matches; |
1295 | ||
1296 | if (!FLOW_IS_PM_DONE(f, direction)) { | |
1f00ff6a | 1297 | pm_matches = AppLayerProtoDetectPMGetProto(tctx, f, |
429c6388 AS |
1298 | buf, buflen, |
1299 | direction, | |
1300 | ipproto, | |
1301 | pm_results); | |
1302 | if (pm_matches > 0) { | |
1303 | alproto = pm_results[0]; | |
1304 | goto end; | |
1305 | } | |
1306 | } | |
1307 | ||
1308 | if (!FLOW_IS_PP_DONE(f, direction)) | |
1309 | alproto = AppLayerProtoDetectPPGetProto(f, buf, buflen, ipproto, direction); | |
1310 | ||
1311 | end: | |
1312 | SCReturnCT(alproto, "AppProto"); | |
1313 | } | |
1314 | ||
1315 | static void AppLayerProtoDetectFreeProbingParsers(AppLayerProtoDetectProbingParser *pp) | |
1316 | { | |
1317 | SCEnter(); | |
1318 | ||
1319 | AppLayerProtoDetectProbingParser *tmp_pp = NULL; | |
1320 | ||
1321 | if (pp == NULL) | |
1322 | goto end; | |
1323 | ||
1324 | while (pp != NULL) { | |
1325 | tmp_pp = pp->next; | |
1f00ff6a | 1326 | AppLayerProtoDetectProbingParserFree(pp); |
429c6388 AS |
1327 | pp = tmp_pp; |
1328 | } | |
1329 | ||
1330 | end: | |
1331 | SCReturn; | |
1332 | } | |
1333 | ||
1334 | /***** State Preparation *****/ | |
1335 | ||
1336 | int AppLayerProtoDetectPrepareState(void) | |
1337 | { | |
1338 | SCEnter(); | |
1339 | ||
1340 | AppLayerProtoDetectPMCtx *ctx_pm; | |
1341 | int i, j; | |
1342 | int ret = 0; | |
1343 | ||
1344 | for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { | |
1345 | for (j = 0; j < 2; j++) { | |
1346 | ctx_pm = &alpd_ctx.ctx_ipp[i].ctx_pm[j]; | |
1347 | ||
1348 | if (AppLayerProtoDetectPMSetContentIDs(ctx_pm) < 0) | |
1349 | goto error; | |
1350 | ||
1351 | if (ctx_pm->max_pat_id == 0) | |
1352 | continue; | |
1353 | ||
1354 | if (AppLayerProtoDetectPMMapSignatures(ctx_pm) < 0) | |
1355 | goto error; | |
1356 | if (AppLayerProtoDetectPMPrepareMpm(ctx_pm) < 0) | |
1357 | goto error; | |
1358 | } | |
1359 | } | |
1360 | ||
eae5b1ba VJ |
1361 | #ifdef DEBUG |
1362 | if (SCLogDebugEnabled()) { | |
1363 | AppLayerProtoDetectPrintProbingParsers(alpd_ctx.ctx_pp); | |
1364 | } | |
1365 | #endif | |
1366 | ||
429c6388 AS |
1367 | goto end; |
1368 | error: | |
1369 | ret = -1; | |
1370 | end: | |
1371 | SCReturnInt(ret); | |
1372 | } | |
1373 | ||
1374 | /***** PP registration *****/ | |
1375 | ||
eae5b1ba VJ |
1376 | /** \brief register parser at a port |
1377 | * | |
1378 | * \param direction STREAM_TOSERVER or STREAM_TOCLIENT for dp or sp | |
1379 | */ | |
5cdeadb3 | 1380 | void AppLayerProtoDetectPPRegister(uint8_t ipproto, |
429c6388 | 1381 | char *portstr, |
f5f14880 | 1382 | AppProto alproto, |
429c6388 AS |
1383 | uint16_t min_depth, uint16_t max_depth, |
1384 | uint8_t direction, | |
1385 | ProbingParserFPtr ProbingParser) | |
1386 | { | |
1387 | SCEnter(); | |
1388 | ||
1389 | DetectPort *head = NULL; | |
1390 | DetectPortParse(&head, portstr); | |
1391 | DetectPort *temp_dp = head; | |
1392 | while (temp_dp != NULL) { | |
1393 | uint32_t port = temp_dp->port; | |
1394 | if (port == 0 && temp_dp->port2 != 0) | |
1395 | port++; | |
1396 | for ( ; port <= temp_dp->port2; port++) { | |
1397 | AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.ctx_pp, | |
1398 | ipproto, | |
1399 | port, | |
1400 | alproto, | |
1401 | min_depth, max_depth, | |
1402 | direction, | |
1403 | ProbingParser); | |
1404 | } | |
1405 | temp_dp = temp_dp->next; | |
1406 | } | |
1407 | DetectPortCleanupList(head); | |
1408 | ||
1409 | SCReturn; | |
1410 | } | |
1411 | ||
ab10c0a0 | 1412 | int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name, |
5cdeadb3 | 1413 | uint8_t ipproto, |
429c6388 AS |
1414 | const char *alproto_name, |
1415 | AppProto alproto, | |
1416 | uint16_t min_depth, uint16_t max_depth, | |
1417 | ProbingParserFPtr ProbingParser) | |
1418 | { | |
1419 | SCEnter(); | |
1420 | ||
1421 | char param[100]; | |
1422 | int r; | |
1423 | ConfNode *node; | |
1424 | ConfNode *port_node = NULL; | |
ab10c0a0 | 1425 | int config = 0; |
429c6388 AS |
1426 | |
1427 | r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.", | |
1428 | alproto_name, ".detection-ports"); | |
1429 | if (r < 0) { | |
1430 | SCLogError(SC_ERR_FATAL, "snprintf failure."); | |
1431 | exit(EXIT_FAILURE); | |
1432 | } else if (r > (int)sizeof(param)) { | |
1433 | SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); | |
1434 | exit(EXIT_FAILURE); | |
1435 | } | |
1436 | node = ConfGetNode(param); | |
1437 | if (node == NULL) { | |
1438 | SCLogDebug("Entry for %s not found.", param); | |
1439 | r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.", | |
1440 | alproto_name, ".", ipproto_name, ".detection-ports"); | |
1441 | if (r < 0) { | |
1442 | SCLogError(SC_ERR_FATAL, "snprintf failure."); | |
1443 | exit(EXIT_FAILURE); | |
1444 | } else if (r > (int)sizeof(param)) { | |
1445 | SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); | |
1446 | exit(EXIT_FAILURE); | |
1447 | } | |
1448 | node = ConfGetNode(param); | |
1449 | if (node == NULL) | |
1450 | goto end; | |
1451 | } | |
1452 | ||
eae5b1ba VJ |
1453 | /* detect by destination port of the flow (e.g. port 53 for DNS) */ |
1454 | port_node = ConfNodeLookupChild(node, "dp"); | |
1455 | if (port_node == NULL) | |
1456 | port_node = ConfNodeLookupChild(node, "toserver"); | |
1457 | ||
429c6388 AS |
1458 | if (port_node != NULL && port_node->val != NULL) { |
1459 | AppLayerProtoDetectPPRegister(ipproto, | |
1460 | port_node->val, | |
1461 | alproto, | |
1462 | min_depth, max_depth, | |
eae5b1ba | 1463 | STREAM_TOSERVER, /* to indicate dp */ |
429c6388 AS |
1464 | ProbingParser); |
1465 | } | |
eae5b1ba VJ |
1466 | |
1467 | /* detect by source port of flow */ | |
1468 | port_node = ConfNodeLookupChild(node, "sp"); | |
1469 | if (port_node == NULL) | |
1470 | port_node = ConfNodeLookupChild(node, "toclient"); | |
429c6388 AS |
1471 | |
1472 | if (port_node != NULL && port_node->val != NULL) { | |
1473 | AppLayerProtoDetectPPRegister(ipproto, | |
1474 | port_node->val, | |
1475 | alproto, | |
1476 | min_depth, max_depth, | |
eae5b1ba | 1477 | STREAM_TOCLIENT, /* to indicate sp */ |
429c6388 AS |
1478 | ProbingParser); |
1479 | ||
1480 | } | |
1481 | ||
ab10c0a0 | 1482 | config = 1; |
429c6388 | 1483 | end: |
ab10c0a0 | 1484 | SCReturnInt(config); |
429c6388 AS |
1485 | } |
1486 | ||
1487 | /***** PM registration *****/ | |
1488 | ||
5cdeadb3 | 1489 | int AppLayerProtoDetectPMRegisterPatternCS(uint8_t ipproto, AppProto alproto, |
429c6388 AS |
1490 | char *pattern, |
1491 | uint16_t depth, uint16_t offset, | |
1492 | uint8_t direction) | |
1493 | { | |
1494 | SCEnter(); | |
dc1599e0 | 1495 | int r = 0; |
1496 | r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto, | |
429c6388 AS |
1497 | pattern, |
1498 | depth, offset, | |
1499 | direction, | |
dc1599e0 | 1500 | 1 /* case-sensitive */); |
1501 | SCReturnInt(r); | |
429c6388 AS |
1502 | } |
1503 | ||
5cdeadb3 | 1504 | int AppLayerProtoDetectPMRegisterPatternCI(uint8_t ipproto, AppProto alproto, |
429c6388 AS |
1505 | char *pattern, |
1506 | uint16_t depth, uint16_t offset, | |
1507 | uint8_t direction) | |
1508 | { | |
1509 | SCEnter(); | |
dc1599e0 | 1510 | int r = 0; |
1511 | r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto, | |
429c6388 AS |
1512 | pattern, |
1513 | depth, offset, | |
1514 | direction, | |
dc1599e0 | 1515 | 0 /* !case-sensitive */); |
1516 | SCReturnInt(r); | |
429c6388 AS |
1517 | } |
1518 | ||
1519 | /***** Setup/General Registration *****/ | |
1520 | ||
1521 | int AppLayerProtoDetectSetup(void) | |
1522 | { | |
1523 | SCEnter(); | |
1524 | ||
1525 | int i, j; | |
1526 | ||
1527 | memset(&alpd_ctx, 0, sizeof(alpd_ctx)); | |
1528 | ||
1529 | for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { | |
1530 | for (j = 0; j < 2; j++) { | |
1531 | MpmInitCtx(&alpd_ctx.ctx_ipp[i].ctx_pm[j].mpm_ctx, MPM_AC); | |
1532 | } | |
1533 | } | |
429c6388 AS |
1534 | SCReturnInt(0); |
1535 | } | |
1536 | ||
1537 | /** | |
1538 | * \todo incomplete. Need more work. | |
1539 | */ | |
1540 | int AppLayerProtoDetectDeSetup(void) | |
1541 | { | |
1542 | SCEnter(); | |
1543 | ||
1544 | int ipproto_map = 0; | |
1545 | int dir = 0; | |
1546 | PatIntId id = 0; | |
1547 | AppLayerProtoDetectPMCtx *pm_ctx = NULL; | |
1548 | AppLayerProtoDetectPMSignature *sig = NULL, *next_sig = NULL; | |
1549 | ||
1550 | for (ipproto_map = 0; ipproto_map < FLOW_PROTO_DEFAULT; ipproto_map++) { | |
1551 | for (dir = 0; dir < 2; dir++) { | |
1552 | pm_ctx = &alpd_ctx.ctx_ipp[ipproto_map].ctx_pm[dir]; | |
1553 | mpm_table[pm_ctx->mpm_ctx.mpm_type].DestroyCtx(pm_ctx->mpm_ctx.ctx); | |
1554 | for (id = 0; id < pm_ctx->max_pat_id; id++) { | |
1555 | sig = pm_ctx->map[id]; | |
429c6388 | 1556 | while (sig != NULL) { |
67053e6e | 1557 | next_sig = sig->next; |
429c6388 AS |
1558 | AppLayerProtoDetectPMFreeSignature(sig); |
1559 | sig = next_sig; | |
1560 | } | |
1561 | } | |
1562 | } | |
1563 | } | |
1564 | ||
1565 | AppLayerProtoDetectFreeProbingParsers(alpd_ctx.ctx_pp); | |
1566 | ||
1567 | SCReturnInt(0); | |
1568 | } | |
1569 | ||
1570 | void AppLayerProtoDetectRegisterProtocol(AppProto alproto, char *alproto_name) | |
1571 | { | |
1572 | SCEnter(); | |
1573 | ||
1574 | if (alpd_ctx.alproto_names[alproto] != NULL) | |
1575 | goto end; | |
1576 | ||
1577 | alpd_ctx.alproto_names[alproto] = alproto_name; | |
1578 | ||
1579 | goto end; | |
1580 | end: | |
1581 | SCReturn; | |
1582 | } | |
1583 | ||
1584 | int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, | |
1585 | const char *alproto) | |
1586 | { | |
1587 | SCEnter(); | |
1588 | ||
1589 | BUG_ON(ipproto == NULL || alproto == NULL); | |
1590 | ||
1591 | int enabled = 1; | |
1592 | char param[100]; | |
1593 | ConfNode *node; | |
1594 | int r; | |
1595 | ||
1596 | if (RunmodeIsUnittests()) | |
1597 | goto enabled; | |
1598 | ||
1599 | r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.", | |
1600 | alproto, ".enabled"); | |
1601 | if (r < 0) { | |
1602 | SCLogError(SC_ERR_FATAL, "snprintf failure."); | |
1603 | exit(EXIT_FAILURE); | |
1604 | } else if (r > (int)sizeof(param)) { | |
1605 | SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); | |
1606 | exit(EXIT_FAILURE); | |
1607 | } | |
1608 | ||
1609 | node = ConfGetNode(param); | |
1610 | if (node == NULL) { | |
1611 | SCLogDebug("Entry for %s not found.", param); | |
1612 | r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.", | |
1613 | alproto, ".", ipproto, ".enabled"); | |
1614 | if (r < 0) { | |
1615 | SCLogError(SC_ERR_FATAL, "snprintf failure."); | |
1616 | exit(EXIT_FAILURE); | |
1617 | } else if (r > (int)sizeof(param)) { | |
1618 | SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); | |
1619 | exit(EXIT_FAILURE); | |
1620 | } | |
1621 | ||
1622 | node = ConfGetNode(param); | |
1623 | if (node == NULL) { | |
1624 | SCLogDebug("Entry for %s not found.", param); | |
1625 | goto enabled; | |
1626 | } | |
1627 | } | |
1628 | ||
1629 | if (strcasecmp(node->val, "yes") == 0) { | |
1630 | goto enabled; | |
1631 | } else if (strcasecmp(node->val, "no") == 0) { | |
1632 | goto disabled; | |
1633 | } else if (strcasecmp(node->val, "detection-only") == 0) { | |
1634 | goto enabled; | |
1635 | } else { | |
1636 | SCLogError(SC_ERR_FATAL, "Invalid value found for %s.", param); | |
1637 | exit(EXIT_FAILURE); | |
1638 | } | |
1639 | ||
1640 | disabled: | |
1641 | enabled = 0; | |
1642 | enabled: | |
1643 | SCReturnInt(enabled); | |
1644 | } | |
1645 | ||
3b8e9ffb | 1646 | AppLayerProtoDetectThreadCtx *AppLayerProtoDetectGetCtxThread(void) |
429c6388 AS |
1647 | { |
1648 | SCEnter(); | |
1649 | ||
30f16ee4 | 1650 | AppLayerProtoDetectThreadCtx *alpd_tctx = NULL; |
429c6388 AS |
1651 | MpmCtx *mpm_ctx; |
1652 | MpmThreadCtx *mpm_tctx; | |
1653 | int i, j; | |
1654 | PatIntId max_pat_id = 0; | |
1655 | ||
1656 | for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { | |
1657 | for (j = 0; j < 2; j++) { | |
59327e0f VJ |
1658 | if (max_pat_id == 0) { |
1659 | max_pat_id = alpd_ctx.ctx_ipp[i].ctx_pm[j].max_pat_id; | |
1660 | ||
1661 | } else if (alpd_ctx.ctx_ipp[i].ctx_pm[j].max_pat_id && | |
1662 | max_pat_id < alpd_ctx.ctx_ipp[i].ctx_pm[j].max_pat_id) | |
1663 | { | |
1664 | max_pat_id = alpd_ctx.ctx_ipp[i].ctx_pm[j].max_pat_id; | |
1665 | } | |
429c6388 AS |
1666 | } |
1667 | } | |
1668 | ||
1669 | alpd_tctx = SCMalloc(sizeof(*alpd_tctx)); | |
1670 | if (alpd_tctx == NULL) | |
1671 | goto error; | |
1672 | memset(alpd_tctx, 0, sizeof(*alpd_tctx)); | |
1673 | ||
1674 | /* Get the max pat id for all the mpm ctxs. */ | |
1675 | if (PmqSetup(&alpd_tctx->pmq, max_pat_id) < 0) | |
1676 | goto error; | |
1677 | ||
1678 | for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { | |
1679 | for (j = 0; j < 2; j++) { | |
1680 | mpm_ctx = &alpd_ctx.ctx_ipp[i].ctx_pm[j].mpm_ctx; | |
1681 | mpm_tctx = &alpd_tctx->mpm_tctx[i][j]; | |
1682 | mpm_table[mpm_ctx->mpm_type].InitThreadCtx(mpm_ctx, mpm_tctx, 0); | |
1683 | } | |
1684 | } | |
1685 | ||
1686 | goto end; | |
1687 | error: | |
1688 | if (alpd_tctx != NULL) | |
1689 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
1690 | alpd_tctx = NULL; | |
1691 | end: | |
3b8e9ffb | 1692 | SCReturnPtr(alpd_tctx, "AppLayerProtoDetectThreadCtx"); |
429c6388 AS |
1693 | } |
1694 | ||
3b8e9ffb | 1695 | void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *alpd_tctx) |
429c6388 AS |
1696 | { |
1697 | SCEnter(); | |
1698 | ||
429c6388 AS |
1699 | MpmCtx *mpm_ctx; |
1700 | MpmThreadCtx *mpm_tctx; | |
1701 | int ipproto_map, dir; | |
1702 | ||
1703 | for (ipproto_map = 0; ipproto_map < FLOW_PROTO_DEFAULT; ipproto_map++) { | |
1704 | for (dir = 0; dir < 2; dir++) { | |
1705 | mpm_ctx = &alpd_ctx.ctx_ipp[ipproto_map].ctx_pm[dir].mpm_ctx; | |
1706 | mpm_tctx = &alpd_tctx->mpm_tctx[ipproto_map][dir]; | |
1707 | mpm_table[mpm_ctx->mpm_type].DestroyThreadCtx(mpm_ctx, mpm_tctx); | |
1708 | } | |
1709 | } | |
1710 | PmqFree(&alpd_tctx->pmq); | |
1711 | SCFree(alpd_tctx); | |
1712 | ||
1713 | SCReturn; | |
1714 | } | |
1715 | ||
1716 | /***** Utility *****/ | |
1717 | ||
1718 | void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos) | |
1719 | { | |
1720 | SCEnter(); | |
1721 | ||
1722 | AppLayerProtoDetectPMGetIpprotos(alproto, ipprotos); | |
1723 | AppLayerProtoDetectPPGetIpprotos(alproto, ipprotos); | |
1724 | ||
1725 | SCReturn; | |
1726 | } | |
1727 | ||
1728 | AppProto AppLayerProtoDetectGetProtoByName(char *alproto_name) | |
1729 | { | |
1730 | SCEnter(); | |
1731 | ||
c779065d | 1732 | AppProto a; |
429c6388 AS |
1733 | for (a = 0; a < ALPROTO_MAX; a++) { |
1734 | if (alpd_ctx.alproto_names[a] != NULL && | |
1735 | strlen(alpd_ctx.alproto_names[a]) == strlen(alproto_name) && | |
1736 | (SCMemcmp(alpd_ctx.alproto_names[a], alproto_name, strlen(alproto_name)) == 0)) | |
59327e0f | 1737 | { |
c779065d | 1738 | SCReturnCT(a, "AppProto"); |
59327e0f | 1739 | } |
429c6388 AS |
1740 | } |
1741 | ||
c779065d | 1742 | SCReturnCT(ALPROTO_UNKNOWN, "AppProto"); |
429c6388 AS |
1743 | } |
1744 | ||
1745 | char *AppLayerProtoDetectGetProtoName(AppProto alproto) | |
1746 | { | |
1747 | return alpd_ctx.alproto_names[alproto]; | |
1748 | } | |
1749 | ||
1750 | void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos) | |
1751 | { | |
1752 | SCEnter(); | |
1753 | ||
1754 | memset(alprotos, 0, ALPROTO_MAX * sizeof(AppProto)); | |
1755 | ||
1756 | int alproto; | |
1757 | ||
1758 | for (alproto = 0; alproto != ALPROTO_MAX; alproto++) { | |
1759 | if (alpd_ctx.alproto_names[alproto] != NULL) | |
1760 | alprotos[alproto] = 1; | |
1761 | } | |
1762 | ||
1763 | SCReturn; | |
1764 | } | |
1765 | ||
1766 | /***** Unittests *****/ | |
1767 | ||
1768 | #ifdef UNITTESTS | |
1769 | ||
1770 | static AppLayerProtoDetectCtx alpd_ctx_ut; | |
1771 | ||
1772 | void AppLayerProtoDetectUnittestCtxBackup(void) | |
1773 | { | |
1774 | SCEnter(); | |
1775 | alpd_ctx_ut = alpd_ctx; | |
1776 | memset(&alpd_ctx, 0, sizeof(alpd_ctx)); | |
1777 | SCReturn; | |
1778 | } | |
1779 | ||
1780 | void AppLayerProtoDetectUnittestCtxRestore(void) | |
1781 | { | |
1782 | SCEnter(); | |
1783 | alpd_ctx = alpd_ctx_ut; | |
1784 | memset(&alpd_ctx_ut, 0, sizeof(alpd_ctx_ut)); | |
1785 | SCReturn; | |
1786 | } | |
1787 | ||
1788 | int AppLayerProtoDetectTest01(void) | |
1789 | { | |
1790 | AppLayerProtoDetectUnittestCtxBackup(); | |
1791 | AppLayerProtoDetectSetup(); | |
1792 | ||
1793 | char *buf; | |
1794 | int r = 0; | |
1795 | ||
1796 | buf = "HTTP"; | |
1797 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); | |
1798 | buf = "GET"; | |
1799 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOSERVER); | |
1800 | ||
1801 | AppLayerProtoDetectPrepareState(); | |
1802 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 1) { | |
1803 | printf("Failure - " | |
1804 | "alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 1\n"); | |
1805 | goto end; | |
1806 | } | |
1807 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { | |
1808 | printf("Failure - " | |
1809 | "alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1\n"); | |
1810 | goto end; | |
1811 | } | |
1812 | ||
1813 | r = 1; | |
1814 | ||
1815 | end: | |
1816 | AppLayerProtoDetectDeSetup(); | |
1817 | AppLayerProtoDetectUnittestCtxRestore(); | |
1818 | return r; | |
1819 | } | |
1820 | ||
1821 | int AppLayerProtoDetectTest02(void) | |
1822 | { | |
1823 | AppLayerProtoDetectUnittestCtxBackup(); | |
1824 | AppLayerProtoDetectSetup(); | |
1825 | ||
1826 | char *buf; | |
1827 | int r = 0; | |
1828 | ||
1829 | buf = "HTTP"; | |
1830 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); | |
1831 | buf = "ftp"; | |
1832 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_FTP, buf, 4, 0, STREAM_TOCLIENT); | |
1833 | ||
1834 | AppLayerProtoDetectPrepareState(); | |
1835 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { | |
1836 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
1837 | goto end; | |
1838 | } | |
1839 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2) { | |
1840 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
1841 | goto end; | |
1842 | } | |
1843 | ||
1844 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { | |
1845 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
1846 | goto end; | |
1847 | } | |
1848 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
1849 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
1850 | goto end; | |
1851 | } | |
1852 | ||
1853 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_FTP) { | |
1854 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_FTP\n"); | |
1855 | goto end; | |
1856 | } | |
1857 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1]->alproto != ALPROTO_HTTP) { | |
1858 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1].alproto != ALPROTO_HTTP\n"); | |
1859 | goto end; | |
1860 | } | |
1861 | ||
1862 | r = 1; | |
1863 | ||
1864 | end: | |
1865 | AppLayerProtoDetectDeSetup(); | |
1866 | AppLayerProtoDetectUnittestCtxRestore(); | |
1867 | return r; | |
1868 | } | |
1869 | ||
1870 | int AppLayerProtoDetectTest03(void) | |
1871 | { | |
1872 | AppLayerProtoDetectUnittestCtxBackup(); | |
1873 | AppLayerProtoDetectSetup(); | |
1874 | ||
1875 | uint8_t l7data[] = "HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n"; | |
1876 | char *buf; | |
1877 | int r = 0; | |
1878 | Flow f; | |
1f00ff6a | 1879 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 1880 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 | 1881 | |
634eb1d3 VJ |
1882 | memset(&f, 0x00, sizeof(f)); |
1883 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
1884 | ||
429c6388 AS |
1885 | memset(pm_results, 0, sizeof(pm_results)); |
1886 | ||
1887 | buf = "HTTP"; | |
1888 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); | |
1889 | buf = "220 "; | |
1890 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_FTP, buf, 4, 0, STREAM_TOCLIENT); | |
1891 | ||
1892 | AppLayerProtoDetectPrepareState(); | |
1893 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
1894 | * it sets internal structures which depends on the above function. */ | |
1895 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
1896 | ||
1897 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { | |
1898 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
1899 | goto end; | |
1900 | } | |
1901 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2) { | |
1902 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
1903 | goto end; | |
1904 | } | |
1905 | ||
1906 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { | |
1907 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
1908 | goto end; | |
1909 | } | |
1910 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
1911 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
1912 | goto end; | |
1913 | } | |
1914 | ||
1915 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_FTP) { | |
1916 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_FTP\n"); | |
1917 | goto end; | |
1918 | } | |
1919 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1]->alproto != ALPROTO_HTTP) { | |
1920 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1].alproto != ALPROTO_HTTP\n"); | |
1921 | goto end; | |
1922 | } | |
1923 | ||
1924 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, | |
1925 | &f, | |
1926 | l7data, sizeof(l7data), | |
1927 | STREAM_TOCLIENT, | |
1928 | IPPROTO_TCP, | |
1929 | pm_results); | |
1930 | if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { | |
1931 | printf("cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); | |
1932 | goto end; | |
1933 | } | |
1934 | ||
1935 | r = 1; | |
1936 | ||
1937 | end: | |
1938 | if (alpd_tctx != NULL) | |
1939 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
1940 | AppLayerProtoDetectDeSetup(); | |
1941 | AppLayerProtoDetectUnittestCtxRestore(); | |
1942 | return r; | |
1943 | } | |
1944 | ||
1945 | int AppLayerProtoDetectTest04(void) | |
1946 | { | |
1947 | AppLayerProtoDetectUnittestCtxBackup(); | |
1948 | AppLayerProtoDetectSetup(); | |
1949 | ||
1950 | uint8_t l7data[] = "HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n"; | |
1951 | char *buf; | |
1952 | int r = 0; | |
1953 | Flow f; | |
1f00ff6a | 1954 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 1955 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 | 1956 | |
634eb1d3 VJ |
1957 | memset(&f, 0x00, sizeof(f)); |
1958 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
1959 | ||
429c6388 AS |
1960 | memset(pm_results, 0, sizeof(pm_results)); |
1961 | ||
1962 | buf = "200 "; | |
1963 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 13, 0, STREAM_TOCLIENT); | |
1964 | ||
1965 | AppLayerProtoDetectPrepareState(); | |
1966 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
1967 | * it sets internal structures which depends on the above function. */ | |
1968 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
1969 | ||
1970 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { | |
1971 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
1972 | goto end; | |
1973 | } | |
1974 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { | |
1975 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
1976 | goto end; | |
1977 | } | |
1978 | ||
1979 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { | |
1980 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
1981 | goto end; | |
1982 | } | |
1983 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
1984 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
1985 | goto end; | |
1986 | } | |
1987 | ||
1988 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) { | |
1989 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_HTTP\n"); | |
1990 | goto end; | |
1991 | } | |
1992 | ||
1993 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, | |
1994 | &f, | |
1995 | l7data, sizeof(l7data), | |
1996 | STREAM_TOCLIENT, | |
1997 | IPPROTO_TCP, | |
1998 | pm_results); | |
1999 | if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { | |
2000 | printf("cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); | |
2001 | goto end; | |
2002 | } | |
2003 | ||
2004 | r = 1; | |
2005 | ||
2006 | end: | |
2007 | if (alpd_tctx != NULL) | |
2008 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2009 | AppLayerProtoDetectDeSetup(); | |
2010 | AppLayerProtoDetectUnittestCtxRestore(); | |
2011 | return r; | |
2012 | } | |
2013 | ||
2014 | int AppLayerProtoDetectTest05(void) | |
2015 | { | |
2016 | AppLayerProtoDetectUnittestCtxBackup(); | |
2017 | AppLayerProtoDetectSetup(); | |
2018 | ||
2019 | uint8_t l7data[] = "HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n<HTML><BODY>Blahblah</BODY></HTML>"; | |
2020 | char *buf; | |
2021 | int r = 0; | |
2022 | Flow f; | |
1f00ff6a | 2023 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2024 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 | 2025 | |
634eb1d3 VJ |
2026 | memset(&f, 0x00, sizeof(f)); |
2027 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
2028 | ||
429c6388 AS |
2029 | memset(pm_results, 0, sizeof(pm_results)); |
2030 | ||
2031 | buf = "HTTP"; | |
2032 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); | |
2033 | buf = "220 "; | |
2034 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_FTP, buf, 4, 0, STREAM_TOCLIENT); | |
2035 | ||
2036 | AppLayerProtoDetectPrepareState(); | |
2037 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2038 | * it sets internal structures which depends on the above function. */ | |
2039 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
4369816c | 2040 | |
429c6388 AS |
2041 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { |
2042 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
2043 | goto end; | |
2044 | } | |
2045 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2) { | |
2046 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
2047 | goto end; | |
4369816c VJ |
2048 | } |
2049 | ||
429c6388 AS |
2050 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { |
2051 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
2052 | goto end; | |
2053 | } | |
2054 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
2055 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
2056 | goto end; | |
4369816c VJ |
2057 | } |
2058 | ||
429c6388 AS |
2059 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_FTP) { |
2060 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_FTP\n"); | |
2061 | goto end; | |
2062 | } | |
2063 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1]->alproto != ALPROTO_HTTP) { | |
2064 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1].alproto != ALPROTO_HTTP\n"); | |
2065 | goto end; | |
2066 | } | |
4369816c | 2067 | |
429c6388 AS |
2068 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, |
2069 | &f, | |
2070 | l7data, sizeof(l7data), | |
2071 | STREAM_TOCLIENT, | |
2072 | IPPROTO_TCP, | |
2073 | pm_results); | |
2074 | if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { | |
2075 | printf("cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); | |
2076 | goto end; | |
4369816c VJ |
2077 | } |
2078 | ||
429c6388 | 2079 | r = 1; |
41e6735b | 2080 | |
429c6388 AS |
2081 | end: |
2082 | if (alpd_tctx != NULL) | |
2083 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2084 | AppLayerProtoDetectDeSetup(); | |
2085 | AppLayerProtoDetectUnittestCtxRestore(); | |
4369816c VJ |
2086 | return r; |
2087 | } | |
2088 | ||
429c6388 AS |
2089 | int AppLayerProtoDetectTest06(void) |
2090 | { | |
2091 | AppLayerProtoDetectUnittestCtxBackup(); | |
2092 | AppLayerProtoDetectSetup(); | |
2093 | ||
4369816c | 2094 | uint8_t l7data[] = "220 Welcome to the OISF FTP server\r\n"; |
429c6388 AS |
2095 | char *buf; |
2096 | int r = 0; | |
2097 | Flow f; | |
1f00ff6a | 2098 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2099 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
4369816c | 2100 | |
634eb1d3 VJ |
2101 | memset(&f, 0x00, sizeof(f)); |
2102 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
2103 | ||
429c6388 AS |
2104 | buf = "HTTP"; |
2105 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); | |
2106 | buf = "220 "; | |
2107 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_FTP, buf, 4, 0, STREAM_TOCLIENT); | |
4369816c | 2108 | |
429c6388 AS |
2109 | AppLayerProtoDetectPrepareState(); |
2110 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2111 | * it sets internal structures which depends on the above function. */ | |
2112 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
4369816c | 2113 | |
429c6388 AS |
2114 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { |
2115 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
2116 | goto end; | |
4369816c | 2117 | } |
429c6388 AS |
2118 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2) { |
2119 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
2120 | goto end; | |
4369816c VJ |
2121 | } |
2122 | ||
429c6388 AS |
2123 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { |
2124 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
2125 | goto end; | |
4369816c | 2126 | } |
429c6388 AS |
2127 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { |
2128 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
2129 | goto end; | |
4369816c VJ |
2130 | } |
2131 | ||
429c6388 AS |
2132 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_FTP) { |
2133 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_FTP\n"); | |
2134 | goto end; | |
2135 | } | |
2136 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1]->alproto != ALPROTO_HTTP) { | |
2137 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1].alproto != ALPROTO_HTTP\n"); | |
2138 | goto end; | |
2139 | } | |
4369816c | 2140 | |
429c6388 AS |
2141 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, |
2142 | &f, | |
2143 | l7data, sizeof(l7data), | |
2144 | STREAM_TOCLIENT, | |
2145 | IPPROTO_TCP, | |
2146 | pm_results); | |
2147 | if (cnt != 1 && pm_results[0] != ALPROTO_FTP) { | |
2148 | printf("cnt != 1 && pm_results[0] != AlPROTO_FTP\n"); | |
2149 | goto end; | |
4369816c VJ |
2150 | } |
2151 | ||
429c6388 | 2152 | r = 1; |
41e6735b | 2153 | |
429c6388 AS |
2154 | end: |
2155 | if (alpd_tctx != NULL) | |
2156 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2157 | AppLayerProtoDetectDeSetup(); | |
2158 | AppLayerProtoDetectUnittestCtxRestore(); | |
4369816c VJ |
2159 | return r; |
2160 | } | |
2161 | ||
429c6388 AS |
2162 | int AppLayerProtoDetectTest07(void) |
2163 | { | |
2164 | AppLayerProtoDetectUnittestCtxBackup(); | |
2165 | AppLayerProtoDetectSetup(); | |
2166 | ||
4369816c | 2167 | uint8_t l7data[] = "220 Welcome to the OISF HTTP/FTP server\r\n"; |
429c6388 AS |
2168 | char *buf; |
2169 | int r = 0; | |
2170 | Flow f; | |
1f00ff6a | 2171 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2172 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 | 2173 | |
634eb1d3 VJ |
2174 | memset(&f, 0x00, sizeof(f)); |
2175 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
2176 | ||
429c6388 | 2177 | memset(pm_results, 0, sizeof(pm_results)); |
4369816c | 2178 | |
429c6388 AS |
2179 | buf = "HTTP"; |
2180 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); | |
4369816c | 2181 | |
429c6388 AS |
2182 | AppLayerProtoDetectPrepareState(); |
2183 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2184 | * it sets internal structures which depends on the above function. */ | |
2185 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
4369816c | 2186 | |
429c6388 AS |
2187 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { |
2188 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
2189 | goto end; | |
2190 | } | |
2191 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { | |
2192 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
2193 | goto end; | |
4369816c VJ |
2194 | } |
2195 | ||
429c6388 AS |
2196 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { |
2197 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
2198 | goto end; | |
2199 | } | |
2200 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
2201 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
2202 | goto end; | |
4369816c VJ |
2203 | } |
2204 | ||
429c6388 AS |
2205 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) { |
2206 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_HTTP\n"); | |
2207 | goto end; | |
2208 | } | |
4369816c | 2209 | |
429c6388 AS |
2210 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, |
2211 | &f, | |
2212 | l7data, sizeof(l7data), | |
2213 | STREAM_TOCLIENT, | |
2214 | IPPROTO_TCP, | |
2215 | pm_results); | |
2216 | if (cnt != 0) { | |
2217 | printf("cnt != 0\n"); | |
2218 | goto end; | |
4369816c VJ |
2219 | } |
2220 | ||
429c6388 | 2221 | r = 1; |
41e6735b | 2222 | |
429c6388 AS |
2223 | end: |
2224 | if (alpd_tctx != NULL) | |
2225 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2226 | AppLayerProtoDetectDeSetup(); | |
2227 | AppLayerProtoDetectUnittestCtxRestore(); | |
4369816c VJ |
2228 | return r; |
2229 | } | |
57331ea2 | 2230 | |
429c6388 AS |
2231 | int AppLayerProtoDetectTest08(void) |
2232 | { | |
2233 | AppLayerProtoDetectUnittestCtxBackup(); | |
2234 | AppLayerProtoDetectSetup(); | |
2235 | ||
2236 | uint8_t l7data[] = { | |
2237 | 0x00, 0x00, 0x00, 0x85, 0xff, 0x53, 0x4d, 0x42, | |
2238 | 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xc8, | |
2239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, | |
2241 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02, | |
2242 | 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, | |
2243 | 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, | |
2244 | 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, | |
2245 | 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, | |
2246 | 0x30, 0x00, 0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f, | |
2247 | 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57, | |
2248 | 0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, | |
2249 | 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61, 0x00, 0x02, | |
2250 | 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, | |
2251 | 0x32, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, | |
2252 | 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54, | |
2253 | 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, | |
2254 | 0x00 | |
2255 | }; | |
2256 | char *buf; | |
2257 | int r = 0; | |
2258 | Flow f; | |
1f00ff6a | 2259 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2260 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 | 2261 | |
634eb1d3 VJ |
2262 | memset(&f, 0x00, sizeof(f)); |
2263 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
2264 | ||
429c6388 | 2265 | memset(pm_results, 0, sizeof(pm_results)); |
57331ea2 | 2266 | |
429c6388 AS |
2267 | buf = "|ff|SMB"; |
2268 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB, buf, 8, 4, STREAM_TOCLIENT); | |
57331ea2 | 2269 | |
429c6388 AS |
2270 | AppLayerProtoDetectPrepareState(); |
2271 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2272 | * it sets internal structures which depends on the above function. */ | |
2273 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
57331ea2 | 2274 | |
429c6388 AS |
2275 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { |
2276 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
2277 | goto end; | |
2278 | } | |
2279 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { | |
2280 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
2281 | goto end; | |
57331ea2 KK |
2282 | } |
2283 | ||
429c6388 AS |
2284 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { |
2285 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
2286 | goto end; | |
2287 | } | |
2288 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
2289 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
2290 | goto end; | |
57331ea2 KK |
2291 | } |
2292 | ||
429c6388 AS |
2293 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_SMB) { |
2294 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_SMB\n"); | |
2295 | goto end; | |
2296 | } | |
57331ea2 | 2297 | |
429c6388 AS |
2298 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, |
2299 | &f, | |
2300 | l7data, sizeof(l7data), | |
2301 | STREAM_TOCLIENT, | |
2302 | IPPROTO_TCP, | |
2303 | pm_results); | |
2304 | if (cnt != 1 && pm_results[0] != ALPROTO_SMB) { | |
2305 | printf("cnt != 1 && pm_results[0] != AlPROTO_SMB\n"); | |
2306 | goto end; | |
57331ea2 KK |
2307 | } |
2308 | ||
429c6388 | 2309 | r = 1; |
41e6735b | 2310 | |
429c6388 AS |
2311 | end: |
2312 | if (alpd_tctx != NULL) | |
2313 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2314 | AppLayerProtoDetectDeSetup(); | |
2315 | AppLayerProtoDetectUnittestCtxRestore(); | |
57331ea2 KK |
2316 | return r; |
2317 | } | |
2318 | ||
429c6388 AS |
2319 | int AppLayerProtoDetectTest09(void) |
2320 | { | |
2321 | AppLayerProtoDetectUnittestCtxBackup(); | |
2322 | AppLayerProtoDetectSetup(); | |
2323 | ||
2324 | uint8_t l7data[] = { | |
2325 | 0x00, 0x00, 0x00, 0x66, 0xfe, 0x53, 0x4d, 0x42, | |
2326 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2327 | 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2328 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2329 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2330 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2331 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2332 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2333 | 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x00, | |
2334 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2335 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2336 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2337 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2338 | 0x00, 0x02, 0x02 | |
2339 | }; | |
2340 | char *buf; | |
2341 | int r = 0; | |
2342 | Flow f; | |
1f00ff6a | 2343 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2344 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
73bdc8a5 | 2345 | |
634eb1d3 VJ |
2346 | memset(&f, 0x00, sizeof(f)); |
2347 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
2348 | ||
429c6388 | 2349 | memset(pm_results, 0, sizeof(pm_results)); |
57331ea2 | 2350 | |
429c6388 AS |
2351 | buf = "|fe|SMB"; |
2352 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2, buf, 8, 4, STREAM_TOCLIENT); | |
57331ea2 | 2353 | |
429c6388 AS |
2354 | AppLayerProtoDetectPrepareState(); |
2355 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2356 | * it sets internal structures which depends on the above function. */ | |
2357 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
57331ea2 | 2358 | |
429c6388 AS |
2359 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { |
2360 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
2361 | goto end; | |
2362 | } | |
2363 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { | |
2364 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
2365 | goto end; | |
57331ea2 KK |
2366 | } |
2367 | ||
429c6388 AS |
2368 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { |
2369 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
2370 | goto end; | |
2371 | } | |
2372 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
2373 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
2374 | goto end; | |
57331ea2 KK |
2375 | } |
2376 | ||
429c6388 AS |
2377 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_SMB2) { |
2378 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_SMB2\n"); | |
2379 | goto end; | |
2380 | } | |
57331ea2 | 2381 | |
429c6388 AS |
2382 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, |
2383 | &f, | |
2384 | l7data, sizeof(l7data), | |
2385 | STREAM_TOCLIENT, | |
2386 | IPPROTO_TCP, | |
2387 | pm_results); | |
2388 | if (cnt != 1 && pm_results[0] != ALPROTO_SMB2) { | |
2389 | printf("cnt != 1 && pm_results[0] != AlPROTO_SMB2\n"); | |
2390 | goto end; | |
57331ea2 KK |
2391 | } |
2392 | ||
429c6388 | 2393 | r = 1; |
41e6735b | 2394 | |
429c6388 AS |
2395 | end: |
2396 | if (alpd_tctx != NULL) | |
2397 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2398 | AppLayerProtoDetectDeSetup(); | |
2399 | AppLayerProtoDetectUnittestCtxRestore(); | |
57331ea2 KK |
2400 | return r; |
2401 | } | |
2402 | ||
429c6388 AS |
2403 | int AppLayerProtoDetectTest10(void) |
2404 | { | |
2405 | AppLayerProtoDetectUnittestCtxBackup(); | |
2406 | AppLayerProtoDetectSetup(); | |
2407 | ||
2408 | uint8_t l7data[] = { | |
2409 | 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, | |
2410 | 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2411 | 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, | |
2412 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, | |
2413 | 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11, | |
2414 | 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57, | |
2415 | 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, | |
2416 | 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, | |
2417 | 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 | |
2418 | }; | |
2419 | char *buf; | |
2420 | int r = 0; | |
2421 | Flow f; | |
1f00ff6a | 2422 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2423 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 | 2424 | |
634eb1d3 VJ |
2425 | memset(&f, 0x00, sizeof(f)); |
2426 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
2427 | ||
429c6388 | 2428 | memset(pm_results, 0, sizeof(pm_results)); |
57331ea2 | 2429 | |
429c6388 AS |
2430 | buf = "|05 00|"; |
2431 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC, buf, 4, 0, STREAM_TOCLIENT); | |
57331ea2 | 2432 | |
429c6388 AS |
2433 | AppLayerProtoDetectPrepareState(); |
2434 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2435 | * it sets internal structures which depends on the above function. */ | |
2436 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
57331ea2 | 2437 | |
429c6388 AS |
2438 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { |
2439 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); | |
2440 | goto end; | |
2441 | } | |
2442 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { | |
2443 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); | |
2444 | goto end; | |
57331ea2 KK |
2445 | } |
2446 | ||
429c6388 AS |
2447 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { |
2448 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
2449 | goto end; | |
2450 | } | |
2451 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
2452 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
2453 | goto end; | |
57331ea2 KK |
2454 | } |
2455 | ||
429c6388 AS |
2456 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_DCERPC) { |
2457 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_DCERPC\n"); | |
2458 | goto end; | |
2459 | } | |
57331ea2 | 2460 | |
429c6388 AS |
2461 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, |
2462 | &f, | |
2463 | l7data, sizeof(l7data), | |
2464 | STREAM_TOCLIENT, | |
2465 | IPPROTO_TCP, | |
2466 | pm_results); | |
2467 | if (cnt != 1 && pm_results[0] != ALPROTO_DCERPC) { | |
2468 | printf("cnt != 1 && pm_results[0] != AlPROTO_DCERPC\n"); | |
2469 | goto end; | |
57331ea2 KK |
2470 | } |
2471 | ||
429c6388 | 2472 | r = 1; |
41e6735b | 2473 | |
429c6388 AS |
2474 | end: |
2475 | if (alpd_tctx != NULL) | |
2476 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2477 | AppLayerProtoDetectDeSetup(); | |
2478 | AppLayerProtoDetectUnittestCtxRestore(); | |
57331ea2 KK |
2479 | return r; |
2480 | } | |
2481 | ||
429c6388 AS |
2482 | /** |
2483 | * \test Why we still get http for connect... obviously because | |
2484 | * we also match on the reply, duh | |
2485 | */ | |
2486 | int AppLayerProtoDetectTest11(void) | |
2487 | { | |
2488 | AppLayerProtoDetectUnittestCtxBackup(); | |
2489 | AppLayerProtoDetectSetup(); | |
2490 | ||
fd409049 VJ |
2491 | uint8_t l7data[] = "CONNECT www.ssllabs.com:443 HTTP/1.0\r\n"; |
2492 | uint8_t l7data_resp[] = "HTTP/1.1 405 Method Not Allowed\r\n"; | |
429c6388 AS |
2493 | int r = 0; |
2494 | Flow f; | |
1f00ff6a | 2495 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2496 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 | 2497 | |
634eb1d3 VJ |
2498 | memset(&f, 0x00, sizeof(f)); |
2499 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
2500 | ||
429c6388 AS |
2501 | memset(pm_results, 0, sizeof(pm_results)); |
2502 | ||
2503 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOSERVER); | |
2504 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "GET", 3, 0, STREAM_TOSERVER); | |
2505 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "PUT", 3, 0, STREAM_TOSERVER); | |
2506 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "POST", 4, 0, STREAM_TOSERVER); | |
2507 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "TRACE", 5, 0, STREAM_TOSERVER); | |
2508 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "OPTIONS", 7, 0, STREAM_TOSERVER); | |
2509 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "CONNECT", 7, 0, STREAM_TOSERVER); | |
2510 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOCLIENT); | |
2511 | ||
2512 | AppLayerProtoDetectPrepareState(); | |
2513 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2514 | * it sets internal structures which depends on the above function. */ | |
2515 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
2516 | ||
2517 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 7) { | |
2518 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 7\n"); | |
2519 | goto end; | |
2520 | } | |
2521 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { | |
2522 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1\n"); | |
2523 | goto end; | |
fd409049 VJ |
2524 | } |
2525 | ||
429c6388 AS |
2526 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map == NULL) { |
2527 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); | |
2528 | goto end; | |
2529 | } | |
2530 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { | |
2531 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); | |
2532 | goto end; | |
fd409049 VJ |
2533 | } |
2534 | ||
429c6388 AS |
2535 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[0]->alproto != ALPROTO_HTTP || |
2536 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[1]->alproto != ALPROTO_HTTP || | |
2537 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[2]->alproto != ALPROTO_HTTP || | |
2538 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[3]->alproto != ALPROTO_HTTP || | |
2539 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[4]->alproto != ALPROTO_HTTP || | |
2540 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[5]->alproto != ALPROTO_HTTP || | |
2541 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[6]->alproto != ALPROTO_HTTP || | |
2542 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) | |
2543 | { | |
2544 | printf("failure 1\n"); | |
2545 | goto end; | |
2546 | } | |
fd409049 | 2547 | |
429c6388 AS |
2548 | memset(pm_results, 0, sizeof(pm_results)); |
2549 | uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, | |
2550 | &f, | |
2551 | l7data, sizeof(l7data), | |
2552 | STREAM_TOSERVER, | |
2553 | IPPROTO_TCP, | |
2554 | pm_results); | |
2555 | if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { | |
2556 | printf("l7data - cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); | |
2557 | goto end; | |
fd409049 VJ |
2558 | } |
2559 | ||
429c6388 AS |
2560 | memset(pm_results, 0, sizeof(pm_results)); |
2561 | cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, | |
2562 | &f, | |
2563 | l7data_resp, sizeof(l7data_resp), | |
2564 | STREAM_TOCLIENT, | |
2565 | IPPROTO_TCP, | |
2566 | pm_results); | |
2567 | if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { | |
2568 | printf("l7data_resp - cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); | |
2569 | goto end; | |
fd409049 VJ |
2570 | } |
2571 | ||
429c6388 AS |
2572 | r = 1; |
2573 | ||
2574 | end: | |
2575 | if (alpd_tctx != NULL) | |
2576 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2577 | AppLayerProtoDetectDeSetup(); | |
2578 | AppLayerProtoDetectUnittestCtxRestore(); | |
fd409049 VJ |
2579 | return r; |
2580 | } | |
57331ea2 | 2581 | |
429c6388 AS |
2582 | /** |
2583 | * \test AlpProtoSignature test | |
2584 | */ | |
2585 | int AppLayerProtoDetectTest12(void) | |
2586 | { | |
2587 | AppLayerProtoDetectUnittestCtxBackup(); | |
2588 | AppLayerProtoDetectSetup(); | |
7a427ec7 | 2589 | |
429c6388 | 2590 | int r = 0; |
7a427ec7 | 2591 | |
429c6388 AS |
2592 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOSERVER); |
2593 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].head == NULL || | |
2594 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) | |
1f00ff6a VJ |
2595 | { |
2596 | printf("failure 1\n"); | |
2597 | goto end; | |
2598 | } | |
7a427ec7 | 2599 | |
429c6388 AS |
2600 | AppLayerProtoDetectPrepareState(); |
2601 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 1) { | |
2602 | printf("failure 2\n"); | |
7a427ec7 VJ |
2603 | goto end; |
2604 | } | |
429c6388 AS |
2605 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].head != NULL || |
2606 | alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map == NULL) | |
1f00ff6a VJ |
2607 | { |
2608 | printf("failure 3\n"); | |
2609 | goto end; | |
2610 | } | |
429c6388 AS |
2611 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[0]->alproto != ALPROTO_HTTP) { |
2612 | printf("failure 4\n"); | |
7a427ec7 VJ |
2613 | goto end; |
2614 | } | |
429c6388 AS |
2615 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[0]->cd->id != 0) { |
2616 | printf("failure 5\n"); | |
7a427ec7 VJ |
2617 | goto end; |
2618 | } | |
429c6388 AS |
2619 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[0]->next != NULL) { |
2620 | printf("failure 6\n"); | |
7a427ec7 VJ |
2621 | goto end; |
2622 | } | |
2623 | ||
2624 | r = 1; | |
429c6388 AS |
2625 | |
2626 | end: | |
2627 | AppLayerProtoDetectDeSetup(); | |
2628 | AppLayerProtoDetectUnittestCtxRestore(); | |
7a427ec7 VJ |
2629 | return r; |
2630 | } | |
2631 | ||
8cc525c9 PR |
2632 | /** |
2633 | * \test What about if we add some sigs only for udp but call for tcp? | |
2634 | * It should not detect any proto | |
2635 | */ | |
429c6388 AS |
2636 | int AppLayerProtoDetectTest13(void) |
2637 | { | |
2638 | AppLayerProtoDetectUnittestCtxBackup(); | |
2639 | AppLayerProtoDetectSetup(); | |
2640 | ||
8cc525c9 PR |
2641 | uint8_t l7data[] = "CONNECT www.ssllabs.com:443 HTTP/1.0\r\n"; |
2642 | uint8_t l7data_resp[] = "HTTP/1.1 405 Method Not Allowed\r\n"; | |
429c6388 AS |
2643 | int r = 0; |
2644 | Flow f; | |
1f00ff6a | 2645 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2646 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 AS |
2647 | uint32_t cnt; |
2648 | ||
634eb1d3 VJ |
2649 | memset(&f, 0x00, sizeof(f)); |
2650 | f.protomap = FlowGetProtoMapping(IPPROTO_TCP); | |
2651 | ||
429c6388 AS |
2652 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOSERVER); |
2653 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "GET", 3, 0, STREAM_TOSERVER); | |
2654 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "PUT", 3, 0, STREAM_TOSERVER); | |
2655 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "POST", 4, 0, STREAM_TOSERVER); | |
2656 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "TRACE", 5, 0, STREAM_TOSERVER); | |
2657 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "OPTIONS", 7, 0, STREAM_TOSERVER); | |
2658 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "CONNECT", 7, 0, STREAM_TOSERVER); | |
2659 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOCLIENT); | |
2660 | ||
2661 | AppLayerProtoDetectPrepareState(); | |
2662 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2663 | * it sets internal structures which depends on the above function. */ | |
2664 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
2665 | ||
2666 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].max_pat_id != 7) { | |
2667 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].max_pat_id != 7\n"); | |
2668 | goto end; | |
8cc525c9 | 2669 | } |
429c6388 AS |
2670 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].max_pat_id != 1) { |
2671 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].max_pat_id != 1\n"); | |
2672 | goto end; | |
8cc525c9 PR |
2673 | } |
2674 | ||
429c6388 AS |
2675 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[0]->alproto != ALPROTO_HTTP || |
2676 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[1]->alproto != ALPROTO_HTTP || | |
2677 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[2]->alproto != ALPROTO_HTTP || | |
2678 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[3]->alproto != ALPROTO_HTTP || | |
2679 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[4]->alproto != ALPROTO_HTTP || | |
2680 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[5]->alproto != ALPROTO_HTTP || | |
2681 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[6]->alproto != ALPROTO_HTTP || | |
2682 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) | |
2683 | { | |
2684 | printf("failure 1\n"); | |
2685 | goto end; | |
2686 | } | |
8cc525c9 | 2687 | |
429c6388 AS |
2688 | memset(pm_results, 0, sizeof(pm_results)); |
2689 | cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, | |
2690 | &f, | |
2691 | l7data, sizeof(l7data), | |
2692 | STREAM_TOSERVER, | |
2693 | IPPROTO_TCP, | |
2694 | pm_results); | |
2695 | if (cnt != 0) { | |
2696 | printf("l7data - cnt != 0\n"); | |
2697 | goto end; | |
8cc525c9 PR |
2698 | } |
2699 | ||
429c6388 AS |
2700 | memset(pm_results, 0, sizeof(pm_results)); |
2701 | cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, | |
2702 | &f, | |
2703 | l7data_resp, sizeof(l7data_resp), | |
2704 | STREAM_TOCLIENT, | |
2705 | IPPROTO_TCP, | |
2706 | pm_results); | |
2707 | if (cnt != 0) { | |
2708 | printf("l7data_resp - cnt != 0\n"); | |
2709 | goto end; | |
8cc525c9 PR |
2710 | } |
2711 | ||
429c6388 AS |
2712 | r = 1; |
2713 | ||
2714 | end: | |
2715 | if (alpd_tctx != NULL) | |
2716 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2717 | AppLayerProtoDetectDeSetup(); | |
2718 | AppLayerProtoDetectUnittestCtxRestore(); | |
8cc525c9 PR |
2719 | return r; |
2720 | } | |
2721 | ||
2722 | /** | |
2723 | * \test What about if we add some sigs only for udp calling it for UDP? | |
2724 | * It should detect ALPROTO_HTTP (over udp). This is just a check | |
2725 | * to ensure that TCP/UDP differences work correctly. | |
2726 | */ | |
429c6388 AS |
2727 | int AppLayerProtoDetectTest14(void) |
2728 | { | |
2729 | AppLayerProtoDetectUnittestCtxBackup(); | |
2730 | AppLayerProtoDetectSetup(); | |
2731 | ||
8cc525c9 PR |
2732 | uint8_t l7data[] = "CONNECT www.ssllabs.com:443 HTTP/1.0\r\n"; |
2733 | uint8_t l7data_resp[] = "HTTP/1.1 405 Method Not Allowed\r\n"; | |
429c6388 AS |
2734 | int r = 0; |
2735 | Flow f; | |
1f00ff6a | 2736 | AppProto pm_results[ALPROTO_MAX]; |
3b8e9ffb | 2737 | AppLayerProtoDetectThreadCtx *alpd_tctx; |
429c6388 AS |
2738 | uint32_t cnt; |
2739 | ||
634eb1d3 VJ |
2740 | memset(&f, 0x00, sizeof(f)); |
2741 | f.protomap = FlowGetProtoMapping(IPPROTO_UDP); | |
2742 | ||
429c6388 AS |
2743 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOSERVER); |
2744 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "GET", 3, 0, STREAM_TOSERVER); | |
2745 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "PUT", 3, 0, STREAM_TOSERVER); | |
2746 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "POST", 4, 0, STREAM_TOSERVER); | |
2747 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "TRACE", 5, 0, STREAM_TOSERVER); | |
2748 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "OPTIONS", 7, 0, STREAM_TOSERVER); | |
2749 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "CONNECT", 7, 0, STREAM_TOSERVER); | |
2750 | AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOCLIENT); | |
2751 | ||
2752 | AppLayerProtoDetectPrepareState(); | |
2753 | /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since | |
2754 | * it sets internal structures which depends on the above function. */ | |
2755 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
2756 | ||
2757 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].max_pat_id != 7) { | |
2758 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].max_pat_id != 7\n"); | |
2759 | goto end; | |
2760 | } | |
2761 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].max_pat_id != 1) { | |
2762 | printf("alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].max_pat_id != 1\n"); | |
2763 | goto end; | |
2764 | } | |
8cc525c9 | 2765 | |
429c6388 AS |
2766 | if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[0]->alproto != ALPROTO_HTTP || |
2767 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[1]->alproto != ALPROTO_HTTP || | |
2768 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[2]->alproto != ALPROTO_HTTP || | |
2769 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[3]->alproto != ALPROTO_HTTP || | |
2770 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[4]->alproto != ALPROTO_HTTP || | |
2771 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[5]->alproto != ALPROTO_HTTP || | |
2772 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[6]->alproto != ALPROTO_HTTP || | |
2773 | alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) | |
2774 | { | |
2775 | printf("failure 1\n"); | |
2776 | goto end; | |
2777 | } | |
8cc525c9 | 2778 | |
429c6388 AS |
2779 | memset(pm_results, 0, sizeof(pm_results)); |
2780 | cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, | |
2781 | &f, | |
2782 | l7data, sizeof(l7data), | |
2783 | STREAM_TOSERVER, | |
2784 | IPPROTO_UDP, | |
2785 | pm_results); | |
2786 | if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { | |
2787 | printf("l7data - cnt != 0\n"); | |
2788 | goto end; | |
8cc525c9 PR |
2789 | } |
2790 | ||
429c6388 AS |
2791 | memset(pm_results, 0, sizeof(pm_results)); |
2792 | cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, | |
2793 | &f, | |
2794 | l7data_resp, sizeof(l7data_resp), | |
2795 | STREAM_TOCLIENT, | |
2796 | IPPROTO_UDP, | |
2797 | pm_results); | |
2798 | if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { | |
2799 | printf("l7data_resp - cnt != 0\n"); | |
2800 | goto end; | |
8cc525c9 PR |
2801 | } |
2802 | ||
429c6388 | 2803 | r = 1; |
8cc525c9 | 2804 | |
429c6388 AS |
2805 | end: |
2806 | if (alpd_tctx != NULL) | |
2807 | AppLayerProtoDetectDestroyCtxThread(alpd_tctx); | |
2808 | AppLayerProtoDetectDeSetup(); | |
2809 | AppLayerProtoDetectUnittestCtxRestore(); | |
2810 | return r; | |
2811 | } | |
2812 | ||
429c6388 AS |
2813 | typedef struct AppLayerProtoDetectPPTestDataElement_ { |
2814 | char *alproto_name; | |
f5f14880 | 2815 | AppProto alproto; |
429c6388 AS |
2816 | uint16_t port; |
2817 | uint32_t alproto_mask; | |
2818 | uint32_t min_depth; | |
2819 | uint32_t max_depth; | |
2820 | } AppLayerProtoDetectPPTestDataElement; | |
2821 | ||
2822 | typedef struct AppLayerProtoDetectPPTestDataPort_ { | |
2823 | uint16_t port; | |
3df90447 | 2824 | uint32_t alproto_mask; |
eae5b1ba VJ |
2825 | uint16_t dp_max_depth; |
2826 | uint16_t sp_max_depth; | |
429c6388 AS |
2827 | |
2828 | AppLayerProtoDetectPPTestDataElement *toserver_element; | |
2829 | AppLayerProtoDetectPPTestDataElement *toclient_element; | |
2830 | int ts_no_of_element; | |
2831 | int tc_no_of_element; | |
2832 | } AppLayerProtoDetectPPTestDataPort; | |
2833 | ||
2834 | ||
2835 | typedef struct AppLayerProtoDetectPPTestDataIPProto_ { | |
1f00ff6a | 2836 | uint8_t ipproto; |
429c6388 AS |
2837 | |
2838 | AppLayerProtoDetectPPTestDataPort *port; | |
2839 | int no_of_port; | |
2840 | } AppLayerProtoDetectPPTestDataIPProto; | |
2841 | ||
2842 | static int AppLayerProtoDetectPPTestData(AppLayerProtoDetectProbingParser *pp, | |
2843 | AppLayerProtoDetectPPTestDataIPProto *ip_proto, | |
2844 | int no_of_ip_proto) | |
2845 | { | |
2846 | int result = 0; | |
ff16d6fa | 2847 | int i = -1, j = -1 , k = -1; |
429c6388 AS |
2848 | #ifdef DEBUG |
2849 | int dir = 0; | |
2850 | #endif | |
2851 | for (i = 0; i < no_of_ip_proto; i++, pp = pp->next) { | |
1f00ff6a | 2852 | if (pp->ipproto != ip_proto[i].ipproto) |
429c6388 AS |
2853 | goto end; |
2854 | ||
2855 | AppLayerProtoDetectProbingParserPort *pp_port = pp->port; | |
2856 | for (k = 0; k < ip_proto[i].no_of_port; k++, pp_port = pp_port->next) { | |
2857 | if (pp_port->port != ip_proto[i].port[k].port) | |
2858 | goto end; | |
3df90447 | 2859 | if (pp_port->alproto_mask != ip_proto[i].port[k].alproto_mask) |
429c6388 | 2860 | goto end; |
3df90447 | 2861 | if (pp_port->alproto_mask != ip_proto[i].port[k].alproto_mask) |
429c6388 | 2862 | goto end; |
eae5b1ba | 2863 | if (pp_port->dp_max_depth != ip_proto[i].port[k].dp_max_depth) |
429c6388 | 2864 | goto end; |
eae5b1ba | 2865 | if (pp_port->sp_max_depth != ip_proto[i].port[k].sp_max_depth) |
429c6388 AS |
2866 | goto end; |
2867 | ||
eae5b1ba | 2868 | AppLayerProtoDetectProbingParserElement *pp_element = pp_port->dp; |
429c6388 AS |
2869 | #ifdef DEBUG |
2870 | dir = 0; | |
2871 | #endif | |
2872 | for (j = 0 ; j < ip_proto[i].port[k].ts_no_of_element; | |
2873 | j++, pp_element = pp_element->next) { | |
2874 | ||
2875 | if (pp_element->alproto != ip_proto[i].port[k].toserver_element[j].alproto) { | |
2876 | goto end; | |
2877 | } | |
2878 | if (pp_element->port != ip_proto[i].port[k].toserver_element[j].port) { | |
2879 | goto end; | |
2880 | } | |
2881 | if (pp_element->alproto_mask != ip_proto[i].port[k].toserver_element[j].alproto_mask) { | |
2882 | goto end; | |
2883 | } | |
2884 | if (pp_element->min_depth != ip_proto[i].port[k].toserver_element[j].min_depth) { | |
2885 | goto end; | |
2886 | } | |
2887 | if (pp_element->max_depth != ip_proto[i].port[k].toserver_element[j].max_depth) { | |
2888 | goto end; | |
2889 | } | |
2890 | } /* for */ | |
2891 | if (pp_element != NULL) | |
2892 | goto end; | |
2893 | ||
eae5b1ba | 2894 | pp_element = pp_port->sp; |
429c6388 AS |
2895 | #ifdef DEBUG |
2896 | dir = 1; | |
2897 | #endif | |
2898 | for (j = 0 ; j < ip_proto[i].port[k].tc_no_of_element; j++, pp_element = pp_element->next) { | |
2899 | if (pp_element->alproto != ip_proto[i].port[k].toclient_element[j].alproto) { | |
2900 | goto end; | |
2901 | } | |
2902 | if (pp_element->port != ip_proto[i].port[k].toclient_element[j].port) { | |
2903 | goto end; | |
2904 | } | |
2905 | if (pp_element->alproto_mask != ip_proto[i].port[k].toclient_element[j].alproto_mask) { | |
2906 | goto end; | |
2907 | } | |
2908 | if (pp_element->min_depth != ip_proto[i].port[k].toclient_element[j].min_depth) { | |
2909 | goto end; | |
2910 | } | |
2911 | if (pp_element->max_depth != ip_proto[i].port[k].toclient_element[j].max_depth) { | |
2912 | goto end; | |
2913 | } | |
2914 | } /* for */ | |
2915 | if (pp_element != NULL) | |
2916 | goto end; | |
2917 | } | |
2918 | if (pp_port != NULL) | |
2919 | goto end; | |
8cc525c9 | 2920 | } |
429c6388 AS |
2921 | if (pp != NULL) |
2922 | goto end; | |
2923 | ||
2924 | result = 1; | |
2925 | end: | |
2926 | #ifdef DEBUG | |
2927 | printf("i = %d, k = %d, j = %d(%s)\n", i, k, j, (dir == 0) ? "ts" : "tc"); | |
2928 | #endif | |
2929 | return result; | |
2930 | } | |
2931 | ||
2932 | static uint16_t ProbingParserDummyForTesting(uint8_t *input, | |
2933 | uint32_t input_len, | |
2934 | uint32_t *offset) | |
2935 | { | |
2936 | return 0; | |
2937 | } | |
2938 | ||
2939 | static int AppLayerProtoDetectTest15(void) | |
2940 | { | |
2941 | AppLayerProtoDetectUnittestCtxBackup(); | |
2942 | AppLayerProtoDetectSetup(); | |
2943 | ||
2944 | int result = 0; | |
2945 | ||
2946 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2947 | "80", | |
2948 | ALPROTO_HTTP, | |
2949 | 5, 8, | |
2950 | STREAM_TOSERVER, | |
2951 | ProbingParserDummyForTesting); | |
2952 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2953 | "80", | |
2954 | ALPROTO_SMB, | |
2955 | 5, 6, | |
2956 | STREAM_TOSERVER, | |
2957 | ProbingParserDummyForTesting); | |
2958 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2959 | "80", | |
2960 | ALPROTO_FTP, | |
2961 | 7, 10, | |
2962 | STREAM_TOSERVER, | |
2963 | ProbingParserDummyForTesting); | |
2964 | ||
2965 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2966 | "81", | |
2967 | ALPROTO_DCERPC, | |
2968 | 9, 10, | |
2969 | STREAM_TOSERVER, | |
2970 | ProbingParserDummyForTesting); | |
2971 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2972 | "81", | |
2973 | ALPROTO_FTP, | |
2974 | 7, 15, | |
2975 | STREAM_TOSERVER, | |
2976 | ProbingParserDummyForTesting); | |
2977 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2978 | "0", | |
2979 | ALPROTO_SMTP, | |
2980 | 12, 0, | |
2981 | STREAM_TOSERVER, | |
2982 | ProbingParserDummyForTesting); | |
2983 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2984 | "0", | |
2985 | ALPROTO_TLS, | |
2986 | 12, 18, | |
2987 | STREAM_TOSERVER, | |
2988 | ProbingParserDummyForTesting); | |
2989 | ||
2990 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2991 | "85", | |
2992 | ALPROTO_DCERPC, | |
2993 | 9, 10, | |
2994 | STREAM_TOSERVER, | |
2995 | ProbingParserDummyForTesting); | |
2996 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
2997 | "85", | |
2998 | ALPROTO_FTP, | |
2999 | 7, 15, | |
3000 | STREAM_TOSERVER, | |
3001 | ProbingParserDummyForTesting); | |
3002 | result = 1; | |
8cc525c9 | 3003 | |
429c6388 AS |
3004 | AppLayerProtoDetectPPRegister(IPPROTO_UDP, |
3005 | "85", | |
3006 | ALPROTO_IMAP, | |
3007 | 12, 23, | |
3008 | STREAM_TOSERVER, | |
3009 | ProbingParserDummyForTesting); | |
3010 | ||
3011 | /* toclient */ | |
3012 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3013 | "0", | |
3014 | ALPROTO_JABBER, | |
3015 | 12, 23, | |
3016 | STREAM_TOCLIENT, | |
3017 | ProbingParserDummyForTesting); | |
3018 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3019 | "0", | |
3020 | ALPROTO_IRC, | |
3021 | 12, 14, | |
3022 | STREAM_TOCLIENT, | |
3023 | ProbingParserDummyForTesting); | |
3024 | ||
3025 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3026 | "85", | |
3027 | ALPROTO_DCERPC, | |
3028 | 9, 10, | |
3029 | STREAM_TOCLIENT, | |
3030 | ProbingParserDummyForTesting); | |
3031 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3032 | "81", | |
3033 | ALPROTO_FTP, | |
3034 | 7, 15, | |
3035 | STREAM_TOCLIENT, | |
3036 | ProbingParserDummyForTesting); | |
3037 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3038 | "0", | |
3039 | ALPROTO_TLS, | |
3040 | 12, 18, | |
3041 | STREAM_TOCLIENT, | |
3042 | ProbingParserDummyForTesting); | |
3043 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3044 | "80", | |
3045 | ALPROTO_HTTP, | |
3046 | 5, 8, | |
3047 | STREAM_TOCLIENT, | |
3048 | ProbingParserDummyForTesting); | |
3049 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3050 | "81", | |
3051 | ALPROTO_DCERPC, | |
3052 | 9, 10, | |
3053 | STREAM_TOCLIENT, | |
3054 | ProbingParserDummyForTesting); | |
3055 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3056 | "90", | |
3057 | ALPROTO_FTP, | |
3058 | 7, 15, | |
3059 | STREAM_TOCLIENT, | |
3060 | ProbingParserDummyForTesting); | |
3061 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3062 | "80", | |
3063 | ALPROTO_SMB, | |
3064 | 5, 6, | |
3065 | STREAM_TOCLIENT, | |
3066 | ProbingParserDummyForTesting); | |
3067 | AppLayerProtoDetectPPRegister(IPPROTO_UDP, | |
3068 | "85", | |
3069 | ALPROTO_IMAP, | |
3070 | 12, 23, | |
3071 | STREAM_TOCLIENT, | |
3072 | ProbingParserDummyForTesting); | |
3073 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3074 | "0", | |
3075 | ALPROTO_SMTP, | |
3076 | 12, 17, | |
3077 | STREAM_TOCLIENT, | |
3078 | ProbingParserDummyForTesting); | |
3079 | AppLayerProtoDetectPPRegister(IPPROTO_TCP, | |
3080 | "80", | |
3081 | ALPROTO_FTP, | |
3082 | 7, 10, | |
3083 | STREAM_TOCLIENT, | |
3084 | ProbingParserDummyForTesting); | |
3085 | ||
3086 | AppLayerProtoDetectPPTestDataElement element_ts_80[] = { | |
3087 | { "http", ALPROTO_HTTP, 80, 1 << ALPROTO_HTTP, 5, 8 }, | |
3088 | { "smb", ALPROTO_SMB, 80, 1 << ALPROTO_SMB, 5, 6 }, | |
3089 | { "ftp", ALPROTO_FTP, 80, 1 << ALPROTO_FTP, 7, 10 }, | |
3090 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, | |
3091 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3092 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, | |
3093 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3094 | }; | |
3095 | AppLayerProtoDetectPPTestDataElement element_tc_80[] = { | |
3096 | { "http", ALPROTO_HTTP, 80, 1 << ALPROTO_HTTP, 5, 8 }, | |
3097 | { "smb", ALPROTO_SMB, 80, 1 << ALPROTO_SMB, 5, 6 }, | |
3098 | { "ftp", ALPROTO_FTP, 80, 1 << ALPROTO_FTP, 7, 10 }, | |
3099 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3100 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, | |
3101 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3102 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } | |
3103 | }; | |
3104 | ||
3105 | AppLayerProtoDetectPPTestDataElement element_ts_81[] = { | |
3106 | { "dcerpc", ALPROTO_DCERPC, 81, 1 << ALPROTO_DCERPC, 9, 10 }, | |
3107 | { "ftp", ALPROTO_FTP, 81, 1 << ALPROTO_FTP, 7, 15 }, | |
3108 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, | |
3109 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3110 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, | |
3111 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3112 | }; | |
3113 | AppLayerProtoDetectPPTestDataElement element_tc_81[] = { | |
3114 | { "ftp", ALPROTO_FTP, 81, 1 << ALPROTO_FTP, 7, 15 }, | |
3115 | { "dcerpc", ALPROTO_DCERPC, 81, 1 << ALPROTO_DCERPC, 9, 10 }, | |
3116 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3117 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, | |
3118 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3119 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } | |
3120 | }; | |
3121 | ||
3122 | AppLayerProtoDetectPPTestDataElement element_ts_85[] = { | |
3123 | { "dcerpc", ALPROTO_DCERPC, 85, 1 << ALPROTO_DCERPC, 9, 10 }, | |
3124 | { "ftp", ALPROTO_FTP, 85, 1 << ALPROTO_FTP, 7, 15 }, | |
3125 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, | |
3126 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3127 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, | |
3128 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3129 | }; | |
3130 | AppLayerProtoDetectPPTestDataElement element_tc_85[] = { | |
3131 | { "dcerpc", ALPROTO_DCERPC, 85, 1 << ALPROTO_DCERPC, 9, 10 }, | |
3132 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3133 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, | |
3134 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3135 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } | |
3136 | }; | |
3137 | ||
3138 | AppLayerProtoDetectPPTestDataElement element_ts_90[] = { | |
3139 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, | |
3140 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3141 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, | |
3142 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3143 | }; | |
3144 | AppLayerProtoDetectPPTestDataElement element_tc_90[] = { | |
3145 | { "ftp", ALPROTO_FTP, 90, 1 << ALPROTO_FTP, 7, 15 }, | |
3146 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3147 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, | |
3148 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3149 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } | |
3150 | }; | |
3151 | ||
3152 | AppLayerProtoDetectPPTestDataElement element_ts_0[] = { | |
3153 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, | |
3154 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3155 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, | |
3156 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3157 | }; | |
3158 | AppLayerProtoDetectPPTestDataElement element_tc_0[] = { | |
3159 | { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, | |
3160 | { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, | |
3161 | { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, | |
3162 | { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } | |
3163 | }; | |
3164 | ||
3165 | ||
3166 | AppLayerProtoDetectPPTestDataElement element_ts_85_udp[] = { | |
3167 | { "imap", ALPROTO_IMAP, 85, 1 << ALPROTO_IMAP, 12, 23 }, | |
3168 | }; | |
3169 | AppLayerProtoDetectPPTestDataElement element_tc_85_udp[] = { | |
3170 | { "imap", ALPROTO_IMAP, 85, 1 << ALPROTO_IMAP, 12, 23 }, | |
3171 | }; | |
3172 | ||
3173 | AppLayerProtoDetectPPTestDataPort ports_tcp[] = { | |
3174 | { 80, | |
3175 | ((1 << ALPROTO_HTTP) | (1 << ALPROTO_SMB) | (1 << ALPROTO_FTP) | | |
3176 | (1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), | |
3177 | ((1 << ALPROTO_HTTP) | (1 << ALPROTO_SMB) | (1 << ALPROTO_FTP) | | |
3178 | (1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), | |
3df90447 | 3179 | 23, |
429c6388 AS |
3180 | element_ts_80, element_tc_80, |
3181 | sizeof(element_ts_80) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3182 | sizeof(element_tc_80) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3183 | }, | |
3184 | { 81, | |
3185 | ((1 << ALPROTO_DCERPC) | (1 << ALPROTO_FTP) | | |
3186 | (1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), | |
3187 | ((1 << ALPROTO_FTP) | (1 << ALPROTO_DCERPC) | | |
3188 | (1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), | |
3df90447 | 3189 | 23, |
429c6388 AS |
3190 | element_ts_81, element_tc_81, |
3191 | sizeof(element_ts_81) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3192 | sizeof(element_tc_81) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3193 | }, | |
3194 | { 85, | |
3195 | ((1 << ALPROTO_DCERPC) | (1 << ALPROTO_FTP) | | |
3196 | (1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), | |
3197 | ((1 << ALPROTO_DCERPC) | | |
3198 | (1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), | |
3df90447 | 3199 | 23, |
429c6388 AS |
3200 | element_ts_85, element_tc_85, |
3201 | sizeof(element_ts_85) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3202 | sizeof(element_tc_85) / sizeof(AppLayerProtoDetectPPTestDataElement) | |
3203 | }, | |
3204 | { 90, | |
3205 | ((1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), | |
3206 | ((1 << ALPROTO_FTP) | | |
3207 | (1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), | |
3df90447 | 3208 | 23, |
429c6388 AS |
3209 | element_ts_90, element_tc_90, |
3210 | sizeof(element_ts_90) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3211 | sizeof(element_tc_90) / sizeof(AppLayerProtoDetectPPTestDataElement) | |
3212 | }, | |
3213 | { 0, | |
3214 | ((1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), | |
3215 | ((1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), | |
3df90447 | 3216 | 23, |
429c6388 AS |
3217 | element_ts_0, element_tc_0, |
3218 | sizeof(element_ts_0) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3219 | sizeof(element_tc_0) / sizeof(AppLayerProtoDetectPPTestDataElement) | |
3220 | } | |
3221 | }; | |
3222 | ||
3223 | AppLayerProtoDetectPPTestDataPort ports_udp[] = { | |
3224 | { 85, | |
3225 | (1 << ALPROTO_IMAP), | |
3226 | (1 << ALPROTO_IMAP), | |
3df90447 | 3227 | 23, |
429c6388 AS |
3228 | element_ts_85_udp, element_tc_85_udp, |
3229 | sizeof(element_ts_85_udp) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3230 | sizeof(element_tc_85_udp) / sizeof(AppLayerProtoDetectPPTestDataElement), | |
3231 | }, | |
3232 | }; | |
3233 | ||
3234 | AppLayerProtoDetectPPTestDataIPProto ip_proto[] = { | |
3235 | { IPPROTO_TCP, | |
3236 | ports_tcp, | |
3237 | sizeof(ports_tcp) / sizeof(AppLayerProtoDetectPPTestDataPort), | |
3238 | }, | |
3239 | { IPPROTO_UDP, | |
3240 | ports_udp, | |
3241 | sizeof(ports_udp) / sizeof(AppLayerProtoDetectPPTestDataPort), | |
3242 | }, | |
3243 | }; | |
3244 | ||
3245 | ||
3246 | if (AppLayerProtoDetectPPTestData(alpd_ctx.ctx_pp, ip_proto, | |
3247 | sizeof(ip_proto) / sizeof(AppLayerProtoDetectPPTestDataIPProto)) == 0) { | |
3248 | goto end; | |
8cc525c9 | 3249 | } |
429c6388 | 3250 | result = 1; |
8cc525c9 | 3251 | |
429c6388 AS |
3252 | end: |
3253 | AppLayerProtoDetectDeSetup(); | |
3254 | AppLayerProtoDetectUnittestCtxRestore(); | |
3255 | return result; | |
8cc525c9 PR |
3256 | } |
3257 | ||
429c6388 | 3258 | |
c6e090f7 | 3259 | /** \test test if the engine detect the proto and match with it */ |
429c6388 | 3260 | static int AppLayerProtoDetectTest16(void) |
c6e090f7 PR |
3261 | { |
3262 | int result = 0; | |
262a7300 | 3263 | Flow *f = NULL; |
c6e090f7 PR |
3264 | HtpState *http_state = NULL; |
3265 | uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" | |
3266 | "User-Agent: Mozilla/1.0\r\n" | |
3267 | "Cookie: hellocatch\r\n\r\n"; | |
3268 | uint32_t http_buf1_len = sizeof(http_buf1) - 1; | |
3269 | TcpSession ssn; | |
1071a532 | 3270 | Packet *p = NULL; |
c6e090f7 PR |
3271 | Signature *s = NULL; |
3272 | ThreadVars tv; | |
3273 | DetectEngineThreadCtx *det_ctx = NULL; | |
71732567 | 3274 | DetectEngineCtx *de_ctx = NULL; |
8dbf7a0d | 3275 | AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); |
c6e090f7 PR |
3276 | |
3277 | memset(&tv, 0, sizeof(ThreadVars)); | |
c6e090f7 PR |
3278 | memset(&ssn, 0, sizeof(TcpSession)); |
3279 | ||
1071a532 | 3280 | p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); |
262a7300 VJ |
3281 | if (p == NULL) { |
3282 | printf("packet setup failed: "); | |
3283 | goto end; | |
3284 | } | |
c6e090f7 | 3285 | |
262a7300 VJ |
3286 | f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); |
3287 | if (f == NULL) { | |
3288 | printf("flow setup failed: "); | |
3289 | goto end; | |
3290 | } | |
3291 | f->protoctx = &ssn; | |
429c6388 | 3292 | f->proto = IPPROTO_TCP; |
262a7300 | 3293 | p->flow = f; |
c6e090f7 | 3294 | |
1071a532 VJ |
3295 | p->flowflags |= FLOW_PKT_TOSERVER; |
3296 | p->flowflags |= FLOW_PKT_ESTABLISHED; | |
1d971b53 | 3297 | p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; |
262a7300 VJ |
3298 | |
3299 | f->alproto = ALPROTO_HTTP; | |
c6e090f7 PR |
3300 | |
3301 | StreamTcpInitConfig(TRUE); | |
c6e090f7 | 3302 | |
71732567 | 3303 | de_ctx = DetectEngineCtxInit(); |
c6e090f7 PR |
3304 | if (de_ctx == NULL) { |
3305 | goto end; | |
3306 | } | |
3307 | de_ctx->mpm_matcher = MPM_B2G; | |
3308 | de_ctx->flags |= DE_QUIET; | |
3309 | ||
3310 | s = de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " | |
3311 | "(msg:\"Test content option\"; " | |
3312 | "sid:1;)"); | |
3313 | if (s == NULL) { | |
3314 | goto end; | |
3315 | } | |
3316 | ||
3317 | SigGroupBuild(de_ctx); | |
3318 | DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); | |
3319 | ||
429c6388 AS |
3320 | SCMutexLock(&f->m); |
3321 | int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); | |
c6e090f7 PR |
3322 | if (r != 0) { |
3323 | printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); | |
cd3e32ce | 3324 | SCMutexUnlock(&f->m); |
c6e090f7 PR |
3325 | goto end; |
3326 | } | |
cd3e32ce | 3327 | SCMutexUnlock(&f->m); |
c6e090f7 | 3328 | |
262a7300 | 3329 | http_state = f->alstate; |
c6e090f7 PR |
3330 | if (http_state == NULL) { |
3331 | printf("no http state: "); | |
3332 | goto end; | |
3333 | } | |
3334 | ||
3335 | /* do detect */ | |
1071a532 | 3336 | SigMatchSignatures(&tv, de_ctx, det_ctx, p); |
c6e090f7 | 3337 | |
1071a532 | 3338 | if (!PacketAlertCheck(p, 1)) { |
c6e090f7 PR |
3339 | printf("sig 1 didn't alert, but it should: "); |
3340 | goto end; | |
3341 | } | |
c6e090f7 | 3342 | result = 1; |
429c6388 AS |
3343 | end: |
3344 | if (alp_tctx != NULL) | |
fdefb65b | 3345 | AppLayerParserThreadCtxFree(alp_tctx); |
c6e090f7 PR |
3346 | if (det_ctx != NULL) |
3347 | DetectEngineThreadCtxDeinit(&tv, det_ctx); | |
3348 | if (de_ctx != NULL) | |
3349 | SigGroupCleanup(de_ctx); | |
3350 | if (de_ctx != NULL) | |
3351 | DetectEngineCtxFree(de_ctx); | |
3352 | ||
3353 | StreamTcpFreeConfig(TRUE); | |
1071a532 VJ |
3354 | |
3355 | UTHFreePackets(&p, 1); | |
262a7300 | 3356 | UTHFreeFlow(f); |
c6e090f7 PR |
3357 | return result; |
3358 | } | |
3359 | ||
3360 | /** \test test if the engine detect the proto on a non standar port | |
3361 | * and match with it */ | |
429c6388 | 3362 | static int AppLayerProtoDetectTest17(void) |
c6e090f7 PR |
3363 | { |
3364 | int result = 0; | |
262a7300 | 3365 | Flow *f = NULL; |
c6e090f7 PR |
3366 | HtpState *http_state = NULL; |
3367 | uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" | |
3368 | "User-Agent: Mozilla/1.0\r\n" | |
3369 | "Cookie: hellocatch\r\n\r\n"; | |
3370 | uint32_t http_buf1_len = sizeof(http_buf1) - 1; | |
3371 | TcpSession ssn; | |
1071a532 | 3372 | Packet *p = NULL; |
c6e090f7 PR |
3373 | Signature *s = NULL; |
3374 | ThreadVars tv; | |
3375 | DetectEngineThreadCtx *det_ctx = NULL; | |
71732567 | 3376 | DetectEngineCtx *de_ctx = NULL; |
8dbf7a0d | 3377 | AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); |
c6e090f7 PR |
3378 | |
3379 | memset(&tv, 0, sizeof(ThreadVars)); | |
c6e090f7 PR |
3380 | memset(&ssn, 0, sizeof(TcpSession)); |
3381 | ||
1071a532 | 3382 | p = UTHBuildPacketSrcDstPorts(http_buf1, http_buf1_len, IPPROTO_TCP, 12345, 88); |
c6e090f7 | 3383 | |
262a7300 VJ |
3384 | f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); |
3385 | if (f == NULL) | |
3386 | goto end; | |
3387 | f->protoctx = &ssn; | |
429c6388 | 3388 | f->proto = IPPROTO_TCP; |
262a7300 | 3389 | p->flow = f; |
1071a532 VJ |
3390 | p->flowflags |= FLOW_PKT_TOSERVER; |
3391 | p->flowflags |= FLOW_PKT_ESTABLISHED; | |
1d971b53 | 3392 | p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; |
262a7300 | 3393 | f->alproto = ALPROTO_HTTP; |
c6e090f7 PR |
3394 | |
3395 | StreamTcpInitConfig(TRUE); | |
c6e090f7 | 3396 | |
71732567 | 3397 | de_ctx = DetectEngineCtxInit(); |
c6e090f7 PR |
3398 | if (de_ctx == NULL) { |
3399 | goto end; | |
3400 | } | |
3401 | de_ctx->mpm_matcher = MPM_B2G; | |
3402 | de_ctx->flags |= DE_QUIET; | |
3403 | ||
3404 | s = de_ctx->sig_list = SigInit(de_ctx, "alert http any !80 -> any any " | |
3405 | "(msg:\"http over non standar port\"; " | |
3406 | "sid:1;)"); | |
3407 | if (s == NULL) { | |
3408 | goto end; | |
3409 | } | |
3410 | ||
3411 | SigGroupBuild(de_ctx); | |
3412 | DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); | |
3413 | ||
cd3e32ce | 3414 | SCMutexLock(&f->m); |
429c6388 | 3415 | int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); |
c6e090f7 PR |
3416 | if (r != 0) { |
3417 | printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); | |
cd3e32ce | 3418 | SCMutexUnlock(&f->m); |
c6e090f7 PR |
3419 | goto end; |
3420 | } | |
cd3e32ce | 3421 | SCMutexUnlock(&f->m); |
c6e090f7 | 3422 | |
262a7300 | 3423 | http_state = f->alstate; |
c6e090f7 PR |
3424 | if (http_state == NULL) { |
3425 | printf("no http state: "); | |
3426 | goto end; | |
3427 | } | |
3428 | ||
3429 | /* do detect */ | |
1071a532 | 3430 | SigMatchSignatures(&tv, de_ctx, det_ctx, p); |
c6e090f7 | 3431 | |
1071a532 | 3432 | if (!PacketAlertCheck(p, 1)) { |
c6e090f7 PR |
3433 | printf("sig 1 didn't alert, but it should: "); |
3434 | goto end; | |
3435 | } | |
3436 | ||
3437 | result = 1; | |
3438 | ||
429c6388 AS |
3439 | end: |
3440 | if (alp_tctx != NULL) | |
fdefb65b | 3441 | AppLayerParserThreadCtxFree(alp_tctx); |
c6e090f7 PR |
3442 | if (det_ctx != NULL) |
3443 | DetectEngineThreadCtxDeinit(&tv, det_ctx); | |
3444 | if (de_ctx != NULL) | |
3445 | SigGroupCleanup(de_ctx); | |
3446 | if (de_ctx != NULL) | |
3447 | DetectEngineCtxFree(de_ctx); | |
3448 | ||
3449 | StreamTcpFreeConfig(TRUE); | |
1071a532 VJ |
3450 | |
3451 | UTHFreePackets(&p, 1); | |
262a7300 | 3452 | UTHFreeFlow(f); |
c6e090f7 PR |
3453 | return result; |
3454 | } | |
3455 | ||
3456 | /** \test test if the engine detect the proto and doesn't match | |
3457 | * because the sig expects another proto (ex ftp)*/ | |
429c6388 | 3458 | static int AppLayerProtoDetectTest18(void) |
c6e090f7 PR |
3459 | { |
3460 | int result = 0; | |
262a7300 | 3461 | Flow *f = NULL; |
c6e090f7 PR |
3462 | HtpState *http_state = NULL; |
3463 | uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" | |
3464 | "User-Agent: Mozilla/1.0\r\n" | |
3465 | "Cookie: hellocatch\r\n\r\n"; | |
3466 | uint32_t http_buf1_len = sizeof(http_buf1) - 1; | |
3467 | TcpSession ssn; | |
1071a532 | 3468 | Packet *p = NULL; |
c6e090f7 PR |
3469 | Signature *s = NULL; |
3470 | ThreadVars tv; | |
3471 | DetectEngineThreadCtx *det_ctx = NULL; | |
71732567 | 3472 | DetectEngineCtx *de_ctx = NULL; |
8dbf7a0d | 3473 | AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); |
c6e090f7 PR |
3474 | |
3475 | memset(&tv, 0, sizeof(ThreadVars)); | |
c6e090f7 PR |
3476 | memset(&ssn, 0, sizeof(TcpSession)); |
3477 | ||
1071a532 | 3478 | p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); |
c6e090f7 | 3479 | |
262a7300 VJ |
3480 | f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); |
3481 | if (f == NULL) | |
3482 | goto end; | |
3483 | f->protoctx = &ssn; | |
429c6388 | 3484 | f->proto = IPPROTO_TCP; |
262a7300 | 3485 | p->flow = f; |
1071a532 VJ |
3486 | p->flowflags |= FLOW_PKT_TOSERVER; |
3487 | p->flowflags |= FLOW_PKT_ESTABLISHED; | |
1d971b53 | 3488 | p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; |
262a7300 | 3489 | f->alproto = ALPROTO_HTTP; |
c6e090f7 PR |
3490 | |
3491 | StreamTcpInitConfig(TRUE); | |
c6e090f7 | 3492 | |
71732567 | 3493 | de_ctx = DetectEngineCtxInit(); |
c6e090f7 PR |
3494 | if (de_ctx == NULL) { |
3495 | goto end; | |
3496 | } | |
3497 | de_ctx->mpm_matcher = MPM_B2G; | |
3498 | de_ctx->flags |= DE_QUIET; | |
3499 | ||
3500 | s = de_ctx->sig_list = SigInit(de_ctx, "alert ftp any any -> any any " | |
3501 | "(msg:\"Test content option\"; " | |
3502 | "sid:1;)"); | |
3503 | if (s == NULL) { | |
3504 | goto end; | |
3505 | } | |
3506 | ||
3507 | SigGroupBuild(de_ctx); | |
3508 | DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); | |
3509 | ||
cd3e32ce | 3510 | SCMutexLock(&f->m); |
429c6388 | 3511 | int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); |
c6e090f7 PR |
3512 | if (r != 0) { |
3513 | printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); | |
cd3e32ce | 3514 | SCMutexUnlock(&f->m); |
c6e090f7 PR |
3515 | goto end; |
3516 | } | |
cd3e32ce | 3517 | SCMutexUnlock(&f->m); |
c6e090f7 | 3518 | |
262a7300 | 3519 | http_state = f->alstate; |
c6e090f7 PR |
3520 | if (http_state == NULL) { |
3521 | printf("no http state: "); | |
3522 | goto end; | |
3523 | } | |
3524 | ||
3525 | /* do detect */ | |
1071a532 | 3526 | SigMatchSignatures(&tv, de_ctx, det_ctx, p); |
c6e090f7 | 3527 | |
1071a532 | 3528 | if (PacketAlertCheck(p, 1)) { |
c6e090f7 PR |
3529 | printf("sig 1 alerted, but it should not (it's not ftp): "); |
3530 | goto end; | |
3531 | } | |
3532 | ||
3533 | result = 1; | |
429c6388 AS |
3534 | end: |
3535 | if (alp_tctx != NULL) | |
fdefb65b | 3536 | AppLayerParserThreadCtxFree(alp_tctx); |
c6e090f7 PR |
3537 | if (det_ctx != NULL) |
3538 | DetectEngineThreadCtxDeinit(&tv, det_ctx); | |
3539 | if (de_ctx != NULL) | |
3540 | SigGroupCleanup(de_ctx); | |
3541 | if (de_ctx != NULL) | |
3542 | DetectEngineCtxFree(de_ctx); | |
3543 | ||
3544 | StreamTcpFreeConfig(TRUE); | |
1071a532 VJ |
3545 | |
3546 | UTHFreePackets(&p, 1); | |
262a7300 | 3547 | UTHFreeFlow(f); |
c6e090f7 PR |
3548 | return result; |
3549 | } | |
3550 | ||
3551 | /** \test test if the engine detect the proto and doesn't match | |
3552 | * because the packet has another proto (ex ftp) */ | |
429c6388 | 3553 | static int AppLayerProtoDetectTest19(void) |
c6e090f7 PR |
3554 | { |
3555 | int result = 0; | |
262a7300 | 3556 | Flow *f = NULL; |
c6e090f7 PR |
3557 | uint8_t http_buf1[] = "MPUT one\r\n"; |
3558 | uint32_t http_buf1_len = sizeof(http_buf1) - 1; | |
3559 | TcpSession ssn; | |
1071a532 | 3560 | Packet *p = NULL; |
c6e090f7 PR |
3561 | Signature *s = NULL; |
3562 | ThreadVars tv; | |
3563 | DetectEngineThreadCtx *det_ctx = NULL; | |
71732567 | 3564 | DetectEngineCtx *de_ctx = NULL; |
8dbf7a0d | 3565 | AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); |
c6e090f7 PR |
3566 | |
3567 | memset(&tv, 0, sizeof(ThreadVars)); | |
c6e090f7 PR |
3568 | memset(&ssn, 0, sizeof(TcpSession)); |
3569 | ||
1071a532 | 3570 | p = UTHBuildPacketSrcDstPorts(http_buf1, http_buf1_len, IPPROTO_TCP, 12345, 88); |
c6e090f7 | 3571 | |
262a7300 VJ |
3572 | f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); |
3573 | if (f == NULL) | |
3574 | goto end; | |
3575 | f->protoctx = &ssn; | |
429c6388 | 3576 | f->proto = IPPROTO_TCP; |
262a7300 | 3577 | p->flow = f; |
1071a532 VJ |
3578 | p->flowflags |= FLOW_PKT_TOSERVER; |
3579 | p->flowflags |= FLOW_PKT_ESTABLISHED; | |
1d971b53 | 3580 | p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; |
262a7300 | 3581 | f->alproto = ALPROTO_FTP; |
c6e090f7 PR |
3582 | |
3583 | StreamTcpInitConfig(TRUE); | |
c6e090f7 | 3584 | |
71732567 | 3585 | de_ctx = DetectEngineCtxInit(); |
c6e090f7 PR |
3586 | if (de_ctx == NULL) { |
3587 | goto end; | |
3588 | } | |
3589 | de_ctx->mpm_matcher = MPM_B2G; | |
3590 | de_ctx->flags |= DE_QUIET; | |
3591 | ||
3592 | s = de_ctx->sig_list = SigInit(de_ctx, "alert http any !80 -> any any " | |
3593 | "(msg:\"http over non standar port\"; " | |
3594 | "sid:1;)"); | |
3595 | if (s == NULL) { | |
3596 | goto end; | |
3597 | } | |
3598 | ||
3599 | SigGroupBuild(de_ctx); | |
3600 | DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); | |
3601 | ||
cd3e32ce | 3602 | SCMutexLock(&f->m); |
429c6388 | 3603 | int r = AppLayerParserParse(alp_tctx, f, ALPROTO_FTP, STREAM_TOSERVER, http_buf1, http_buf1_len); |
c6e090f7 PR |
3604 | if (r != 0) { |
3605 | printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); | |
cd3e32ce | 3606 | SCMutexUnlock(&f->m); |
c6e090f7 PR |
3607 | goto end; |
3608 | } | |
cd3e32ce | 3609 | SCMutexUnlock(&f->m); |
c6e090f7 | 3610 | |
c6e090f7 | 3611 | /* do detect */ |
1071a532 | 3612 | SigMatchSignatures(&tv, de_ctx, det_ctx, p); |
c6e090f7 | 3613 | |
1071a532 | 3614 | if (PacketAlertCheck(p, 1)) { |
c6e090f7 PR |
3615 | printf("sig 1 alerted, but it should not (it's ftp): "); |
3616 | goto end; | |
3617 | } | |
3618 | ||
3619 | result = 1; | |
3620 | ||
429c6388 AS |
3621 | end: |
3622 | if (alp_tctx != NULL) | |
fdefb65b | 3623 | AppLayerParserThreadCtxFree(alp_tctx); |
c6e090f7 PR |
3624 | if (det_ctx != NULL) |
3625 | DetectEngineThreadCtxDeinit(&tv, det_ctx); | |
3626 | if (de_ctx != NULL) | |
3627 | SigGroupCleanup(de_ctx); | |
3628 | if (de_ctx != NULL) | |
3629 | DetectEngineCtxFree(de_ctx); | |
3630 | ||
3631 | StreamTcpFreeConfig(TRUE); | |
1071a532 | 3632 | UTHFreePackets(&p, 1); |
262a7300 | 3633 | UTHFreeFlow(f); |
c6e090f7 PR |
3634 | return result; |
3635 | } | |
3636 | ||
3637 | /** \test test if the engine detect the proto and match with it | |
3638 | * and also against a content option */ | |
429c6388 | 3639 | static int AppLayerProtoDetectTest20(void) |
c6e090f7 PR |
3640 | { |
3641 | int result = 0; | |
262a7300 | 3642 | Flow *f = NULL; |
c6e090f7 PR |
3643 | uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" |
3644 | "User-Agent: Mozilla/1.0\r\n" | |
3645 | "Cookie: hellocatch\r\n\r\n"; | |
3646 | uint32_t http_buf1_len = sizeof(http_buf1) - 1; | |
3647 | TcpSession ssn; | |
1071a532 | 3648 | Packet *p = NULL; |
c6e090f7 PR |
3649 | Signature *s = NULL; |
3650 | ThreadVars tv; | |
3651 | DetectEngineThreadCtx *det_ctx = NULL; | |
71732567 | 3652 | DetectEngineCtx *de_ctx = NULL; |
8dbf7a0d | 3653 | AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); |
c6e090f7 PR |
3654 | |
3655 | memset(&tv, 0, sizeof(ThreadVars)); | |
c6e090f7 PR |
3656 | memset(&ssn, 0, sizeof(TcpSession)); |
3657 | ||
1071a532 | 3658 | p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); |
c6e090f7 | 3659 | |
262a7300 VJ |
3660 | f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); |
3661 | if (f == NULL) | |
3662 | goto end; | |
3663 | f->protoctx = &ssn; | |
3664 | p->flow = f; | |
1071a532 VJ |
3665 | p->flowflags |= FLOW_PKT_TOSERVER; |
3666 | p->flowflags |= FLOW_PKT_ESTABLISHED; | |
1d971b53 | 3667 | p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; |
262a7300 VJ |
3668 | f->alproto = ALPROTO_HTTP; |
3669 | f->proto = IPPROTO_TCP; | |
1071a532 VJ |
3670 | p->flags |= PKT_STREAM_ADD; |
3671 | p->flags |= PKT_STREAM_EOF; | |
c6e090f7 | 3672 | |
71732567 | 3673 | de_ctx = DetectEngineCtxInit(); |
c6e090f7 PR |
3674 | if (de_ctx == NULL) { |
3675 | goto end; | |
3676 | } | |
3677 | ||
3678 | StreamTcpInitConfig(TRUE); | |
c6e090f7 PR |
3679 | |
3680 | StreamMsg *stream_msg = StreamMsgGetFromPool(); | |
3681 | if (stream_msg == NULL) { | |
3682 | printf("no stream_msg: "); | |
3683 | goto end; | |
3684 | } | |
3685 | ||
0ec375d9 VJ |
3686 | memcpy(stream_msg->data, http_buf1, http_buf1_len); |
3687 | stream_msg->data_len = http_buf1_len; | |
c6e090f7 PR |
3688 | |
3689 | ssn.toserver_smsg_head = stream_msg; | |
3690 | ssn.toserver_smsg_tail = stream_msg; | |
3691 | ||
3692 | de_ctx->mpm_matcher = MPM_B2G; | |
3693 | de_ctx->flags |= DE_QUIET; | |
3694 | ||
3695 | s = de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " | |
3696 | "(msg:\"Test content option\"; " | |
3697 | "content:\"one\"; sid:1;)"); | |
3698 | if (s == NULL) { | |
3699 | goto end; | |
3700 | } | |
3701 | ||
3702 | SigGroupBuild(de_ctx); | |
3703 | DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); | |
3704 | ||
cd3e32ce | 3705 | SCMutexLock(&f->m); |
429c6388 | 3706 | int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); |
c6e090f7 PR |
3707 | if (r != 0) { |
3708 | printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); | |
cd3e32ce | 3709 | SCMutexUnlock(&f->m); |
c6e090f7 PR |
3710 | goto end; |
3711 | } | |
cd3e32ce | 3712 | SCMutexUnlock(&f->m); |
c6e090f7 PR |
3713 | |
3714 | /* do detect */ | |
1071a532 | 3715 | SigMatchSignatures(&tv, de_ctx, det_ctx, p); |
c6e090f7 | 3716 | |
1071a532 | 3717 | if (!PacketAlertCheck(p, 1)) { |
c6e090f7 PR |
3718 | printf("sig 1 didn't alert, but it should: "); |
3719 | goto end; | |
3720 | } | |
3721 | ||
3722 | result = 1; | |
3723 | ||
429c6388 AS |
3724 | end: |
3725 | if (alp_tctx != NULL) | |
fdefb65b | 3726 | AppLayerParserThreadCtxFree(alp_tctx); |
c6e090f7 PR |
3727 | if (det_ctx != NULL) |
3728 | DetectEngineThreadCtxDeinit(&tv, det_ctx); | |
3729 | if (de_ctx != NULL) | |
3730 | SigGroupCleanup(de_ctx); | |
3731 | if (de_ctx != NULL) | |
3732 | DetectEngineCtxFree(de_ctx); | |
3733 | ||
3734 | StreamTcpFreeConfig(TRUE); | |
1071a532 | 3735 | UTHFreePackets(&p, 1); |
262a7300 | 3736 | UTHFreeFlow(f); |
c6e090f7 PR |
3737 | return result; |
3738 | } | |
3739 | ||
4369816c | 3740 | |
429c6388 AS |
3741 | void AppLayerProtoDetectUnittestsRegister(void) |
3742 | { | |
3743 | SCEnter(); | |
3744 | ||
3745 | UtRegisterTest("AppLayerProtoDetectTest01", AppLayerProtoDetectTest01, 1); | |
3746 | UtRegisterTest("AppLayerProtoDetectTest02", AppLayerProtoDetectTest02, 1); | |
3747 | UtRegisterTest("AppLayerProtoDetectTest03", AppLayerProtoDetectTest03, 1); | |
3748 | UtRegisterTest("AppLayerProtoDetectTest04", AppLayerProtoDetectTest04, 1); | |
3749 | UtRegisterTest("AppLayerProtoDetectTest05", AppLayerProtoDetectTest05, 1); | |
3750 | UtRegisterTest("AppLayerProtoDetectTest06", AppLayerProtoDetectTest06, 1); | |
3751 | UtRegisterTest("AppLayerProtoDetectTest07", AppLayerProtoDetectTest07, 1); | |
3752 | UtRegisterTest("AppLayerProtoDetectTest08", AppLayerProtoDetectTest08, 1); | |
3753 | UtRegisterTest("AppLayerProtoDetectTest09", AppLayerProtoDetectTest09, 1); | |
3754 | UtRegisterTest("AppLayerProtoDetectTest10", AppLayerProtoDetectTest10, 1); | |
3755 | UtRegisterTest("AppLayerProtoDetectTest11", AppLayerProtoDetectTest11, 1); | |
3756 | UtRegisterTest("AppLayerProtoDetectTest12", AppLayerProtoDetectTest12, 1); | |
3757 | UtRegisterTest("AppLayerProtoDetectTest13", AppLayerProtoDetectTest13, 1); | |
3758 | UtRegisterTest("AppLayerProtoDetectTest14", AppLayerProtoDetectTest14, 1); | |
3759 | UtRegisterTest("AppLayerProtoDetectTest15", AppLayerProtoDetectTest15, 1); | |
3760 | UtRegisterTest("AppLayerProtoDetectTest16", AppLayerProtoDetectTest16, 1); | |
3761 | UtRegisterTest("AppLayerProtoDetectTest17", AppLayerProtoDetectTest17, 1); | |
3762 | UtRegisterTest("AppLayerProtoDetectTest18", AppLayerProtoDetectTest18, 1); | |
3763 | UtRegisterTest("AppLayerProtoDetectTest19", AppLayerProtoDetectTest19, 1); | |
3764 | UtRegisterTest("AppLayerProtoDetectTest20", AppLayerProtoDetectTest20, 1); | |
3765 | ||
3766 | SCReturn; | |
c43319c3 | 3767 | } |
429c6388 AS |
3768 | |
3769 | #endif /* UNITTESTS */ |