suricata
decode-gre.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 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  * \ingroup decode
20  *
21  * @{
22  */
23 
24 
25 /**
26  * \file
27  *
28  * \author Breno Silva <breno.silva@gmail.com>
29  *
30  * Decodes GRE
31  */
32 
33 #include "suricata-common.h"
34 #include "suricata.h"
35 #include "decode.h"
36 #include "decode-events.h"
37 #include "decode-gre.h"
38 
39 #include "util-validate.h"
40 #include "util-unittest.h"
41 #include "util-debug.h"
42 
43 /**
44  * \brief Function to decode GRE packets
45  */
46 
47 int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
48 {
49  DEBUG_VALIDATE_BUG_ON(pkt == NULL);
50 
51  uint32_t header_len = GRE_HDR_LEN;
52  GRESreHdr *gsre = NULL;
53  GREPPtPHd *gre_pptp_h = NULL;
54 
56 
57  if(len < GRE_HDR_LEN) {
59  return TM_ECODE_FAILED;
60  }
61  if (!PacketIncreaseCheckLayers(p)) {
62  return TM_ECODE_FAILED;
63  }
64 
65  GREHdr *greh = PacketSetGRE(p, pkt);
66 
67  SCLogDebug("p %p pkt %p GRE protocol %04x Len: %d GRE version %x", p, pkt, GRE_GET_PROTO(greh),
69 
70  switch (GRE_GET_VERSION(greh)) {
71  case GRE_VERSION_0:
72 
73  /* GRE version 0 doesn't support the fields below RFC 1701 */
74 
75  /**
76  * \todo We need to make sure this does not allow bypassing
77  * inspection. A server may just ignore these and
78  * continue processing the packet, but we will not look
79  * further into it.
80  */
81 
84  return TM_ECODE_OK;
85  }
86 
89  return TM_ECODE_OK;
90  }
91 
92  /* Adjust header length based on content */
93 
95  header_len += GRE_KEY_LEN;
96 
98  header_len += GRE_SEQ_LEN;
99 
101  header_len += GRE_CHKSUM_LEN + GRE_OFFSET_LEN;
102 
103  if (header_len > len) {
105  return TM_ECODE_OK;
106  }
107 
108  if (GRE_FLAG_ISSET_ROUTE(greh)) {
109  while (1)
110  {
111  if ((header_len + GRE_SRE_HDR_LEN) > len) {
114  return TM_ECODE_OK;
115  }
116 
117  gsre = (GRESreHdr *)(pkt + header_len);
118 
119  header_len += GRE_SRE_HDR_LEN;
120 
121  if ((SCNtohs(gsre->af) == 0) && (gsre->sre_length == 0))
122  break;
123 
124  header_len += gsre->sre_length;
125  if (header_len > len) {
128  return TM_ECODE_OK;
129  }
130  }
131  }
132  break;
133 
134  case GRE_VERSION_1:
135 
136  /* GRE version 1 doesn't support the fields below RFC 1701 */
137 
138  /**
139  * \todo We need to make sure this does not allow bypassing
140  * inspection. A server may just ignore these and
141  * continue processing the packet, but we will not look
142  * further into it.
143  */
144 
147  return TM_ECODE_OK;
148  }
149 
150  if (GRE_FLAG_ISSET_ROUTE(greh)) {
152  return TM_ECODE_OK;
153  }
154 
155  if (GRE_FLAG_ISSET_SSR(greh)) {
157  return TM_ECODE_OK;
158  }
159 
160  if (GRE_FLAG_ISSET_RECUR(greh)) {
162  return TM_ECODE_OK;
163  }
164 
167  return TM_ECODE_OK;
168  }
169 
170  if (GRE_GET_PROTO(greh) != GRE_PROTO_PPP) {
172  return TM_ECODE_OK;
173  }
174 
175  if (!(GRE_FLAG_ISSET_KY(greh))) {
177  return TM_ECODE_OK;
178  }
179 
180  header_len += GRE_KEY_LEN;
181  /* key is set and proto == PPP */
182  gre_pptp_h = (GREPPtPHd *)pkt;
183 
184  /* Adjust header length based on content */
185 
186  if (GRE_FLAG_ISSET_SQ(greh))
187  header_len += GRE_SEQ_LEN;
188 
190  header_len += GREV1_ACK_LEN;
191 
192  if (header_len > len) {
194  return TM_ECODE_OK;
195  }
196 
197  break;
198  default:
200  return TM_ECODE_OK;
201  }
202 
203  switch (GRE_GET_PROTO(greh)) {
204  case ETHERNET_TYPE_IP:
205  {
206  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
207  len - header_len, DECODE_TUNNEL_IPV4);
208  if (tp != NULL) {
211  }
212  break;
213  }
214 
215  case GRE_PROTO_PPP:
216  {
217  if (gre_pptp_h && !gre_pptp_h->payload_length)
218  return TM_ECODE_OK;
219 
220  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
221  len - header_len, DECODE_TUNNEL_PPP);
222  if (tp != NULL) {
225  }
226  break;
227  }
228 
229  case ETHERNET_TYPE_IPV6:
230  {
231  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
232  len - header_len, DECODE_TUNNEL_IPV6);
233  if (tp != NULL) {
236  }
237  break;
238  }
239 
240  case ETHERNET_TYPE_VLAN:
241  {
242  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
243  len - header_len, DECODE_TUNNEL_VLAN);
244  if (tp != NULL) {
247  }
248  break;
249  }
250 
252  {
253  // Determine if it's Type I or Type II based on the flags in the GRE header.
254  // Type I: 0|0|0|0|0|00000|000000000|00000
255  // Type II: 0|0|0|1|0|00000|000000000|00000
256  // Seq
257  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len, len - header_len,
259  if (tp != NULL) {
262  }
263  break;
264  }
265 
267  {
268  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
269  len - header_len, DECODE_TUNNEL_ETHERNET);
270  if (tp != NULL) {
273  }
274  break;
275  }
276 
277  case ETHERNET_TYPE_ARP: {
279  tv, dtv, p, pkt + header_len, len - header_len, DECODE_TUNNEL_ARP);
280  if (tp != NULL) {
283  }
284  break;
285  }
286 
287  default:
288  return TM_ECODE_OK;
289  }
290  return TM_ECODE_OK;
291 }
292 
293 
294 #ifdef UNITTESTS
295 /**
296  * \test DecodeGRETest01 is a test for small gre packet
297  */
298 
299 static int DecodeGREtest01 (void)
300 {
301  uint8_t raw_gre[] = { 0x00 ,0x6e ,0x62 };
302  Packet *p = PacketGetFromAlloc();
303  FAIL_IF_NULL(p);
304  ThreadVars tv;
306 
307  memset(&tv, 0, sizeof(ThreadVars));
308  memset(&dtv, 0, sizeof(DecodeThreadVars));
309 
310  DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre));
312 
313  SCFree(p);
314  PASS;
315 }
316 
317 /**
318  * \test DecodeGRETest02 is a test for wrong gre version
319  */
320 
321 static int DecodeGREtest02 (void)
322 {
323  uint8_t raw_gre[] = {
324  0x00, 0x6e, 0x62, 0xac, 0x40, 0x00, 0x40, 0x2f,
325  0xc2, 0xc7, 0x0a, 0x00, 0x00, 0x64, 0x0a, 0x00,
326  0x00, 0x8a, 0x30, 0x01, 0x0b, 0x00, 0x4e, 0x00,
327  0x00, 0x00, 0x18, 0x4a, 0x50, 0xff, 0x03, 0x00,
328  0x21, 0x45, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x40,
329  0x00, 0x40, 0x11, 0x94, 0x22, 0x50, 0x7e, 0x2b,
330  0x2d, 0xc2, 0x6d, 0x68, 0x68, 0x80, 0x0e, 0x00,
331  0x35, 0x00, 0x36, 0x9f, 0x18, 0xdb, 0xc4, 0x01,
332  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
333  0x01, 0x03, 0x73, 0x31, 0x36, 0x09, 0x73, 0x69,
334  0x74, 0x65, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x03,
335  0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
336  0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00,
337  0x00, 0x00, 0x00 };
338  Packet *p = PacketGetFromAlloc();
339  FAIL_IF_NULL(p);
340  ThreadVars tv;
342 
343  memset(&tv, 0, sizeof(ThreadVars));
344  memset(&dtv, 0, sizeof(DecodeThreadVars));
345 
346  DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre));
348 
349  SCFree(p);
350  PASS;
351 }
352 
353 
354 /**
355  * \test DecodeGRETest03 is a test for valid gre packet
356  */
357 
358 static int DecodeGREtest03 (void)
359 {
360  uint8_t raw_gre[] = {
361  0x00, 0x6e, 0x62, 0xac, 0x40, 0x00, 0x40, 0x2f,
362  0xc2, 0xc7, 0x0a, 0x00, 0x00, 0x64, 0x0a, 0x00,
363  0x00, 0x8a, 0x30, 0x01, 0x88, 0x0b, 0x00, 0x4e,
364  0x00, 0x00, 0x00, 0x18, 0x4a, 0x50, 0xff, 0x03,
365  0x00, 0x21, 0x45, 0x00, 0x00, 0x4a, 0x00, 0x00,
366  0x40, 0x00, 0x40, 0x11, 0x94, 0x22, 0x50, 0x7e,
367  0x2b, 0x2d, 0xc2, 0x6d, 0x68, 0x68, 0x80, 0x0e,
368  0x00, 0x35, 0x00, 0x36, 0x9f, 0x18, 0xdb, 0xc4,
369  0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
370  0x00, 0x01, 0x03, 0x73, 0x31, 0x36, 0x09, 0x73,
371  0x69, 0x74, 0x65, 0x6d, 0x65, 0x74, 0x65, 0x72,
372  0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
373  0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00,
374  0x00, 0x00, 0x00, 0x00 };
375  Packet *p = PacketGetFromAlloc();
376  FAIL_IF_NULL(p);
377  ThreadVars tv;
379 
380  memset(&tv, 0, sizeof(ThreadVars));
381  memset(&dtv, 0, sizeof(DecodeThreadVars));
382 
383  DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre));
384  FAIL_IF_NOT(PacketIsGRE(p));
385 
386  SCFree(p);
387  PASS;
388 }
389 #endif /* UNITTESTS */
390 
391 /**
392  * \brief this function registers unit tests for GRE decoder
393  */
394 
396 {
397 #ifdef UNITTESTS
398  UtRegisterTest("DecodeGREtest01", DecodeGREtest01);
399  UtRegisterTest("DecodeGREtest02", DecodeGREtest02);
400  UtRegisterTest("DecodeGREtest03", DecodeGREtest03);
401 #endif /* UNITTESTS */
402 }
403 /**
404  * @}
405  */
ETHERNET_TYPE_BRIDGE
#define ETHERNET_TYPE_BRIDGE
Definition: decode-ethernet.h:36
GRE_FLAG_ISSET_CHKSUM
#define GRE_FLAG_ISSET_CHKSUM(r)
Definition: decode-gre.h:70
GRE_FLAG_ISSET_ROUTE
#define GRE_FLAG_ISSET_ROUTE(r)
Definition: decode-gre.h:71
len
uint8_t len
Definition: app-layer-dnp3.h:2
DECODE_TUNNEL_IPV6
@ DECODE_TUNNEL_IPV6
Definition: decode.h:1085
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
GREV1_ACK_LEN
#define GREV1_ACK_LEN
Definition: decode-gre.h:81
GRE_FLAG_ISSET_RECUR
#define GRE_FLAG_ISSET_RECUR(r)
Definition: decode-gre.h:75
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
ENGINE_ISSET_EVENT
#define ENGINE_ISSET_EVENT(p, e)
Definition: decode.h:1178
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
GRE_VERSION1_HDR_TOO_BIG
@ GRE_VERSION1_HDR_TOO_BIG
Definition: decode-events.h:142
ETHERNET_TYPE_IPV6
#define ETHERNET_TYPE_IPV6
Definition: decode-ethernet.h:39
GRE_PKT_TOO_SMALL
@ GRE_PKT_TOO_SMALL
Definition: decode-events.h:128
GRE_HDR_LEN
#define GRE_HDR_LEN
Definition: decode-gre.h:62
DECODE_TUNNEL_ERSPANI
@ DECODE_TUNNEL_ERSPANI
Definition: decode.h:1082
GRE_WRONG_VERSION
@ GRE_WRONG_VERSION
Definition: decode-events.h:129
GRE_VERSION1_ROUTE
@ GRE_VERSION1_ROUTE
Definition: decode-events.h:135
ETHERNET_TYPE_ERSPAN
#define ETHERNET_TYPE_ERSPAN
Definition: decode-ethernet.h:48
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
util-unittest.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1337
GREV1_FLAG_ISSET_FLAGS
#define GREV1_FLAG_ISSET_FLAGS(r)
Definition: decode-gre.h:82
decode-gre.h
DECODE_TUNNEL_ERSPANII
@ DECODE_TUNNEL_ERSPANII
Definition: decode.h:1081
decode.h
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
GRE_FLAG_ISSET_SQ
#define GRE_FLAG_ISSET_SQ(r)
Definition: decode-gre.h:73
GRE_VERSION0_RECUR
@ GRE_VERSION0_RECUR
Definition: decode-events.h:130
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
DECODE_TUNNEL_PPP
@ DECODE_TUNNEL_PPP
Definition: decode.h:1087
GRE_VERSION1_NO_KEY
@ GRE_VERSION1_NO_KEY
Definition: decode-events.h:139
DecodeGRE
int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Function to decode GRE packets.
Definition: decode-gre.c:47
GRE_VERSION_0
#define GRE_VERSION_0
Definition: decode-gre.h:59
GRE_VERSION0_FLAGS
@ GRE_VERSION0_FLAGS
Definition: decode-events.h:131
GRE_KEY_LEN
#define GRE_KEY_LEN
Definition: decode-gre.h:65
GRE_VERSION1_SSR
@ GRE_VERSION1_SSR
Definition: decode-events.h:136
DECODE_TUNNEL_VLAN
@ DECODE_TUNNEL_VLAN
Definition: decode.h:1083
Packet_
Definition: decode.h:482
DECODE_TUNNEL_IPV4
@ DECODE_TUNNEL_IPV4
Definition: decode.h:1084
GRE_VERSION0_HDR_TOO_BIG
@ GRE_VERSION0_HDR_TOO_BIG
Definition: decode-events.h:132
DECODE_TUNNEL_ETHERNET
@ DECODE_TUNNEL_ETHERNET
Definition: decode.h:1080
GRE_VERSION1_WRONG_PROTOCOL
@ GRE_VERSION1_WRONG_PROTOCOL
Definition: decode-events.h:140
GRE_OFFSET_LEN
#define GRE_OFFSET_LEN
Definition: decode-gre.h:64
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
GRE_CHKSUM_LEN
#define GRE_CHKSUM_LEN
Definition: decode-gre.h:63
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:168
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:414
suricata-common.h
GRE_VERSION1_RECUR
@ GRE_VERSION1_RECUR
Definition: decode-events.h:137
GREV1_FLAG_ISSET_ACK
#define GREV1_FLAG_ISSET_ACK(r)
Definition: decode-gre.h:83
DecodeThreadVars_::counter_gre
uint16_t counter_gre
Definition: decode.h:981
GRE_SRE_HDR_LEN
#define GRE_SRE_HDR_LEN
Definition: decode-gre.h:67
GRE_PROTO_PPP
#define GRE_PROTO_PPP
Definition: decode-gre.h:68
GRE_VERSION0_MALFORMED_SRE_HDR
@ GRE_VERSION0_MALFORMED_SRE_HDR
Definition: decode-events.h:133
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:232
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:946
DecodeGRERegisterTests
void DecodeGRERegisterTests(void)
this function registers unit tests for GRE decoder
Definition: decode-gre.c:395
GRE_GET_PROTO
#define GRE_GET_PROTO(r)
Definition: decode-gre.h:78
greh
GREHdr greh
Definition: decode-gre.h:0
ETHERNET_TYPE_ARP
#define ETHERNET_TYPE_ARP
Definition: decode-ethernet.h:35
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:111
GRE_FLAG_ISSET_KY
#define GRE_FLAG_ISSET_KY(r)
Definition: decode-gre.h:72
GRE_FLAG_ISSET_SSR
#define GRE_FLAG_ISSET_SSR(r)
Definition: decode-gre.h:74
suricata.h
PKT_SRC_DECODER_GRE
@ PKT_SRC_DECODER_GRE
Definition: decode.h:56
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1171
ETHERNET_TYPE_VLAN
#define ETHERNET_TYPE_VLAN
Definition: decode-vlan.h:31
DECODE_TUNNEL_ARP
@ DECODE_TUNNEL_ARP
Definition: decode.h:1089
GRE_SEQ_LEN
#define GRE_SEQ_LEN
Definition: decode-gre.h:66
GRE_GET_VERSION
#define GRE_GET_VERSION(r)
Definition: decode-gre.h:76
PacketTunnelPktSetup
Packet * PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent, const uint8_t *pkt, uint32_t len, enum DecodeTunnelProto proto)
Setup a pseudo packet (tunnel)
Definition: decode.c:367
GRE_VERSION1_FLAGS
@ GRE_VERSION1_FLAGS
Definition: decode-events.h:138
GRE_VERSION1_CHKSUM
@ GRE_VERSION1_CHKSUM
Definition: decode-events.h:134
GRE_VERSION_1
#define GRE_VERSION_1
Definition: decode-gre.h:60
ETHERNET_TYPE_IP
#define ETHERNET_TYPE_IP
Definition: decode-ethernet.h:34
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102