suricata
detect-pktvar.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 
39 #define PARSE_REGEX "(.*),(.*)"
40 static pcre *parse_regex;
41 static pcre_extra *parse_regex_study;
42 
43 static int DetectPktvarMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *,
44  const Signature *, const SigMatchCtx *);
45 static int DetectPktvarSetup (DetectEngineCtx *, Signature *, const char *);
46 
48 {
49  sigmatch_table[DETECT_PKTVAR].name = "pktvar";
50  sigmatch_table[DETECT_PKTVAR].Match = DetectPktvarMatch;
51  sigmatch_table[DETECT_PKTVAR].Setup = DetectPktvarSetup;
54 
55  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
56 }
57 
58 /*
59  * returns 0: no match
60  * 1: match
61  * -1: error
62  */
63 
64 static int DetectPktvarMatch (ThreadVars *t, 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 
80 static int DetectPktvarSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
81 {
82  char *varname = NULL, *varcontent = NULL;
83 #define MAX_SUBSTRINGS 30
84  int ret = 0, res = 0;
85  int ov[MAX_SUBSTRINGS];
86  uint8_t *content = NULL;
87  uint16_t len = 0;
88 
89  ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
90  if (ret != 3) {
91  SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for pktvar.", rawstr);
92  return -1;
93  }
94 
95  const char *str_ptr;
96  res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr);
97  if (res < 0) {
98  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
99  return -1;
100  }
101  varname = (char *)str_ptr;
102 
103  res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr);
104  if (res < 0) {
105  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
106  return -1;
107  }
108  varcontent = (char *)str_ptr;
109 
110  SCLogDebug("varname '%s', varcontent '%s'", varname, varcontent);
111 
112  char *parse_content;
113  if (strlen(varcontent) >= 2 && varcontent[0] == '"' &&
114  varcontent[strlen(varcontent) - 1] == '"')
115  {
116  parse_content = varcontent + 1;
117  varcontent[strlen(varcontent) - 1] = '\0';
118  } else {
119  parse_content = varcontent;
120  }
121 
122  ret = DetectContentDataParse("pktvar", parse_content, &content, &len);
123  if (ret == -1 || content == NULL) {
124  pcre_free(varname);
125  pcre_free(varcontent);
126  return -1;
127  }
128 
129  DetectPktvarData *cd = SCCalloc(1, sizeof(DetectPktvarData));
130  if (unlikely(cd == NULL)) {
131  pcre_free(varname);
132  pcre_free(varcontent);
133  SCFree(content);
134  return -1;
135  }
136 
137  cd->content = content;
138  cd->content_len = len;
139  cd->id = VarNameStoreSetupAdd(varname, VAR_TYPE_PKT_VAR);
140  pcre_free(varname);
141  pcre_free(varcontent);
142 
143  /* Okay so far so good, lets get this into a SigMatch
144  * and put it in the Signature. */
145  SigMatch *sm = SigMatchAlloc();
146  if (unlikely(sm == NULL)) {
147  SCFree(cd->content);
148  SCFree(cd);
149  return -1;
150  }
151  sm->type = DETECT_PKTVAR;
152  sm->ctx = (SigMatchCtx *)cd;
153 
155  return 0;
156 }
157 
158 
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1431
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1170
#define SCLogDebug(...)
Definition: util-debug.h:335
#define unlikely(expr)
Definition: util-optimize.h:35
int DetectContentDataParse(const char *keyword, const char *contentstr, uint8_t **pstr, uint16_t *plen)
Parse a content string, ie "abc|DE|fgh".
const char * name
Definition: detect.h:1184
Signature container.
Definition: detect.h:514
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:318
main detection engine ctx
Definition: detect.h:743
#define SCCalloc(nm, a)
Definition: util-mem.h:197
uint16_t value_len
Definition: decode.h:314
void(* Free)(void *)
Definition: detect.h:1175
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
#define MAX_SUBSTRINGS
uint8_t type
Definition: detect.h:324
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:288
#define PARSE_REGEX
Definition: detect-pktvar.c:39
SigMatchCtx * ctx
Definition: detect.h:326
#define SCFree(a)
Definition: util-mem.h:228
PoolThreadReserved res
uint8_t * value
Definition: decode.h:316
int(* Match)(ThreadVars *, DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1153
uint32_t VarNameStoreSetupAdd(const char *name, const enum VarTypes type)
add to staging or return existing id if already in there
void DetectPktvarRegister(void)
Definition: detect-pktvar.c:47
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
PktVar * PktVarGet(Packet *p, uint32_t id)
Definition: pkt-var.c:40
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
#define SpmSearch(text, textlen, needle, needlelen)
Definition: util-spm.h:101
void(* RegisterTests)(void)
Definition: detect.h:1176
a single match condition for a signature
Definition: detect.h:323