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-unittest.h"
40 #include "util-debug.h"
41 
42 /**
43  * \brief Function to decode GRE packets
44  */
45 
46 int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
47 {
48  uint32_t header_len = GRE_HDR_LEN;
49  GRESreHdr *gsre = NULL;
50 
52 
53  if(len < GRE_HDR_LEN) {
55  return TM_ECODE_FAILED;
56  }
57 
58  p->greh = (GREHdr *)pkt;
59  if(p->greh == NULL)
60  return TM_ECODE_FAILED;
61 
62  SCLogDebug("p %p pkt %p GRE protocol %04x Len: %d GRE version %x",
63  p, pkt, GRE_GET_PROTO(p->greh), len,GRE_GET_VERSION(p->greh));
64 
65  switch (GRE_GET_VERSION(p->greh))
66  {
67  case GRE_VERSION_0:
68 
69  /* GRE version 0 doesn't support the fields below RFC 1701 */
70 
71  /**
72  * \todo We need to make sure this does not allow bypassing
73  * inspection. A server may just ignore these and
74  * continue processing the packet, but we will not look
75  * further into it.
76  */
77 
78  if (GRE_FLAG_ISSET_RECUR(p->greh)) {
80  return TM_ECODE_OK;
81  }
82 
83  if (GREV1_FLAG_ISSET_FLAGS(p->greh)) {
85  return TM_ECODE_OK;
86  }
87 
88  /* Adjust header length based on content */
89 
90  if (GRE_FLAG_ISSET_KY(p->greh))
91  header_len += GRE_KEY_LEN;
92 
93  if (GRE_FLAG_ISSET_SQ(p->greh))
94  header_len += GRE_SEQ_LEN;
95 
97  header_len += GRE_CHKSUM_LEN + GRE_OFFSET_LEN;
98 
99  if (header_len > len) {
101  return TM_ECODE_OK;
102  }
103 
104  if (GRE_FLAG_ISSET_ROUTE(p->greh))
105  {
106  while (1)
107  {
108  if ((header_len + GRE_SRE_HDR_LEN) > len) {
111  return TM_ECODE_OK;
112  }
113 
114  gsre = (GRESreHdr *)(pkt + header_len);
115 
116  header_len += GRE_SRE_HDR_LEN;
117 
118  if ((SCNtohs(gsre->af) == 0) && (gsre->sre_length == 0))
119  break;
120 
121  header_len += gsre->sre_length;
122  if (header_len > len) {
125  return TM_ECODE_OK;
126  }
127  }
128  }
129  break;
130 
131  case GRE_VERSION_1:
132 
133  /* GRE version 1 doesn't support the fields below RFC 1701 */
134 
135  /**
136  * \todo We need to make sure this does not allow bypassing
137  * inspection. A server may just ignore these and
138  * continue processing the packet, but we will not look
139  * further into it.
140  */
141 
142  if (GRE_FLAG_ISSET_CHKSUM(p->greh)) {
144  return TM_ECODE_OK;
145  }
146 
147  if (GRE_FLAG_ISSET_ROUTE(p->greh)) {
149  return TM_ECODE_OK;
150  }
151 
152  if (GRE_FLAG_ISSET_SSR(p->greh)) {
154  return TM_ECODE_OK;
155  }
156 
157  if (GRE_FLAG_ISSET_RECUR(p->greh)) {
159  return TM_ECODE_OK;
160  }
161 
162  if (GREV1_FLAG_ISSET_FLAGS(p->greh)) {
164  return TM_ECODE_OK;
165  }
166 
167  if (GRE_GET_PROTO(p->greh) != GRE_PROTO_PPP) {
169  return TM_ECODE_OK;
170  }
171 
172  if (!(GRE_FLAG_ISSET_KY(p->greh))) {
174  return TM_ECODE_OK;
175  }
176 
177  header_len += GRE_KEY_LEN;
178 
179  /* Adjust header length based on content */
180 
181  if (GRE_FLAG_ISSET_SQ(p->greh))
182  header_len += GRE_SEQ_LEN;
183 
184  if (GREV1_FLAG_ISSET_ACK(p->greh))
185  header_len += GREV1_ACK_LEN;
186 
187  if (header_len > len) {
189  return TM_ECODE_OK;
190  }
191 
192  break;
193  default:
195  return TM_ECODE_OK;
196  }
197 
198  switch (GRE_GET_PROTO(p->greh))
199  {
200  case ETHERNET_TYPE_IP:
201  {
202  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
203  len - header_len, DECODE_TUNNEL_IPV4);
204  if (tp != NULL) {
207  }
208  break;
209  }
210 
211  case GRE_PROTO_PPP:
212  {
213  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
214  len - header_len, DECODE_TUNNEL_PPP);
215  if (tp != NULL) {
218  }
219  break;
220  }
221 
222  case ETHERNET_TYPE_IPV6:
223  {
224  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
225  len - header_len, DECODE_TUNNEL_IPV6);
226  if (tp != NULL) {
229  }
230  break;
231  }
232 
233  case ETHERNET_TYPE_VLAN:
234  {
235  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
236  len - header_len, DECODE_TUNNEL_VLAN);
237  if (tp != NULL) {
240  }
241  break;
242  }
243 
245  {
246  // Determine if it's Type I or Type II based on the flags in the GRE header.
247  // Type I: 0|0|0|0|0|00000|000000000|00000
248  // Type II: 0|0|0|1|0|00000|000000000|00000
249  // Seq
250  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
251  len - header_len,
252  GRE_FLAG_ISSET_SQ(p->greh) == 0 ?
255  if (tp != NULL) {
258  }
259  break;
260  }
261 
263  {
264  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len,
265  len - header_len, DECODE_TUNNEL_ETHERNET);
266  if (tp != NULL) {
269  }
270  break;
271  }
272 
273  default:
274  return TM_ECODE_OK;
275  }
276  return TM_ECODE_OK;
277 }
278 
279 
280 #ifdef UNITTESTS
281 /**
282  * \test DecodeGRETest01 is a test for small gre packet
283  */
284 
285 static int DecodeGREtest01 (void)
286 {
287  uint8_t raw_gre[] = { 0x00 ,0x6e ,0x62 };
288  Packet *p = PacketGetFromAlloc();
289  FAIL_IF_NULL(p);
290  ThreadVars tv;
292 
293  memset(&tv, 0, sizeof(ThreadVars));
294  memset(&dtv, 0, sizeof(DecodeThreadVars));
295 
296  DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre));
298 
299  SCFree(p);
300  PASS;
301 }
302 
303 /**
304  * \test DecodeGRETest02 is a test for wrong gre version
305  */
306 
307 static int DecodeGREtest02 (void)
308 {
309  uint8_t raw_gre[] = {
310  0x00, 0x6e, 0x62, 0xac, 0x40, 0x00, 0x40, 0x2f,
311  0xc2, 0xc7, 0x0a, 0x00, 0x00, 0x64, 0x0a, 0x00,
312  0x00, 0x8a, 0x30, 0x01, 0x0b, 0x00, 0x4e, 0x00,
313  0x00, 0x00, 0x18, 0x4a, 0x50, 0xff, 0x03, 0x00,
314  0x21, 0x45, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x40,
315  0x00, 0x40, 0x11, 0x94, 0x22, 0x50, 0x7e, 0x2b,
316  0x2d, 0xc2, 0x6d, 0x68, 0x68, 0x80, 0x0e, 0x00,
317  0x35, 0x00, 0x36, 0x9f, 0x18, 0xdb, 0xc4, 0x01,
318  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
319  0x01, 0x03, 0x73, 0x31, 0x36, 0x09, 0x73, 0x69,
320  0x74, 0x65, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x03,
321  0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
322  0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00,
323  0x00, 0x00, 0x00 };
324  Packet *p = PacketGetFromAlloc();
325  FAIL_IF_NULL(p);
326  ThreadVars tv;
328 
329  memset(&tv, 0, sizeof(ThreadVars));
330  memset(&dtv, 0, sizeof(DecodeThreadVars));
331 
332  DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre));
334 
335  SCFree(p);
336  PASS;
337 }
338 
339 
340 /**
341  * \test DecodeGRETest03 is a test for valid gre packet
342  */
343 
344 static int DecodeGREtest03 (void)
345 {
346  uint8_t raw_gre[] = {
347  0x00, 0x6e, 0x62, 0xac, 0x40, 0x00, 0x40, 0x2f,
348  0xc2, 0xc7, 0x0a, 0x00, 0x00, 0x64, 0x0a, 0x00,
349  0x00, 0x8a, 0x30, 0x01, 0x88, 0x0b, 0x00, 0x4e,
350  0x00, 0x00, 0x00, 0x18, 0x4a, 0x50, 0xff, 0x03,
351  0x00, 0x21, 0x45, 0x00, 0x00, 0x4a, 0x00, 0x00,
352  0x40, 0x00, 0x40, 0x11, 0x94, 0x22, 0x50, 0x7e,
353  0x2b, 0x2d, 0xc2, 0x6d, 0x68, 0x68, 0x80, 0x0e,
354  0x00, 0x35, 0x00, 0x36, 0x9f, 0x18, 0xdb, 0xc4,
355  0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
356  0x00, 0x01, 0x03, 0x73, 0x31, 0x36, 0x09, 0x73,
357  0x69, 0x74, 0x65, 0x6d, 0x65, 0x74, 0x65, 0x72,
358  0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
359  0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00,
360  0x00, 0x00, 0x00, 0x00 };
361  Packet *p = PacketGetFromAlloc();
362  FAIL_IF_NULL(p);
363  ThreadVars tv;
365 
366  memset(&tv, 0, sizeof(ThreadVars));
367  memset(&dtv, 0, sizeof(DecodeThreadVars));
368 
369  DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre));
370  FAIL_IF_NULL(p->greh);
371 
372  SCFree(p);
373  PASS;
374 }
375 #endif /* UNITTESTS */
376 
377 /**
378  * \brief this function registers unit tests for GRE decoder
379  */
380 
382 {
383 #ifdef UNITTESTS
384  UtRegisterTest("DecodeGREtest01", DecodeGREtest01);
385  UtRegisterTest("DecodeGREtest02", DecodeGREtest02);
386  UtRegisterTest("DecodeGREtest03", DecodeGREtest03);
387 #endif /* UNITTESTS */
388 }
389 /**
390  * @}
391  */
GRE_PKT_TOO_SMALL
@ GRE_PKT_TOO_SMALL
Definition: decode-events.h:127
Packet_::greh
GREHdr * greh
Definition: decode.h:548
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:65
GRE_FLAG_ISSET_ROUTE
#define GRE_FLAG_ISSET_ROUTE(r)
Definition: decode-gre.h:66
len
uint8_t len
Definition: app-layer-dnp3.h:2
DECODE_TUNNEL_IPV6
@ DECODE_TUNNEL_IPV6
Definition: decode.h:917
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
GRE_VERSION0_RECUR
@ GRE_VERSION0_RECUR
Definition: decode-events.h:129
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:169
GREV1_ACK_LEN
#define GREV1_ACK_LEN
Definition: decode-gre.h:76
GRE_FLAG_ISSET_RECUR
#define GRE_FLAG_ISSET_RECUR(r)
Definition: decode-gre.h:70
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:1030
GRE_VERSION1_NO_KEY
@ GRE_VERSION1_NO_KEY
Definition: decode-events.h:138
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
GRE_WRONG_VERSION
@ GRE_WRONG_VERSION
Definition: decode-events.h:128
ETHERNET_TYPE_IPV6
#define ETHERNET_TYPE_IPV6
Definition: decode-ethernet.h:39
GRE_HDR_LEN
#define GRE_HDR_LEN
Definition: decode-gre.h:57
DECODE_TUNNEL_ERSPANI
@ DECODE_TUNNEL_ERSPANI
Definition: decode.h:914
GRE_VERSION0_MALFORMED_SRE_HDR
@ GRE_VERSION0_MALFORMED_SRE_HDR
Definition: decode-events.h:132
ETHERNET_TYPE_ERSPAN
#define ETHERNET_TYPE_ERSPAN
Definition: decode-ethernet.h:48
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
util-unittest.h
GRE_VERSION1_WRONG_PROTOCOL
@ GRE_VERSION1_WRONG_PROTOCOL
Definition: decode-events.h:139
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
GRE_VERSION0_HDR_TOO_BIG
@ GRE_VERSION0_HDR_TOO_BIG
Definition: decode-events.h:131
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1162
GREV1_FLAG_ISSET_FLAGS
#define GREV1_FLAG_ISSET_FLAGS(r)
Definition: decode-gre.h:77
decode-gre.h
DECODE_TUNNEL_ERSPANII
@ DECODE_TUNNEL_ERSPANII
Definition: decode.h:913
GRE_VERSION1_FLAGS
@ GRE_VERSION1_FLAGS
Definition: decode-events.h:137
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:68
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
DECODE_TUNNEL_PPP
@ DECODE_TUNNEL_PPP
Definition: decode.h:919
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:46
GRE_VERSION_0
#define GRE_VERSION_0
Definition: decode-gre.h:54
GRE_KEY_LEN
#define GRE_KEY_LEN
Definition: decode-gre.h:60
DECODE_TUNNEL_VLAN
@ DECODE_TUNNEL_VLAN
Definition: decode.h:915
Packet_
Definition: decode.h:415
DECODE_TUNNEL_IPV4
@ DECODE_TUNNEL_IPV4
Definition: decode.h:916
DECODE_TUNNEL_ETHERNET
@ DECODE_TUNNEL_ETHERNET
Definition: decode.h:912
GRE_OFFSET_LEN
#define GRE_OFFSET_LEN
Definition: decode-gre.h:59
decode-events.h
GRE_VERSION1_RECUR
@ GRE_VERSION1_RECUR
Definition: decode-events.h:136
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
GRE_VERSION1_SSR
@ GRE_VERSION1_SSR
Definition: decode-events.h:135
GRE_CHKSUM_LEN
#define GRE_CHKSUM_LEN
Definition: decode-gre.h:58
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:167
GRE_VERSION1_HDR_TOO_BIG
@ GRE_VERSION1_HDR_TOO_BIG
Definition: decode-events.h:141
GRE_VERSION1_CHKSUM
@ GRE_VERSION1_CHKSUM
Definition: decode-events.h:133
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:395
suricata-common.h
GREV1_FLAG_ISSET_ACK
#define GREV1_FLAG_ISSET_ACK(r)
Definition: decode-gre.h:78
DecodeThreadVars_::counter_gre
uint16_t counter_gre
Definition: decode.h:664
GRE_SRE_HDR_LEN
#define GRE_SRE_HDR_LEN
Definition: decode-gre.h:62
GRE_PROTO_PPP
#define GRE_PROTO_PPP
Definition: decode-gre.h:63
GRE_VERSION1_ROUTE
@ GRE_VERSION1_ROUTE
Definition: decode-events.h:134
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
GRE_VERSION0_FLAGS
@ GRE_VERSION0_FLAGS
Definition: decode-events.h:130
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:146
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:634
DecodeGRERegisterTests
void DecodeGRERegisterTests(void)
this function registers unit tests for GRE decoder
Definition: decode-gre.c:381
GRE_GET_PROTO
#define GRE_GET_PROTO(r)
Definition: decode-gre.h:73
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:110
GRE_FLAG_ISSET_KY
#define GRE_FLAG_ISSET_KY(r)
Definition: decode-gre.h:67
GRE_FLAG_ISSET_SSR
#define GRE_FLAG_ISSET_SSR(r)
Definition: decode-gre.h:69
suricata.h
PKT_SRC_DECODER_GRE
@ PKT_SRC_DECODER_GRE
Definition: decode.h:52
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1023
ETHERNET_TYPE_VLAN
#define ETHERNET_TYPE_VLAN
Definition: decode-vlan.h:31
GRE_SEQ_LEN
#define GRE_SEQ_LEN
Definition: decode-gre.h:61
GRE_GET_VERSION
#define GRE_GET_VERSION(r)
Definition: decode-gre.h:71
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:281
GRE_VERSION_1
#define GRE_VERSION_1
Definition: decode-gre.h:55
ETHERNET_TYPE_IP
#define ETHERNET_TYPE_IP
Definition: decode-ethernet.h:34