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