suricata
detect-transform-compress-whitespace.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 compress_whitespace tranform keyword
24  */
25 
26 #include "suricata-common.h"
27 
28 #include "detect.h"
29 #include "detect-engine.h"
31 #include "detect-parse.h"
33 
34 #include "util-unittest.h"
35 #include "util-print.h"
36 
37 static int DetectTransformCompressWhitespaceSetup (DetectEngineCtx *, Signature *, const char *);
38 static void DetectTransformCompressWhitespaceRegisterTests(void);
39 
40 static void TransformCompressWhitespace(InspectionBuffer *buffer);
41 
43 {
46  "modify buffer to compress consecutive whitespace characters "
47  "into a single one before inspection";
49  DOC_URL DOC_VERSION "/rules/transforms.html#compress-whitespace";
51  TransformCompressWhitespace;
53  DetectTransformCompressWhitespaceSetup;
55  DetectTransformCompressWhitespaceRegisterTests;
56 
58 }
59 
60 /**
61  * \internal
62  * \brief Apply the compress_whitespace keyword to the last pattern match
63  * \param det_ctx detection engine ctx
64  * \param s signature
65  * \param nullstr should be null
66  * \retval 0 ok
67  * \retval -1 failure
68  */
69 static int DetectTransformCompressWhitespaceSetup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr)
70 {
71  SCEnter();
73  SCReturnInt(r);
74 }
75 
76 static void TransformCompressWhitespace(InspectionBuffer *buffer)
77 {
78  const uint8_t *input = buffer->inspect;
79  const uint32_t input_len = buffer->inspect_len;
80  uint8_t output[input_len]; // we can only shrink
81  uint8_t *oi = output, *os = output;
82 
83  //PrintRawDataFp(stdout, input, input_len);
84  for (uint32_t i = 0; i < input_len; ) {
85  if (!(isspace(*input))) {
86  *oi++ = *input++;
87  i++;
88  } else {
89  *oi++ = *input++;
90  i++;
91 
92  while (i < input_len && isspace(*input)) {
93  input++;
94  i++;
95  }
96  }
97  }
98  uint32_t output_size = oi - os;
99  //PrintRawDataFp(stdout, output, output_size);
100 
101  InspectionBufferCopy(buffer, os, output_size);
102 }
103 
104 #ifdef UNITTESTS
105 static int TransformDoubleWhitespace(InspectionBuffer *buffer)
106 {
107  const uint8_t *input = buffer->inspect;
108  const uint32_t input_len = buffer->inspect_len;
109  uint8_t output[input_len * 2]; // if all chars are whitespace this fits
110  uint8_t *oi = output, *os = output;
111 
112  PrintRawDataFp(stdout, input, input_len);
113  for (uint32_t i = 0; i < input_len; i++) {
114  if (isspace(*input)) {
115  *oi++ = *input;
116  }
117  *oi++ = *input;
118  input++;
119  }
120  uint32_t output_size = oi - os;
121  PrintRawDataFp(stdout, output, output_size);
122 
123  InspectionBufferCopy(buffer, os, output_size);
124  return 0;
125 }
126 
127 static int DetectTransformCompressWhitespaceTest01(void)
128 {
129  const uint8_t *input = (const uint8_t *)" A B C D ";
130  uint32_t input_len = strlen((char *)input);
131 
132  InspectionBuffer buffer;
133  InspectionBufferInit(&buffer, 8);
134  InspectionBufferSetup(&buffer, input, input_len);
135  PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
136  TransformCompressWhitespace(&buffer);
137  PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
138  InspectionBufferFree(&buffer);
139  PASS;
140 }
141 
142 static int DetectTransformCompressWhitespaceTest02(void)
143 {
144  const uint8_t *input = (const uint8_t *)" A B C D ";
145  uint32_t input_len = strlen((char *)input);
146 
147  InspectionBuffer buffer;
148  InspectionBufferInit(&buffer, 8);
149  InspectionBufferSetup(&buffer, input, input_len);
150  PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
151  TransformDoubleWhitespace(&buffer);
152  PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
153  TransformDoubleWhitespace(&buffer);
154  PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
155  TransformCompressWhitespace(&buffer);
156  PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
157  InspectionBufferFree(&buffer);
158  PASS;
159 }
160 
161 #endif
162 
163 static void DetectTransformCompressWhitespaceRegisterTests(void)
164 {
165 #ifdef UNITTESTS
166  UtRegisterTest("DetectTransformCompressWhitespaceTest01",
167  DetectTransformCompressWhitespaceTest01);
168  UtRegisterTest("DetectTransformCompressWhitespaceTest02",
169  DetectTransformCompressWhitespaceTest02);
170 #endif
171 }
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
#define PASS
Pass the test.
const char * name
Definition: detect.h:1200
Signature container.
Definition: detect.h:522
int DetectSignatureAddTransform(Signature *s, int transform)
void InspectionBufferInit(InspectionBuffer *buffer, uint32_t initial_size)
void(* Transform)(InspectionBuffer *)
Definition: detect.h:1183
main detection engine ctx
Definition: detect.h:761
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define SCEnter(...)
Definition: util-debug.h:337
#define SCReturnInt(x)
Definition: util-debug.h:341
const char * desc
Definition: detect.h:1202
void DetectTransformCompressWhitespaceRegister(void)
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition: util-print.c:141
void InspectionBufferCopy(InspectionBuffer *buffer, uint8_t *buf, uint32_t buf_len)
void InspectionBufferSetup(InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
#define SIGMATCH_NOOPT
Definition: detect.h:1369
const char * url
Definition: detect.h:1203
uint32_t inspect_len
Definition: detect.h:345
const uint8_t * inspect
Definition: detect.h:343
#define DOC_URL
Definition: suricata.h:86
void InspectionBufferFree(InspectionBuffer *buffer)
#define DOC_VERSION
Definition: suricata.h:91
uint16_t flags
Definition: detect.h:1194
void(* RegisterTests)(void)
Definition: detect.h:1192