suricata
decode-vlan.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  * Decode 802.1q
31  */
32 
33 #include "suricata-common.h"
34 #include "decode.h"
35 #include "decode-vlan.h"
36 #include "decode-events.h"
37 
38 #include "util-validate.h"
39 #include "util-unittest.h"
40 #include "util-debug.h"
41 
42 /**
43  * \internal
44  * \brief this function is used to decode IEEE802.1q packets
45  *
46  * \param tv pointer to the thread vars
47  * \param dtv pointer code thread vars
48  * \param p pointer to the packet struct
49  * \param pkt pointer to the raw packet
50  * \param len packet len
51  * \param pq pointer to the packet queue
52  *
53  */
55  const uint8_t *pkt, uint32_t len)
56 {
57  DEBUG_VALIDATE_BUG_ON(pkt == NULL);
58 
59  uint16_t proto;
60 
61  if (p->vlan_idx == 0)
63  else if (p->vlan_idx == 1)
65 
66  if(len < VLAN_HEADER_LEN) {
68  return TM_ECODE_FAILED;
69  }
70  if (!PacketIncreaseCheckLayers(p)) {
71  return TM_ECODE_FAILED;
72  }
73  if (p->vlan_idx >= 2) {
75  return TM_ECODE_FAILED;
76  }
77 
78  VLANHdr *vlan_hdr = (VLANHdr *)pkt;
79 
80  proto = GET_VLAN_PROTO(vlan_hdr);
81 
82  SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRIu32 "",
83  p, pkt, proto, GET_VLAN_PRIORITY(vlan_hdr), GET_VLAN_CFI(vlan_hdr),
84  GET_VLAN_ID(vlan_hdr), len);
85 
86  p->vlan_id[p->vlan_idx++] = (uint16_t)GET_VLAN_ID(vlan_hdr);
87 
88  if (DecodeNetworkLayer(tv, dtv, proto, p,
89  pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN) == false) {
91  return TM_ECODE_FAILED;
92  }
93  return TM_ECODE_OK;
94 }
95 
96 uint16_t DecodeVLANGetId(const Packet *p, uint8_t layer)
97 {
98  if (unlikely(layer > 1))
99  return 0;
100  if (p->vlan_idx > layer) {
101  return p->vlan_id[layer];
102  }
103  return 0;
104 }
105 
106 typedef struct IEEE8021ahHdr_ {
107  uint32_t flags;
108  uint8_t c_destination[6];
109  uint8_t c_source[6];
110  uint16_t type; /**< next protocol */
111 } __attribute__((__packed__)) IEEE8021ahHdr;
112 
113 #define IEEE8021AH_HEADER_LEN sizeof(IEEE8021ahHdr)
114 
116  const uint8_t *pkt, uint32_t len)
117 {
118  DEBUG_VALIDATE_BUG_ON(pkt == NULL);
119 
121 
122  if (len < IEEE8021AH_HEADER_LEN) {
124  return TM_ECODE_FAILED;
125  }
126 
127  IEEE8021ahHdr *hdr = (IEEE8021ahHdr *)pkt;
128  const uint16_t next_proto = SCNtohs(hdr->type);
129 
130  DecodeNetworkLayer(tv, dtv, next_proto, p,
132 
133  return TM_ECODE_OK;
134 }
135 
136 #ifdef UNITTESTS
137 #include "util-unittest-helper.h"
138 #include "packet.h"
139 
140 /** \todo Must GRE+VLAN and Multi-Vlan packets to
141  * create more tests
142  */
143 
144 /**
145  * \test DecodeVLANTest01 test if vlan header is too small.
146  *
147  * \retval 1 on success
148  * \retval 0 on failure
149  */
150 static int DecodeVLANtest01 (void)
151 {
152  uint8_t raw_vlan[] = { 0x00, 0x20, 0x08 };
153  Packet *p = PacketGetFromAlloc();
154  if (unlikely(p == NULL))
155  return 0;
156  ThreadVars tv;
158 
159  memset(&tv, 0, sizeof(ThreadVars));
160  memset(&dtv, 0, sizeof(DecodeThreadVars));
161 
162  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
163 
165  SCFree(p);
166  return 1;
167  }
168 
169  SCFree(p);
170  return 0;
171 }
172 
173 /**
174  * \test DecodeVLANTest02 test if vlan header has unknown type.
175  *
176  * \retval 1 on success
177  * \retval 0 on failure
178  */
179 static int DecodeVLANtest02 (void)
180 {
181  uint8_t raw_vlan[] = {
182  0x00, 0x20, 0x01, 0x00, 0x45, 0x00, 0x00, 0x34,
183  0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
184  0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
185  0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
186  0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
187  0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
188  0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
189  Packet *p = PacketGetFromAlloc();
190  if (unlikely(p == NULL))
191  return 0;
192  ThreadVars tv;
194 
195  memset(&tv, 0, sizeof(ThreadVars));
196  memset(&dtv, 0, sizeof(DecodeThreadVars));
197 
198  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
199 
200 
202  SCFree(p);
203  return 1;
204  }
205 
206  SCFree(p);
207  return 0;
208 }
209 
210 /**
211  * \test DecodeVLANTest02 test a good vlan header.
212  *
213  * \retval 1 on success
214  * \retval 0 on failure
215  */
216 static int DecodeVLANtest03 (void)
217 {
218  uint8_t raw_vlan[] = {
219  0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
220  0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
221  0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
222  0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
223  0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
224  0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
225  0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
226  Packet *p = PacketGetFromAlloc();
227  if (unlikely(p == NULL))
228  return 0;
229  ThreadVars tv;
231 
232  memset(&tv, 0, sizeof(ThreadVars));
233  memset(&dtv, 0, sizeof(DecodeThreadVars));
234 
236 
237  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
238 
239 
240  if(p->vlan_id[0] == 0) {
241  goto error;
242  }
243 
245  goto error;
246  }
247 
249  goto error;
250  }
251 
252  PacketRecycle(p);
253  FlowShutdown();
254  SCFree(p);
255  return 1;
256 
257 error:
258  PacketRecycle(p);
259  FlowShutdown();
260  SCFree(p);
261  return 0;
262 }
263 #endif /* UNITTESTS */
264 
266 {
267 #ifdef UNITTESTS
268  UtRegisterTest("DecodeVLANtest01", DecodeVLANtest01);
269  UtRegisterTest("DecodeVLANtest02", DecodeVLANtest02);
270  UtRegisterTest("DecodeVLANtest03", DecodeVLANtest03);
271 #endif /* UNITTESTS */
272 }
273 
274 /**
275  * @}
276  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:887
len
uint8_t len
Definition: app-layer-dnp3.h:2
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:167
Packet_::vlan_id
uint16_t vlan_id[2]
Definition: decode.h:455
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
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:902
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:167
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:456
GET_VLAN_CFI
#define GET_VLAN_CFI(vlanh)
Definition: decode-vlan.h:35
IEEE8021AH_HEADER_LEN
#define IEEE8021AH_HEADER_LEN
proto
uint8_t proto
Definition: decode-template.h:0
IEEE8021ahHdr_
Definition: decode-vlan.c:106
DecodeVLANGetId
uint16_t DecodeVLANGetId(const Packet *p, uint8_t layer)
Definition: decode-vlan.c:96
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
util-unittest.h
util-unittest-helper.h
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
VLAN_HEADER_TOO_MANY_LAYERS
@ VLAN_HEADER_TOO_MANY_LAYERS
Definition: decode-events.h:147
__attribute__
struct IEEE8021ahHdr_ __attribute__((__packed__))
DNP3 link header.
Definition: decode-vlan.c:111
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:543
decode.h
util-debug.h
GET_VLAN_PRIORITY
#define GET_VLAN_PRIORITY(vlanh)
Definition: decode-vlan.h:34
VLAN_HEADER_LEN
#define VLAN_HEADER_LEN
Definition: decode-vlan.h:50
IEEE8021ahHdr_::type
uint16_t type
Definition: decode-vlan.c:110
VLAN_UNKNOWN_TYPE
@ VLAN_UNKNOWN_TYPE
Definition: decode-events.h:146
IEEE8021ahHdr_::flags
uint32_t flags
Definition: decode-vlan.c:107
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
GET_VLAN_PROTO
#define GET_VLAN_PROTO(vlanh)
Definition: decode-vlan.h:37
VLAN_HEADER_TOO_SMALL
@ VLAN_HEADER_TOO_SMALL
Definition: decode-events.h:145
DecodeThreadVars_::counter_vlan_qinq
uint16_t counter_vlan_qinq
Definition: decode.h:698
Packet_
Definition: decode.h:428
DecodeThreadVars_::counter_ieee8021ah
uint16_t counter_ieee8021ah
Definition: decode.h:701
DecodeThreadVars_::counter_vlan
uint16_t counter_vlan
Definition: decode.h:697
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
decode-vlan.h
DecodeVLANRegisterTests
void DecodeVLANRegisterTests(void)
Definition: decode-vlan.c:265
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:403
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:689
packet.h
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:173
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:664
IEEE8021AH_HEADER_TOO_SMALL
@ IEEE8021AH_HEADER_TOO_SMALL
Definition: decode-events.h:149
IEEE8021ahHdr_::c_source
uint8_t c_source[6]
Definition: decode-vlan.c:109
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:895
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:41
GET_VLAN_ID
#define GET_VLAN_ID(vlanh)
Definition: decode-vlan.h:36
DecodeIEEE8021ah
int DecodeIEEE8021ah(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t)
DecodeVLAN
int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-vlan.c:54
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
IEEE8021ahHdr_::c_destination
uint8_t c_destination[6]
Definition: decode-vlan.c:108