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  }
75  if (p->vlan_idx > VLAN_MAX_LAYER_IDX) {
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 
97 typedef 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;
103 
104 #define IEEE8021AH_HEADER_LEN sizeof(IEEE8021ahHdr)
105 
107  const uint8_t *pkt, uint32_t len)
108 {
109  DEBUG_VALIDATE_BUG_ON(pkt == NULL);
110 
112 
113  if (len < IEEE8021AH_HEADER_LEN) {
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  */
141 static int DecodeVLANtest01 (void)
142 {
143  uint8_t raw_vlan[] = { 0x00, 0x20, 0x08 };
144  Packet *p = PacketGetFromAlloc();
145  if (unlikely(p == NULL))
146  return 0;
147  ThreadVars tv;
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  */
170 static 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};
180  Packet *p = PacketGetFromAlloc();
181  if (unlikely(p == NULL))
182  return 0;
183  ThreadVars tv;
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  */
207 static 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};
217  Packet *p = PacketGetFromAlloc();
218  if (unlikely(p == NULL))
219  return 0;
220  ThreadVars tv;
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 
248 error:
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  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1150
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:166
VLAN_HEADER_TOO_MANY_LAYERS
@ VLAN_HEADER_TOO_MANY_LAYERS
Definition: decode-events.h:148
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:1163
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:143
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:504
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:97
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
util-unittest.h
util-unittest-helper.h
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
VLAN_HEADER_TOO_SMALL
@ VLAN_HEADER_TOO_SMALL
Definition: decode-events.h:146
__attribute__
struct IEEE8021ahHdr_ __attribute__((__packed__))
DNP3 link header.
Definition: decode-vlan.c:102
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:518
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:46
IEEE8021ahHdr_::type
uint16_t type
Definition: decode-vlan.c:101
IEEE8021ahHdr_::flags
uint32_t flags
Definition: decode-vlan.c:98
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
GET_VLAN_PROTO
#define GET_VLAN_PROTO(vlanh)
Definition: decode-vlan.h:37
DecodeThreadVars_::counter_vlan_qinq
uint16_t counter_vlan_qinq
Definition: decode.h:970
Packet_
Definition: decode.h:476
DecodeThreadVars_::counter_ieee8021ah
uint16_t counter_ieee8021ah
Definition: decode.h:974
DecodeThreadVars_::counter_vlan
uint16_t counter_vlan
Definition: decode.h:969
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
decode-vlan.h
DecodeVLANRegisterTests
void DecodeVLANRegisterTests(void)
Definition: decode-vlan.c:256
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:423
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:665
packet.h
VLAN_UNKNOWN_TYPE
@ VLAN_UNKNOWN_TYPE
Definition: decode-events.h:147
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:932
DecodeThreadVars_::counter_vlan_qinqinq
uint16_t counter_vlan_qinqinq
Definition: decode.h:971
VLAN_MAX_LAYER_IDX
#define VLAN_MAX_LAYER_IDX
Definition: decode-vlan.h:52
IEEE8021ahHdr_::c_source
uint8_t c_source[6]
Definition: decode-vlan.c:100
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1158
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
GET_VLAN_ID
#define GET_VLAN_ID(vlanh)
Definition: decode-vlan.h:36
Packet_::vlan_id
uint16_t vlan_id[VLAN_MAX_LAYERS]
Definition: decode.h:503
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
IEEE8021AH_HEADER_TOO_SMALL
@ IEEE8021AH_HEADER_TOO_SMALL
Definition: decode-events.h:150
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
IEEE8021ahHdr_::c_destination
uint8_t c_destination[6]
Definition: decode-vlan.c:99