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