suricata
decode-vlan.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2022 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 else if (p->vlan_idx == 2)
67
68 if(len < VLAN_HEADER_LEN) {
70 return TM_ECODE_FAILED;
71 }
72 if (!PacketIncreaseCheckLayers(p)) {
73 return TM_ECODE_FAILED;
74 }
77 return TM_ECODE_FAILED;
78 }
79
80 VLANHdr *vlan_hdr = (VLANHdr *)pkt;
81
82 proto = GET_VLAN_PROTO(vlan_hdr);
83
84 SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRIu32 "",
85 p, pkt, proto, GET_VLAN_PRIORITY(vlan_hdr), GET_VLAN_CFI(vlan_hdr),
86 GET_VLAN_ID(vlan_hdr), len);
87
88 p->vlan_id[p->vlan_idx++] = (uint16_t)GET_VLAN_ID(vlan_hdr);
89
90 if (!DecodeNetworkLayer(tv, dtv, proto, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN)) {
92 return TM_ECODE_FAILED;
93 }
94 return TM_ECODE_OK;
95}
96
97typedef struct IEEE8021ahHdr_ {
98 uint32_t flags;
99 uint8_t c_destination[6];
100 uint8_t c_source[6];
101 uint16_t type; /**< next protocol */
102} __attribute__((__packed__)) IEEE8021ahHdr;
104#define IEEE8021AH_HEADER_LEN sizeof(IEEE8021ahHdr)
107 const uint8_t *pkt, uint32_t len)
108{
109 DEBUG_VALIDATE_BUG_ON(pkt == NULL);
110
112
115 return TM_ECODE_FAILED;
116 }
117
118 IEEE8021ahHdr *hdr = (IEEE8021ahHdr *)pkt;
119 const uint16_t next_proto = SCNtohs(hdr->type);
120
121 DecodeNetworkLayer(tv, dtv, next_proto, p,
123
124 return TM_ECODE_OK;
125}
126
127#ifdef UNITTESTS
128#include "util-unittest-helper.h"
129#include "packet.h"
130
131/** \todo Must GRE+VLAN and Multi-Vlan packets to
132 * create more tests
133 */
134
135/**
136 * \test DecodeVLANTest01 test if vlan header is too small.
137 *
138 * \retval 1 on success
139 * \retval 0 on failure
140 */
141static int DecodeVLANtest01 (void)
142{
143 uint8_t raw_vlan[] = { 0x00, 0x20, 0x08 };
145 if (unlikely(p == NULL))
146 return 0;
149
150 memset(&tv, 0, sizeof(ThreadVars));
151 memset(&dtv, 0, sizeof(DecodeThreadVars));
152
153 DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
154
156 SCFree(p);
157 return 1;
158 }
159
160 SCFree(p);
161 return 0;
162}
163
164/**
165 * \test DecodeVLANTest02 test if vlan header has unknown type.
166 *
167 * \retval 1 on success
168 * \retval 0 on failure
169 */
170static int DecodeVLANtest02 (void)
171{
172 uint8_t raw_vlan[] = {
173 0x00, 0x20, 0x01, 0x00, 0x45, 0x00, 0x00, 0x34,
174 0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
175 0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
176 0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
177 0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
178 0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
179 0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
181 if (unlikely(p == NULL))
182 return 0;
185
186 memset(&tv, 0, sizeof(ThreadVars));
187 memset(&dtv, 0, sizeof(DecodeThreadVars));
188
189 DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
190
191
193 SCFree(p);
194 return 1;
195 }
196
197 SCFree(p);
198 return 0;
199}
200
201/**
202 * \test DecodeVLANTest02 test a good vlan header.
203 *
204 * \retval 1 on success
205 * \retval 0 on failure
206 */
207static int DecodeVLANtest03 (void)
208{
209 uint8_t raw_vlan[] = {
210 0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
211 0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
212 0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
213 0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
214 0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
215 0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
216 0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
218 if (unlikely(p == NULL))
219 return 0;
222
223 memset(&tv, 0, sizeof(ThreadVars));
224 memset(&dtv, 0, sizeof(DecodeThreadVars));
225
227
228 DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
229
230
231 if(p->vlan_id[0] == 0) {
232 goto error;
233 }
234
236 goto error;
237 }
238
240 goto error;
241 }
242
243 PacketRecycle(p);
244 FlowShutdown();
245 SCFree(p);
246 return 1;
247
248error:
249 PacketRecycle(p);
250 FlowShutdown();
251 SCFree(p);
252 return 0;
253}
254#endif /* UNITTESTS */
255
257{
258#ifdef UNITTESTS
259 UtRegisterTest("DecodeVLANtest01", DecodeVLANtest01);
260 UtRegisterTest("DecodeVLANtest02", DecodeVLANtest02);
261 UtRegisterTest("DecodeVLANtest03", DecodeVLANtest03);
262#endif /* UNITTESTS */
263}
264
265/**
266 * @}
267 */
uint8_t len
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition counters.c:166
@ VLAN_HEADER_TOO_SMALL
@ VLAN_UNKNOWN_TYPE
@ IEEE8021AH_HEADER_TOO_SMALL
@ VLAN_HEADER_TOO_MANY_LAYERS
uint8_t proto
void DecodeVLANRegisterTests(void)
int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition decode-vlan.c:54
#define IEEE8021AH_HEADER_LEN
#define VLAN_MAX_LAYER_IDX
Definition decode-vlan.h:52
#define VLAN_HEADER_LEN
Definition decode-vlan.h:46
#define GET_VLAN_CFI(vlanh)
Definition decode-vlan.h:35
#define GET_VLAN_PROTO(vlanh)
Definition decode-vlan.h:37
#define GET_VLAN_PRIORITY(vlanh)
Definition decode-vlan.h:34
#define GET_VLAN_ID(vlanh)
Definition decode-vlan.h:36
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition decode.h:1194
#define ENGINE_ISSET_EVENT(p, e)
Definition decode.h:1199
int DecodeIEEE8021ah(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t)
#define ENGINE_SET_EVENT(p, e)
Definition decode.h:1186
struct PrefilterEngineFlowbits __attribute__
DNP3 application header.
void FlowInitConfig(bool quiet)
initialize the configuration
Definition flow.c:547
void FlowShutdown(void)
shutdown the flow engine
Definition flow.c:691
#define FLOW_QUIET
Definition flow.h:43
DecodeThreadVars * dtv
ThreadVars * tv
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition decode.c:258
void PacketRecycle(Packet *p)
Definition packet.c:150
Structure to hold thread specific data for all decode modules.
Definition decode.h:963
uint16_t counter_vlan_qinqinq
Definition decode.h:1003
uint16_t counter_ieee8021ah
Definition decode.h:1006
uint16_t counter_vlan_qinq
Definition decode.h:1002
uint16_t counter_vlan
Definition decode.h:1001
uint8_t c_source[6]
uint8_t c_destination[6]
Definition decode-vlan.c:99
uint32_t flags
Definition decode-vlan.c:98
uint16_t vlan_id[VLAN_MAX_LAYERS]
Definition decode.h:528
uint8_t vlan_idx
Definition decode.h:529
Per thread variable structure.
Definition threadvars.h:58
#define SCNtohs(x)
@ TM_ECODE_FAILED
@ TM_ECODE_OK
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)
#define DEBUG_VALIDATE_BUG_ON(exp)