suricata
detect-l3proto.c
Go to the documentation of this file.
1/* Copyright (C) 2012-2013 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Eric Leblond <eric@regit.org>
22 *
23 *
24 * Implements the l3_proto keyword
25 */
26
27#include "suricata-common.h"
28#include "decode.h"
29#include "detect.h"
30
31#include "detect-ipproto.h"
32
33#include "detect-parse.h"
34#include "detect-engine.h"
35#include "detect-engine-mpm.h"
36#include "detect-engine-build.h"
37
40
41#include "detect-l3proto.h"
42
43#include "util-byte.h"
44#include "util-unittest.h"
46
47#include "util-debug.h"
48
49static int DetectL3ProtoSetup(DetectEngineCtx *, Signature *, const char *);
50#ifdef UNITTESTS
51static void DetectL3protoRegisterTests(void);
52#endif
53
55{
58 sigmatch_table[DETECT_L3PROTO].Setup = DetectL3ProtoSetup;
60#ifdef UNITTESTS
61 sigmatch_table[DETECT_L3PROTO].RegisterTests = DetectL3protoRegisterTests;
62#endif
63}
64/**
65 * \internal
66 * \brief Setup l3_proto keyword.
67 *
68 * \param de_ctx Detection engine context
69 * \param s Signature
70 * \param optstr Options string
71 *
72 * \return Non-zero on error
73 */
74static int DetectL3ProtoSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr)
75{
76 const char *str = optstr;
77
78 /* reset possible any value */
79 if (s->proto.flags & DETECT_PROTO_ANY) {
80 s->proto.flags &= ~DETECT_PROTO_ANY;
81 }
82
83 /* authorized value, ip, any, ip4, ipv4, ip6, ipv6 */
84 if (strcasecmp(str,"ipv4") == 0 ||
85 strcasecmp(str,"ip4") == 0 ) {
86 if (s->proto.flags & DETECT_PROTO_IPV6) {
87 SCLogError("Conflicting l3 proto specified");
88 goto error;
89 }
91 SCLogDebug("IPv4 protocol detected");
92 } else if (strcasecmp(str,"ipv6") == 0 ||
93 strcasecmp(str,"ip6") == 0 ) {
94 if (s->proto.flags & DETECT_PROTO_IPV6) {
95 SCLogError("Conflicting l3 proto specified");
96 goto error;
97 }
99 SCLogDebug("IPv6 protocol detected");
100 } else {
101 SCLogError("Invalid l3 proto: \"%s\"", str);
102 goto error;
103 }
104
105 return 0;
106error:
107 return -1;
108}
109
110#ifdef UNITTESTS
111#include "detect-engine-alert.h"
112
113/**
114 * \test DetectL3protoTestSig01 is a test for checking the working of ttl keyword
115 * by setting up the signature and later testing its working by matching
116 * the received packet against the sig.
117 */
118
119static int DetectL3protoTestSig1(void)
120{
121
123 FAIL_IF_NULL(p);
124 Signature *s = NULL;
125 ThreadVars th_v;
126 DetectEngineThreadCtx *det_ctx;
127 IPV4Hdr ip4h;
128
129 memset(&th_v, 0, sizeof(th_v));
130
131 p->src.family = AF_INET;
132 p->dst.family = AF_INET;
133 p->proto = IPPROTO_TCP;
134 UTHSetIPV4Hdr(p, &ip4h);
135
138
140
142 de_ctx, "alert ip any any -> any any (msg:\"l3proto ipv4\"; l3_proto:ipv4; sid:1;)");
143 FAIL_IF_NULL(s);
144
146 de_ctx, "alert ip any any -> any any (msg:\"l3proto ipv6\"; l3_proto:ipv6; sid:2;)");
147 FAIL_IF_NULL(s);
148
150 de_ctx, "alert ip any any -> any any (msg:\"l3proto ip4\"; l3_proto:ip4; sid:3;)");
151 FAIL_IF_NULL(s);
152
154 de_ctx, "alert ip any any -> any any (msg:\"l3proto ip6\"; l3_proto:ip6; sid:4;)");
155 FAIL_IF_NULL(s);
156
158 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
159
160 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
165
166 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
168
169 SCFree(p);
170
171 PASS;
172}
173
174/**
175 * \test DetectL3protoTestSig02 is a test for checking the working of l3proto keyword
176 * by setting up the signature and later testing its working by matching
177 * the received IPv6 packet against the sig.
178 */
179
180static int DetectL3protoTestSig2(void)
181{
182
184 FAIL_IF_NULL(p);
185 Signature *s = NULL;
186 ThreadVars th_v;
187 DetectEngineThreadCtx *det_ctx;
188 IPV6Hdr ip6h;
189
190 memset(&th_v, 0, sizeof(th_v));
191
192 p->src.family = AF_INET6;
193 p->dst.family = AF_INET6;
194 p->proto = IPPROTO_TCP;
195 UTHSetIPV6Hdr(p, &ip6h);
196
199
201
203 de_ctx, "alert ip any any -> any any (msg:\"l3proto ipv4\"; l3_proto:ipv4; sid:1;)");
204 FAIL_IF_NULL(s);
205
207 de_ctx, "alert ip any any -> any any (msg:\"l3proto ipv6\"; l3_proto:ipv6; sid:2;)");
208 FAIL_IF_NULL(s);
209
211 de_ctx, "alert ip any any -> any any (msg:\"l3proto ip4\"; l3_proto:ip4; sid:3;)");
212 FAIL_IF_NULL(s);
213
215 de_ctx, "alert ip any any -> any any (msg:\"l3proto ip6\"; l3_proto:ip6; sid:4;)");
216 FAIL_IF_NULL(s);
217
219 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
220
221 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
226
227 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
229
230 SCFree(p);
231
232 PASS;
233}
234
235/**
236 * \test DetectL3protoTestSig03 is a test for checking the working of l3proto keyword
237 * in conjunction with ip_proto keyword.
238 */
239
240static int DetectL3protoTestSig3(void)
241{
242
244 FAIL_IF_NULL(p);
245 Signature *s = NULL;
246 ThreadVars th_v;
247 DetectEngineThreadCtx *det_ctx;
248 IPV6Hdr ip6h;
249
250 memset(&th_v, 0, sizeof(th_v));
251
252 p->src.family = AF_INET6;
253 p->dst.family = AF_INET6;
254 p->proto = IPPROTO_TCP;
255 UTHSetIPV6Hdr(p, &ip6h);
256
259
261
262 s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (msg:\"l3proto ipv4 and "
263 "ip_proto udp\"; l3_proto:ipv4; ip_proto:17; sid:1;)");
264 FAIL_IF_NULL(s);
265
266 s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (msg:\"l3proto ipv6 and "
267 "ip_proto udp\"; l3_proto:ipv6; ip_proto:17; sid:2;)");
268 FAIL_IF_NULL(s);
269
270 s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (msg:\"l3proto ip4 and ip_proto "
271 "tcp\"; l3_proto:ipv4; ip_proto:6; sid:3;)");
272 FAIL_IF_NULL(s);
273
274 s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (msg:\"l3proto ipv6 and "
275 "ip_proto tcp\"; l3_proto:ipv6; ip_proto:6; sid:4;)");
276 FAIL_IF_NULL(s);
277
279 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
280
281 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
286
287 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
289
290 SCFree(p);
291
292 PASS;
293}
294
295/**
296 * \brief this function registers unit tests for DetectL3proto
297 */
298static void DetectL3protoRegisterTests(void)
299{
300 UtRegisterTest("DetectL3protoTestSig1", DetectL3protoTestSig1);
301 UtRegisterTest("DetectL3protoTestSig2", DetectL3protoTestSig2);
302 UtRegisterTest("DetectL3protoTestSig3", DetectL3protoTestSig3);
303}
304#endif /* UNITTESTS */
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
#define DETECT_PROTO_IPV6
#define DETECT_PROTO_IPV4
#define DETECT_PROTO_ANY
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
void DetectL3ProtoRegister(void)
Registration function for ip_proto keyword.
SigTableElmt * sigmatch_table
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition detect.c:2420
#define DE_QUIET
Definition detect.h:330
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition decode.c:258
char family
Definition decode.h:113
main detection engine ctx
Definition detect.h:932
uint8_t flags
Definition detect.h:934
Address src
Definition decode.h:505
Address dst
Definition decode.h:506
uint8_t proto
Definition decode.h:523
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
void(* RegisterTests)(void)
Definition detect.h:1448
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition detect.h:1421
const char * name
Definition detect.h:1459
Signature container.
Definition detect.h:668
DetectProto proto
Definition detect.h:687
Per thread variable structure.
Definition threadvars.h:58
#define str(s)
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCFree(p)
Definition util-mem.h:61
void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h)
void UTHSetIPV6Hdr(Packet *p, IPV6Hdr *ip6h)