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,
91  pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN) == false) {
93  return TM_ECODE_FAILED;
94  }
95  return TM_ECODE_OK;
96 }
97 
98 typedef struct IEEE8021ahHdr_ {
99  uint32_t flags;
100  uint8_t c_destination[6];
101  uint8_t c_source[6];
102  uint16_t type; /**< next protocol */
103 } __attribute__((__packed__)) IEEE8021ahHdr;
104 
105 #define IEEE8021AH_HEADER_LEN sizeof(IEEE8021ahHdr)
106 
108  const uint8_t *pkt, uint32_t len)
109 {
110  DEBUG_VALIDATE_BUG_ON(pkt == NULL);
111 
113 
114  if (len < IEEE8021AH_HEADER_LEN) {
116  return TM_ECODE_FAILED;
117  }
118 
119  IEEE8021ahHdr *hdr = (IEEE8021ahHdr *)pkt;
120  const uint16_t next_proto = SCNtohs(hdr->type);
121 
122  DecodeNetworkLayer(tv, dtv, next_proto, p,
124 
125  return TM_ECODE_OK;
126 }
127 
128 #ifdef UNITTESTS
129 #include "util-unittest-helper.h"
130 #include "packet.h"
131 
132 /** \todo Must GRE+VLAN and Multi-Vlan packets to
133  * create more tests
134  */
135 
136 /**
137  * \test DecodeVLANTest01 test if vlan header is too small.
138  *
139  * \retval 1 on success
140  * \retval 0 on failure
141  */
142 static int DecodeVLANtest01 (void)
143 {
144  uint8_t raw_vlan[] = { 0x00, 0x20, 0x08 };
145  Packet *p = PacketGetFromAlloc();
146  if (unlikely(p == NULL))
147  return 0;
148  ThreadVars tv;
150 
151  memset(&tv, 0, sizeof(ThreadVars));
152  memset(&dtv, 0, sizeof(DecodeThreadVars));
153 
154  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
155 
157  SCFree(p);
158  return 1;
159  }
160 
161  SCFree(p);
162  return 0;
163 }
164 
165 /**
166  * \test DecodeVLANTest02 test if vlan header has unknown type.
167  *
168  * \retval 1 on success
169  * \retval 0 on failure
170  */
171 static int DecodeVLANtest02 (void)
172 {
173  uint8_t raw_vlan[] = {
174  0x00, 0x20, 0x01, 0x00, 0x45, 0x00, 0x00, 0x34,
175  0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
176  0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
177  0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
178  0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
179  0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
180  0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
181  Packet *p = PacketGetFromAlloc();
182  if (unlikely(p == NULL))
183  return 0;
184  ThreadVars tv;
186 
187  memset(&tv, 0, sizeof(ThreadVars));
188  memset(&dtv, 0, sizeof(DecodeThreadVars));
189 
190  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
191 
192 
194  SCFree(p);
195  return 1;
196  }
197 
198  SCFree(p);
199  return 0;
200 }
201 
202 /**
203  * \test DecodeVLANTest02 test a good vlan header.
204  *
205  * \retval 1 on success
206  * \retval 0 on failure
207  */
208 static int DecodeVLANtest03 (void)
209 {
210  uint8_t raw_vlan[] = {
211  0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
212  0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
213  0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
214  0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
215  0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
216  0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
217  0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
218  Packet *p = PacketGetFromAlloc();
219  if (unlikely(p == NULL))
220  return 0;
221  ThreadVars tv;
223 
224  memset(&tv, 0, sizeof(ThreadVars));
225  memset(&dtv, 0, sizeof(DecodeThreadVars));
226 
228 
229  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
230 
231 
232  if(p->vlan_id[0] == 0) {
233  goto error;
234  }
235 
237  goto error;
238  }
239 
241  goto error;
242  }
243 
244  PacketRecycle(p);
245  FlowShutdown();
246  SCFree(p);
247  return 1;
248 
249 error:
250  PacketRecycle(p);
251  FlowShutdown();
252  SCFree(p);
253  return 0;
254 }
255 #endif /* UNITTESTS */
256 
258 {
259 #ifdef UNITTESTS
260  UtRegisterTest("DecodeVLANtest01", DecodeVLANtest01);
261  UtRegisterTest("DecodeVLANtest02", DecodeVLANtest02);
262  UtRegisterTest("DecodeVLANtest03", DecodeVLANtest03);
263 #endif /* UNITTESTS */
264 }
265 
266 /**
267  * @}
268  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1146
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:147
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:1161
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:501
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:98
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:145
__attribute__
struct IEEE8021ahHdr_ __attribute__((__packed__))
DNP3 link header.
Definition: decode-vlan.c:103
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:533
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:102
IEEE8021ahHdr_::flags
uint32_t flags
Definition: decode-vlan.c:99
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:966
Packet_
Definition: decode.h:473
DecodeThreadVars_::counter_ieee8021ah
uint16_t counter_ieee8021ah
Definition: decode.h:970
DecodeThreadVars_::counter_vlan
uint16_t counter_vlan
Definition: decode.h:965
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
decode-vlan.h
DecodeVLANRegisterTests
void DecodeVLANRegisterTests(void)
Definition: decode-vlan.c:257
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:414
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:680
packet.h
VLAN_UNKNOWN_TYPE
@ VLAN_UNKNOWN_TYPE
Definition: decode-events.h:146
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:929
DecodeThreadVars_::counter_vlan_qinqinq
uint16_t counter_vlan_qinqinq
Definition: decode.h:967
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:101
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1154
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:500
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:149
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:100