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  if (!PacketIncreaseCheckLayers(p)) {
119  return TM_ECODE_FAILED;
120  }
121  IEEE8021ahHdr *hdr = (IEEE8021ahHdr *)pkt;
122  const uint16_t next_proto = SCNtohs(hdr->type);
123 
124  DecodeNetworkLayer(tv, dtv, next_proto, p,
126 
127  return TM_ECODE_OK;
128 }
129 
130 #ifdef UNITTESTS
131 #include "util-unittest-helper.h"
132 #include "packet.h"
133 
134 /** \todo Must GRE+VLAN and Multi-Vlan packets to
135  * create more tests
136  */
137 
138 /**
139  * \test DecodeVLANTest01 test if vlan header is too small.
140  *
141  * \retval 1 on success
142  * \retval 0 on failure
143  */
144 static int DecodeVLANtest01 (void)
145 {
146  uint8_t raw_vlan[] = { 0x00, 0x20, 0x08 };
148  FAIL_IF_NULL(p);
149  ThreadVars tv;
151  memset(&tv, 0, sizeof(ThreadVars));
152  memset(&dtv, 0, sizeof(DecodeThreadVars));
153 
154  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
156 
157  PacketFree(p);
158  PASS;
159 }
160 
161 /**
162  * \test DecodeVLANTest02 test if vlan header has unknown type.
163  *
164  * \retval 1 on success
165  * \retval 0 on failure
166  */
167 static int DecodeVLANtest02 (void)
168 {
169  uint8_t raw_vlan[] = {
170  0x00, 0x20, 0x01, 0x00, 0x45, 0x00, 0x00, 0x34,
171  0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
172  0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
173  0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
174  0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
175  0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
176  0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
178  FAIL_IF_NULL(p);
179  ThreadVars tv;
181  memset(&tv, 0, sizeof(ThreadVars));
182  memset(&dtv, 0, sizeof(DecodeThreadVars));
183 
184  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
185 
187  PacketFree(p);
188  PASS;
189 }
190 
191 /**
192  * \test DecodeVLANTest02 test a good vlan header.
193  *
194  * \retval 1 on success
195  * \retval 0 on failure
196  */
197 static int DecodeVLANtest03 (void)
198 {
199  uint8_t raw_vlan[] = {
200  0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
201  0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
202  0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
203  0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
204  0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
205  0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
206  0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
208  FAIL_IF_NULL(p);
209  ThreadVars tv;
211  memset(&tv, 0, sizeof(ThreadVars));
212  memset(&dtv, 0, sizeof(DecodeThreadVars));
213 
215 
216  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
217 
218  FAIL_IF(p->vlan_id[0] == 0);
221 
222  PacketFree(p);
223  FlowShutdown();
224  PASS;
225 }
226 #endif /* UNITTESTS */
227 
229 {
230 #ifdef UNITTESTS
231  UtRegisterTest("DecodeVLANtest01", DecodeVLANtest01);
232  UtRegisterTest("DecodeVLANtest02", DecodeVLANtest02);
233  UtRegisterTest("DecodeVLANtest03", DecodeVLANtest03);
234 #endif /* UNITTESTS */
235 }
236 
237 /**
238  * @}
239  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1224
len
uint8_t len
Definition: app-layer-dnp3.h:2
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DecodeThreadVars_::counter_vlan_qinqinq
StatsCounterId counter_vlan_qinqinq
Definition: decode.h:1034
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:1237
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
VLAN_UNKNOWN_TYPE
@ VLAN_UNKNOWN_TYPE
Definition: decode-events.h:154
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:542
GET_VLAN_CFI
#define GET_VLAN_CFI(vlanh)
Definition: decode-vlan.h:35
IEEE8021AH_HEADER_LEN
#define IEEE8021AH_HEADER_LEN
VLAN_HEADER_TOO_MANY_LAYERS
@ VLAN_HEADER_TOO_MANY_LAYERS
Definition: decode-events.h:155
proto
uint8_t proto
Definition: decode-template.h:0
IEEE8021ahHdr_
Definition: decode-vlan.c:97
p
Packet * p
Definition: fuzz_iprep.c:21
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
util-unittest.h
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
__attribute__
struct IEEE8021ahHdr_ __attribute__((__packed__))
DNP3 link header.
Definition: decode-vlan.c:102
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:577
decode.h
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
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
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:164
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:225
IEEE8021AH_HEADER_TOO_SMALL
@ IEEE8021AH_HEADER_TOO_SMALL
Definition: decode-events.h:157
DecodeThreadVars_::counter_ieee8021ah
StatsCounterId counter_ieee8021ah
Definition: decode.h:1038
Packet_
Definition: decode.h:514
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:34
decode-vlan.h
DecodeVLANRegisterTests
void DecodeVLANRegisterTests(void)
Definition: decode-vlan.c:228
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:439
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:721
packet.h
VLAN_HEADER_TOO_SMALL
@ VLAN_HEADER_TOO_SMALL
Definition: decode-events.h:153
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:33
DecodeThreadVars_::counter_vlan_qinq
StatsCounterId counter_vlan_qinq
Definition: decode.h:1033
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:264
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:993
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:1232
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:541
DecodeIEEE8021ah
int DecodeIEEE8021ah(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t)
DecodeThreadVars_::counter_vlan
StatsCounterId counter_vlan
Definition: decode.h:1032
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
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:109
IEEE8021ahHdr_::c_destination
uint8_t c_destination[6]
Definition: decode-vlan.c:99