1 //--------------------------------------------------------------------------
2 // Copyright (C) 2020-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation. You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // cd_vxlan.cc author Bhagya Tholpady <bbantwal@cisco.com>
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "framework/codec.h"
25 #include "log/text_log.h"
26 #include "main/snort_config.h"
27 #include "packet_io/active.h"
28
29 using namespace snort;
30
31 #define CD_VXLAN_NAME "vxlan"
32 #define CD_VXLAN_HELP "support for Virtual Extensible LAN"
33
34 namespace
35 {
36 class VxlanCodec : public Codec
37 {
38 public:
VxlanCodec()39 VxlanCodec() : Codec(CD_VXLAN_NAME) { }
40
41 void get_protocol_ids(std::vector<ProtocolId>& v) override;
42 bool decode(const RawData&, CodecData&, DecodeData&) override;
43 void log(TextLog* const, const uint8_t* pkt, const uint16_t len) override;
44 };
45
46 struct VXLANHdr
47 {
48 uint8_t flags;
49 uint8_t reserved_1[3];
50 uint8_t vni[3]; //VXLAN network id
51 uint8_t reserved_2;
52 };
53 constexpr uint16_t VXLAN_MIN_HDR_LEN = 8;
54 } // anonymous namespace
55
get_protocol_ids(std::vector<ProtocolId> & v)56 void VxlanCodec::get_protocol_ids(std::vector<ProtocolId>& v)
57 {
58 v.push_back(ProtocolId::VXLAN);
59 }
60
decode(const RawData & raw,CodecData & codec,DecodeData &)61 bool VxlanCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
62 {
63 if ( raw.len < VXLAN_MIN_HDR_LEN )
64 return false;
65
66 const VXLANHdr* const hdr = reinterpret_cast<const VXLANHdr*>(raw.data);
67
68 if ( hdr->flags != 0x08 )
69 return false;
70
71 if ( codec.conf->tunnel_bypass_enabled(TUNNEL_VXLAN) )
72 codec.tunnel_bypass = true;
73
74 codec.lyr_len = VXLAN_MIN_HDR_LEN;
75 codec.proto_bits |= PROTO_BIT__VXLAN;
76 codec.next_prot_id = ProtocolId::ETHERNET_802_3;
77 codec.codec_flags |= CODEC_NON_IP_TUNNEL;
78
79 return true;
80 }
81
log(TextLog * const text_log,const uint8_t * raw_pkt,const uint16_t)82 void VxlanCodec::log(TextLog* const text_log, const uint8_t* raw_pkt,
83 const uint16_t /*lyr_len*/)
84 {
85 const VXLANHdr* const hdr = reinterpret_cast<const VXLANHdr*>(raw_pkt);
86 uint32_t vni = ( hdr->vni[0] << 16 ) | ( hdr->vni[1] << 8 ) | hdr->vni[2];
87 TextLog_Print(text_log, "network identifier: %u", vni);
88 }
89
90 //-------------------------------------------------------------------------
91 // api
92 //-------------------------------------------------------------------------
93
ctor(Module *)94 static Codec* ctor(Module*)
95 { return new VxlanCodec(); }
96
dtor(Codec * cd)97 static void dtor(Codec* cd)
98 { delete cd; }
99
100 static const CodecApi vxlan_api =
101 {
102 {
103 PT_CODEC,
104 sizeof(CodecApi),
105 CDAPI_VERSION,
106 0,
107 API_RESERVED,
108 API_OPTIONS,
109 CD_VXLAN_NAME,
110 CD_VXLAN_HELP,
111 nullptr,
112 nullptr
113 },
114 nullptr, // pinit
115 nullptr, // pterm
116 nullptr, // tinit
117 nullptr, // tterm
118 ctor, // ctor
119 dtor, // dtor
120 };
121
122 #ifdef BUILDING_SO
123 SO_PUBLIC const BaseApi* snort_plugins[] =
124 #else
125 const BaseApi* cd_vxlan[] =
126 #endif
127 {
128 &vxlan_api.base,
129 nullptr
130 };
131
132