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  FAIL_IF_NULL(p);
146  ThreadVars tv;
148  memset(&tv, 0, sizeof(ThreadVars));
149  memset(&dtv, 0, sizeof(DecodeThreadVars));
150 
151  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
153 
154  PacketFree(p);
155  PASS;
156 }
157 
158 /**
159  * \test DecodeVLANTest02 test if vlan header has unknown type.
160  *
161  * \retval 1 on success
162  * \retval 0 on failure
163  */
164 static int DecodeVLANtest02 (void)
165 {
166  uint8_t raw_vlan[] = {
167  0x00, 0x20, 0x01, 0x00, 0x45, 0x00, 0x00, 0x34,
168  0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
169  0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
170  0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
171  0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
172  0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
173  0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
174  Packet *p = PacketGetFromAlloc();
175  FAIL_IF_NULL(p);
176  ThreadVars tv;
178  memset(&tv, 0, sizeof(ThreadVars));
179  memset(&dtv, 0, sizeof(DecodeThreadVars));
180 
181  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
182 
184  PacketFree(p);
185  PASS;
186 }
187 
188 /**
189  * \test DecodeVLANTest02 test a good vlan header.
190  *
191  * \retval 1 on success
192  * \retval 0 on failure
193  */
194 static int DecodeVLANtest03 (void)
195 {
196  uint8_t raw_vlan[] = {
197  0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
198  0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9,
199  0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15,
200  0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55,
201  0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50,
202  0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a,
203  0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3};
204  Packet *p = PacketGetFromAlloc();
205  FAIL_IF_NULL(p);
206  ThreadVars tv;
208  memset(&tv, 0, sizeof(ThreadVars));
209  memset(&dtv, 0, sizeof(DecodeThreadVars));
210 
212 
213  DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan));
214 
215  FAIL_IF(p->vlan_id[0] == 0);
218 
219  PacketFree(p);
220  FlowShutdown();
221  PASS;
222 }
223 #endif /* UNITTESTS */
224 
226 {
227 #ifdef UNITTESTS
228  UtRegisterTest("DecodeVLANtest01", DecodeVLANtest01);
229  UtRegisterTest("DecodeVLANtest02", DecodeVLANtest02);
230  UtRegisterTest("DecodeVLANtest03", DecodeVLANtest03);
231 #endif /* UNITTESTS */
232 }
233 
234 /**
235  * @}
236  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1188
len
uint8_t len
Definition: app-layer-dnp3.h:2
VLAN_HEADER_TOO_MANY_LAYERS
@ VLAN_HEADER_TOO_MANY_LAYERS
Definition: decode-events.h:154
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
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:1201
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:529
VLAN_HEADER_TOO_SMALL
@ VLAN_HEADER_TOO_SMALL
Definition: decode-events.h:152
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: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:547
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
IEEE8021AH_HEADER_TOO_SMALL
@ IEEE8021AH_HEADER_TOO_SMALL
Definition: decode-events.h:156
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
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:219
DecodeThreadVars_::counter_vlan_qinq
uint16_t counter_vlan_qinq
Definition: decode.h:1002
Packet_
Definition: decode.h:501
DecodeThreadVars_::counter_ieee8021ah
uint16_t counter_ieee8021ah
Definition: decode.h:1007
DecodeThreadVars_::counter_vlan
uint16_t counter_vlan
Definition: decode.h:1001
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
decode-vlan.h
DecodeVLANRegisterTests
void DecodeVLANRegisterTests(void)
Definition: decode-vlan.c:225
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:431
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:691
packet.h
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:258
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:963
DecodeThreadVars_::counter_vlan_qinqinq
uint16_t counter_vlan_qinqinq
Definition: decode.h:1003
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:1196
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:528
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
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
VLAN_UNKNOWN_TYPE
@ VLAN_UNKNOWN_TYPE
Definition: decode-events.h:153
IEEE8021ahHdr_::c_destination
uint8_t c_destination[6]
Definition: decode-vlan.c:99