suricata
detect-pktvar.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2020 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 Victor Julien <victor@inliniac.net>
22 *
23 * Implements the pktvar keyword
24 */
25
26#include "suricata-common.h"
27#include "decode.h"
28
29#include "detect.h"
30#include "detect-parse.h"
31
32#include "threads.h"
33#include "pkt-var.h"
34#include "detect-pktvar.h"
35#include "detect-content.h"
36#include "util-spm.h"
37#include "util-debug.h"
38#include "util-var-name.h"
39
40#define PARSE_REGEX "(.*),(.*)"
41static DetectParseRegex parse_regex;
42
43static int DetectPktvarMatch (DetectEngineThreadCtx *, Packet *,
44 const Signature *, const SigMatchCtx *);
45static int DetectPktvarSetup (DetectEngineCtx *, Signature *, const char *);
46static void DetectPktvarFree(DetectEngineCtx *, void *data);
47
49{
51 sigmatch_table[DETECT_PKTVAR].Match = DetectPktvarMatch;
52 sigmatch_table[DETECT_PKTVAR].Setup = DetectPktvarSetup;
53 sigmatch_table[DETECT_PKTVAR].Free = DetectPktvarFree;
54
56}
57
58/*
59 * returns 0: no match
60 * 1: match
61 * -1: error
62 */
63
64static int DetectPktvarMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
65 const Signature *s, const SigMatchCtx *ctx)
66{
67 int ret = 0;
68 const DetectPktvarData *pd = (const DetectPktvarData *)ctx;
69
70 PktVar *pv = PktVarGet(p, pd->id);
71 if (pv != NULL) {
72 uint8_t *ptr = SpmSearch(pv->value, pv->value_len, pd->content, pd->content_len);
73 if (ptr != NULL)
74 ret = 1;
75 }
76
77 return ret;
78}
79
80static void DetectPktvarFree(DetectEngineCtx *de_ctx, void *ptr)
81{
82 DetectPktvarData *data = ptr;
83 if (data != NULL) {
85 SCFree(data->content);
86 SCFree(data);
87 }
88}
89
90static int DetectPktvarSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
91{
92 char *varname = NULL, *varcontent = NULL;
93 int res = 0;
94 size_t pcre2_len;
95 uint8_t *content = NULL;
96 uint16_t len = 0;
97
98 pcre2_match_data *match = NULL;
99 int ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0);
100 if (ret != 3) {
101 SCLogError("\"%s\" is not a valid setting for pktvar.", rawstr);
102 goto error;
103 }
104
105 const char *str_ptr;
106 res = pcre2_substring_get_bynumber(match, 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
107 if (res < 0) {
108 SCLogError("pcre2_substring_get_bynumber failed");
109 goto error;
110 }
111 varname = (char *)str_ptr;
112
113 res = pcre2_substring_get_bynumber(match, 2, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
114 if (res < 0) {
115 pcre2_substring_free((PCRE2_UCHAR8 *)varname);
116 SCLogError("pcre2_substring_get_bynumber failed");
117 goto error;
118 }
119 varcontent = (char *)str_ptr;
120
121 SCLogDebug("varname '%s', varcontent '%s'", varname, varcontent);
122
123 char *parse_content;
124 if (strlen(varcontent) >= 2 && varcontent[0] == '"' &&
125 varcontent[strlen(varcontent) - 1] == '"')
126 {
127 parse_content = varcontent + 1;
128 varcontent[strlen(varcontent) - 1] = '\0';
129 } else {
130 parse_content = varcontent;
131 }
132
133 ret = DetectContentDataParse("pktvar", parse_content, &content, &len);
134 if (ret == -1 || content == NULL) {
135 pcre2_substring_free((PCRE2_UCHAR8 *)varname);
136 pcre2_substring_free((PCRE2_UCHAR8 *)varcontent);
137 goto error;
138 }
139 pcre2_substring_free((PCRE2_UCHAR8 *)varcontent);
140
142 if (unlikely(cd == NULL)) {
143 pcre2_substring_free((PCRE2_UCHAR8 *)varname);
144 SCFree(content);
145 goto error;
146 }
147
148 cd->content = content;
149 cd->content_len = len;
151 pcre2_substring_free((PCRE2_UCHAR8 *)varname);
152
153 /* Okay so far so good, lets get this into a SigMatch
154 * and put it in the Signature. */
157 goto error;
158 }
159
160 pcre2_match_data_free(match);
161 return 0;
162
163error:
164 if (match) {
165 pcre2_match_data_free(match);
166 }
167 return -1;
168}
uint8_t len
int DetectContentDataParse(const char *keyword, const char *contentstr, uint8_t **pstr, uint16_t *plen)
Parse a content string, ie "abc|DE|fgh".
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
#define PARSE_REGEX
void DetectPktvarRegister(void)
@ DETECT_SM_LIST_MATCH
Definition detect.h:117
DetectEngineCtx * de_ctx
struct Thresholds ctx
PktVar * PktVarGet(Packet *p, uint32_t id)
Definition pkt-var.c:40
main detection engine ctx
Definition detect.h:932
uint16_t value_len
Definition decode.h:317
uint8_t * value
Definition decode.h:319
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
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
#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
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define unlikely(expr)
#define SpmSearch(text, textlen, needle, needlelen)
Definition util-spm.h:99
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
@ VAR_TYPE_PKT_VAR
Definition util-var.h:33