1 /* Copyright (C) 2020 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 Victor Julien <victor@inliniac.net>
29 *
30 * Decodes ERSPAN Types I and II
31 */
32
33 #include "suricata-common.h"
34 #include "suricata.h"
35 #include "decode.h"
36 #include "decode-events.h"
37 #include "decode-erspan.h"
38
39 #include "util-unittest.h"
40 #include "util-debug.h"
41
42 /**
43 * \brief Functions to decode ERSPAN Type I and II packets
44 */
45
46 /*
47 * \brief ERSPAN Type I was configurable in 5.0.x but is no longer configurable.
48 *
49 * Issue a warning if a configuration setting is found.
50 */
DecodeERSPANConfig(void)51 void DecodeERSPANConfig(void)
52 {
53 int enabled = 0;
54 if (ConfGetBool("decoder.erspan.typeI.enabled", &enabled) == 1) {
55 SCLogWarning(SC_WARN_ERSPAN_CONFIG,
56 "ERSPAN Type I is no longer configurable and it is always"
57 " enabled; ignoring configuration setting.");
58 }
59 }
60
61 /**
62 * \brief ERSPAN Type I
63 */
DecodeERSPANTypeI(ThreadVars * tv,DecodeThreadVars * dtv,Packet * p,const uint8_t * pkt,uint32_t len)64 int DecodeERSPANTypeI(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
65 const uint8_t *pkt, uint32_t len)
66 {
67 StatsIncr(tv, dtv->counter_erspan);
68
69 return DecodeEthernet(tv, dtv, p, pkt, len);
70 }
71
72 /**
73 * \brief ERSPAN Type II
74 */
DecodeERSPAN(ThreadVars * tv,DecodeThreadVars * dtv,Packet * p,const uint8_t * pkt,uint32_t len)75 int DecodeERSPAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
76 {
77 StatsIncr(tv, dtv->counter_erspan);
78
79 if (len < sizeof(ErspanHdr)) {
80 ENGINE_SET_EVENT(p,ERSPAN_HEADER_TOO_SMALL);
81 return TM_ECODE_FAILED;
82 }
83 if (!PacketIncreaseCheckLayers(p)) {
84 return TM_ECODE_FAILED;
85 }
86
87 const ErspanHdr *ehdr = (const ErspanHdr *)pkt;
88 uint16_t version = SCNtohs(ehdr->ver_vlan) >> 12;
89 uint16_t vlan_id = SCNtohs(ehdr->ver_vlan) & 0x0fff;
90
91 SCLogDebug("ERSPAN: version %u vlan %u", version, vlan_id);
92
93 /* only v1 is tested at this time */
94 if (version != 1) {
95 ENGINE_SET_EVENT(p,ERSPAN_UNSUPPORTED_VERSION);
96 return TM_ECODE_FAILED;
97 }
98
99 if (vlan_id > 0) {
100 if (p->vlan_idx >= 2) {
101 ENGINE_SET_EVENT(p,ERSPAN_TOO_MANY_VLAN_LAYERS);
102 return TM_ECODE_FAILED;
103 }
104 p->vlan_id[p->vlan_idx] = vlan_id;
105 p->vlan_idx++;
106 }
107
108 return DecodeEthernet(tv, dtv, p, pkt + sizeof(ErspanHdr), len - sizeof(ErspanHdr));
109 }
110
111 /**
112 * @}
113 */
114