suricata
detect-snmp-pdu_type.c
Go to the documentation of this file.
1 /* Copyright (C) 2015-2019 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 Pierre Chifflier <chifflier@wzdftpd.net>
22  */
23 
24 #include "suricata-common.h"
25 #include "conf.h"
26 #include "detect.h"
27 #include "detect-parse.h"
28 #include "detect-engine.h"
30 #include "detect-snmp-pdu_type.h"
31 #include "app-layer-parser.h"
32 
33 #include "rust-snmp-snmp-gen.h"
34 #include "rust-snmp-detect-gen.h"
35 
36 /**
37  * [snmp.pdu_type]:<type>;
38  */
39 #define PARSE_REGEX "^\\s*([0-9]+)\\s*$"
40 static pcre *parse_regex;
41 static pcre_extra *parse_regex_study;
42 
43 typedef struct DetectSNMPPduTypeData_ {
44  uint32_t pdu_type;
46 
47 static DetectSNMPPduTypeData *DetectSNMPPduTypeParse (const char *);
48 static int DetectSNMPPduTypeSetup (DetectEngineCtx *, Signature *s, const char *str);
49 static void DetectSNMPPduTypeFree(void *);
50 #ifdef UNITTESTS
51 static void DetectSNMPPduTypeRegisterTests(void);
52 #endif
53 static int g_snmp_pdu_type_buffer_id = 0;
54 
55 static int DetectEngineInspectSNMPRequestGeneric(ThreadVars *tv,
56  DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
57  const Signature *s, const SigMatchData *smd,
58  Flow *f, uint8_t flags, void *alstate,
59  void *txv, uint64_t tx_id);
60 
61 static int DetectSNMPPduTypeMatch (DetectEngineThreadCtx *, Flow *,
62  uint8_t, void *, void *, const Signature *,
63  const SigMatchCtx *);
64 
66 {
67  sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].name = "snmp.pdu_type";
68  sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].desc = "match SNMP Pdu type";
69  sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].url = DOC_URL DOC_VERSION "/rules/snmp-keywords.html#snmp.pdu_type";
71  sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].AppLayerTxMatch = DetectSNMPPduTypeMatch;
72  sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].Setup = DetectSNMPPduTypeSetup;
73  sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].Free = DetectSNMPPduTypeFree;
74 #ifdef UNITTESTS
75  sigmatch_table[DETECT_AL_SNMP_PDU_TYPE].RegisterTests = DetectSNMPPduTypeRegisterTests;
76 #endif
78 
79  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
80 
83  DetectEngineInspectSNMPRequestGeneric);
84 
87  DetectEngineInspectSNMPRequestGeneric);
88 
89  g_snmp_pdu_type_buffer_id = DetectBufferTypeGetByName("snmp.pdu_type");
90 }
91 
92 static int DetectEngineInspectSNMPRequestGeneric(ThreadVars *tv,
93  DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
94  const Signature *s, const SigMatchData *smd,
95  Flow *f, uint8_t flags, void *alstate,
96  void *txv, uint64_t tx_id)
97 {
98  return DetectEngineInspectGenericList(tv, de_ctx, det_ctx, s, smd,
99  f, flags, alstate, txv, tx_id);
100 }
101 
102 /**
103  * \internal
104  * \brief Function to match pdu_type of a TX
105  *
106  * \param t Pointer to thread vars.
107  * \param det_ctx Pointer to the pattern matcher thread.
108  * \param f Pointer to the current flow.
109  * \param flags Flags.
110  * \param state App layer state.
111  * \param s Pointer to the Signature.
112  * \param m Pointer to the sigmatch that we will cast into
113  * DetectSNMPPduTypeData.
114  *
115  * \retval 0 no match.
116  * \retval 1 match.
117  */
118 static int DetectSNMPPduTypeMatch (DetectEngineThreadCtx *det_ctx,
119  Flow *f, uint8_t flags, void *state,
120  void *txv, const Signature *s,
121  const SigMatchCtx *ctx)
122 {
123  SCEnter();
124 
125  const DetectSNMPPduTypeData *dd = (const DetectSNMPPduTypeData *)ctx;
126  uint32_t pdu_type;
127  rs_snmp_tx_get_pdu_type(txv, &pdu_type);
128  SCLogDebug("pdu_type %u ref_pdu_type %d",
129  pdu_type, dd->pdu_type);
130  if (pdu_type == dd->pdu_type)
131  SCReturnInt(1);
132  SCReturnInt(0);
133 }
134 
135 /**
136  * \internal
137  * \brief Function to parse options passed via snmp.pdu_type keywords.
138  *
139  * \param rawstr Pointer to the user provided options.
140  *
141  * \retval dd pointer to DetectSNMPPduTypeData on success.
142  * \retval NULL on failure.
143  */
144 static DetectSNMPPduTypeData *DetectSNMPPduTypeParse (const char *rawstr)
145 {
146  DetectSNMPPduTypeData *dd = NULL;
147 #define MAX_SUBSTRINGS 30
148  int ret = 0, res = 0;
149  int ov[MAX_SUBSTRINGS];
150  char value1[20] = "";
151  char *endptr = NULL;
152 
153  ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0,
154  0, ov, MAX_SUBSTRINGS);
155  if (ret != 2) {
156  SCLogError(SC_ERR_PCRE_MATCH, "Parse error %s", rawstr);
157  goto error;
158  }
159 
160  res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, value1,
161  sizeof(value1));
162  if (res < 0) {
163  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
164  goto error;
165  }
166 
167  dd = SCCalloc(1, sizeof(DetectSNMPPduTypeData));
168  if (unlikely(dd == NULL))
169  goto error;
170 
171  /* set the value */
172  dd->pdu_type = strtoul(value1, &endptr, 10);
173  if (endptr == NULL || *endptr != '\0') {
174  SCLogError(SC_ERR_INVALID_SIGNATURE, "invalid character as arg "
175  "to snmp.pdu_type keyword");
176  goto error;
177  }
178 
179  return dd;
180 
181 error:
182  if (dd)
183  SCFree(dd);
184  return NULL;
185 }
186 
187 /**
188  * \brief Function to add the parsed snmp pdu_type field into the current signature.
189  *
190  * \param de_ctx Pointer to the Detection Engine Context.
191  * \param s Pointer to the Current Signature.
192  * \param rawstr Pointer to the user provided flags options.
193  * \param type Defines if this is notBefore or notAfter.
194  *
195  * \retval 0 on Success.
196  * \retval -1 on Failure.
197  */
198 static int DetectSNMPPduTypeSetup (DetectEngineCtx *de_ctx, Signature *s,
199  const char *rawstr)
200 {
201  DetectSNMPPduTypeData *dd = NULL;
202  SigMatch *sm = NULL;
203 
205  return -1;
206 
207  dd = DetectSNMPPduTypeParse(rawstr);
208  if (dd == NULL) {
209  SCLogError(SC_ERR_INVALID_ARGUMENT,"Parsing \'%s\' failed", rawstr);
210  goto error;
211  }
212 
213  /* okay so far so good, lets get this into a SigMatch
214  * and put it in the Signature. */
215  sm = SigMatchAlloc();
216  if (sm == NULL)
217  goto error;
218 
220  sm->ctx = (void *)dd;
221 
222  SCLogDebug("snmp.pdu_type %d", dd->pdu_type);
223  SigMatchAppendSMToList(s, sm, g_snmp_pdu_type_buffer_id);
224  return 0;
225 
226 error:
227  DetectSNMPPduTypeFree(dd);
228  return -1;
229 }
230 
231 /**
232  * \internal
233  * \brief Function to free memory associated with DetectSNMPPduTypeData.
234  *
235  * \param de_ptr Pointer to DetectSNMPPduTypeData.
236  */
237 static void DetectSNMPPduTypeFree(void *ptr)
238 {
239  SCFree(ptr);
240 }
241 
242 #ifdef UNITTESTS
244 #endif /* UNITTESTS */
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1439
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1179
#define SCLogDebug(...)
Definition: util-debug.h:335
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
void DetectSNMPPduTypeRegister(void)
#define MAX_SUBSTRINGS
#define unlikely(expr)
Definition: util-optimize.h:35
Data needed for Match()
Definition: detect.h:322
const char * name
Definition: detect.h:1193
int DetectEngineInspectGenericList(ThreadVars *tv, const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, const uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Signature container.
Definition: detect.h:517
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:308
main detection engine ctx
Definition: detect.h:756
int DetectBufferTypeGetByName(const char *name)
#define str(s)
#define SCCalloc(nm, a)
Definition: util-mem.h:253
#define SIG_FLAG_TOCLIENT
Definition: detect.h:233
void(* Free)(void *)
Definition: detect.h:1184
#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 SIG_FLAG_TOSERVER
Definition: detect.h:232
#define SCEnter(...)
Definition: util-debug.h:337
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1163
uint8_t type
Definition: detect.h:314
#define SCReturnInt(x)
Definition: util-debug.h:341
#define PARSE_REGEX
const char * desc
Definition: detect.h:1195
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:288
SigMatchCtx * ctx
Definition: detect.h:316
struct DetectSNMPPduTypeData_ DetectSNMPPduTypeData
#define SCFree(a)
Definition: util-mem.h:322
PoolThreadReserved res
uint16_t tx_id
#define SIGMATCH_NOOPT
Definition: detect.h:1362
const char * url
Definition: detect.h:1196
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1166
#define DOC_URL
Definition: suricata.h:86
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
Per thread variable structure.
Definition: threadvars.h:57
#define DOC_VERSION
Definition: suricata.h:91
uint16_t flags
Definition: detect.h:1187
Flow data structure.
Definition: flow.h:325
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback)
register inspect engine at start up time
void(* RegisterTests)(void)
Definition: detect.h:1185
a single match condition for a signature
Definition: detect.h:313