"Fossies" - the Fresh Open Source Software Archive 
Member "snort3_extra-3.1.53.0/src/codecs/cd_pbb/cd_pbb.cc" (20 Dec 2022, 6905 Bytes) of package /linux/misc/snort3_extra-3.1.53.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "cd_pbb.cc" see the
Fossies "Dox" file reference documentation.
1 //--------------------------------------------------------------------------
2 // Copyright (C) 2017-2022 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
19 // cd_pbb.cc author Russ Combs <rucombs@cisco.com>
20
21 #include <daq_dlt.h>
22
23 #include "codecs/codec_module.h"
24 #include "framework/codec.h"
25 #include "log/text_log.h"
26 #include "main/snort_config.h"
27 #include "protocols/packet_manager.h"
28
29 using namespace snort;
30
31 #define CD_PBB_NAME "pbb"
32 #define CD_PBB_HELP "support for 802.1ah protocol"
33
34 #define ETHERTYPE_8021AH 0x88E7
35
36 namespace
37 {
38 struct PbbHdr
39 {
40 uint32_t i_sid;
41 uint8_t ether_dst[6];
42 uint8_t ether_src[6];
43 uint16_t ether_type;
44
45 inline ProtocolId ethertype() const
46 { return (ProtocolId)ntohs(ether_type); }
47 } __attribute__((__packed__));
48
49 static const RuleMap pbb_rules[] =
50 {
51 // FIXIT-H need own gid
52 { DECODE_ETH_HDR_TRUNC, "truncated ethernet header" },
53 { 0, nullptr }
54 };
55
56 class PbbModule : public BaseCodecModule
57 {
58 public:
59 PbbModule() : BaseCodecModule(CD_PBB_NAME, CD_PBB_HELP) { }
60
61 const RuleMap* get_rules() const override
62 { return pbb_rules; }
63 };
64
65 class PbbCodec : public Codec
66 {
67 public:
68 PbbCodec() : Codec(CD_PBB_NAME) { }
69
70 void get_protocol_ids(std::vector<ProtocolId>&) override;
71 void log(TextLog* const, const uint8_t* pkt, const uint16_t len) override;
72 bool decode(const RawData&, CodecData&, DecodeData&) override;
73 bool encode(const uint8_t* const raw_in, const uint16_t raw_len,
74 EncState&, Buffer&, Flow*) override;
75 void format(bool reverse, uint8_t* raw_pkt, DecodeData& snort) override;
76 void update(const ip::IpApi&, const EncodeFlags, uint8_t* raw_pkt,
77 uint16_t lyr_len, uint32_t& updated_len) override;
78 };
79 } // namespace
80
81 void PbbCodec::get_protocol_ids(std::vector<ProtocolId>& v)
82 {
83 v.push_back((ProtocolId)ETHERTYPE_8021AH);
84 }
85
86 bool PbbCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
87 {
88 if (raw.len < sizeof(PbbHdr))
89 {
90 codec_event(codec, DECODE_ETH_HDR_TRUNC);
91 return false;
92 }
93
94 const PbbHdr* pbb = reinterpret_cast<const PbbHdr*>(raw.data);
95
96 ProtocolId next_prot = pbb->ethertype();
97
98 codec.proto_bits |= PROTO_BIT__ETH;
99 codec.lyr_len = sizeof(PbbHdr);
100 codec.next_prot_id = next_prot;
101
102 return true;
103 }
104
105 void PbbCodec::log(TextLog* const text_log, const uint8_t* raw_pkt,
106 const uint16_t len)
107 {
108 const PbbHdr* pbb = reinterpret_cast<const PbbHdr*>(raw_pkt);
109
110 /* src addr */
111 TextLog_Print(text_log, "%02X:%02X:%02X:%02X:%02X:%02X -> ", pbb->ether_src[0],
112 pbb->ether_src[1], pbb->ether_src[2], pbb->ether_src[3],
113 pbb->ether_src[4], pbb->ether_src[5]);
114
115 /* dest addr */
116 TextLog_Print(text_log, "%02X:%02X:%02X:%02X:%02X:%02X", pbb->ether_dst[0],
117 pbb->ether_dst[1], pbb->ether_dst[2], pbb->ether_dst[3],
118 pbb->ether_dst[4], pbb->ether_dst[5]);
119
120 TextLog_Print(text_log, " len:%hu", len);
121 TextLog_Print(text_log, " type:0x%04X", static_cast<uint16_t>(pbb->ethertype()));
122 }
123
124 //-------------------------------------------------------------------------
125 // ethernet
126 //-------------------------------------------------------------------------
127
128 bool PbbCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/,
129 EncState& enc, Buffer& buf, Flow*)
130 {
131 const PbbHdr* hi = reinterpret_cast<const PbbHdr*>(raw_in);
132
133 // not raw ip -> encode layer 2
134 bool raw = ( enc.flags & ENC_FLAG_RAW );
135
136 if ( !raw || (buf.size() != 0) )
137 {
138 // we get here for outer-most layer when not raw ip
139 // we also get here for any encapsulated ethernet layer.
140 if ( !buf.allocate(sizeof(PbbHdr)) )
141 return false;
142
143 PbbHdr* ho = reinterpret_cast<PbbHdr*>(buf.data());
144 ho->ether_type = enc.ethertype_set() ?
145 htons(to_utype(enc.next_ethertype)) : hi->ether_type;
146
147 if ( enc.forward() )
148 {
149 memcpy(ho->ether_src, hi->ether_src, sizeof(ho->ether_src));
150
151 if ( SnortConfig::get_conf()->eth_dst )
152 memcpy(ho->ether_dst, SnortConfig::get_conf()->eth_dst, sizeof(ho->ether_dst));
153 else
154 memcpy(ho->ether_dst, hi->ether_dst, sizeof(ho->ether_dst));
155 }
156 else
157 {
158 memcpy(ho->ether_src, hi->ether_dst, sizeof(ho->ether_src));
159
160 if ( SnortConfig::get_conf()->eth_dst )
161 memcpy(ho->ether_dst, SnortConfig::get_conf()->eth_dst, sizeof(ho->ether_dst));
162 else
163 memcpy(ho->ether_dst, hi->ether_src, sizeof(ho->ether_dst));
164 }
165 }
166
167 enc.next_ethertype = ProtocolId::ETHERTYPE_NOT_SET;
168 enc.next_proto = IpProtocol::PROTO_NOT_SET;
169 return true;
170 }
171
172 void PbbCodec::format(bool reverse, uint8_t* raw_pkt, DecodeData&)
173 {
174 PbbHdr* ch = reinterpret_cast<PbbHdr*>(raw_pkt);
175
176 if ( reverse )
177 {
178 uint8_t tmp_addr[6];
179
180 memcpy(tmp_addr, ch->ether_dst, sizeof(ch->ether_dst));
181 memcpy(ch->ether_dst, ch->ether_src, sizeof(ch->ether_src));
182 memcpy(ch->ether_src, tmp_addr, sizeof(ch->ether_src));
183 }
184 }
185
186 void PbbCodec::update(const ip::IpApi&, const EncodeFlags, uint8_t*,
187 uint16_t lyr_len, uint32_t& updated_len)
188 {
189 updated_len += lyr_len;
190 }
191
192 //-------------------------------------------------------------------------
193 // api
194 //-------------------------------------------------------------------------
195
196 static Module* mod_ctor()
197 { return new PbbModule; }
198
199 static void mod_dtor(Module* m)
200 { delete m; }
201
202 static Codec* ctor(Module*)
203 { return new PbbCodec(); }
204
205 static void dtor(Codec* cd)
206 { delete cd; }
207
208 static const CodecApi pbb_api =
209 {
210 {
211 PT_CODEC,
212 sizeof(CodecApi),
213 CDAPI_VERSION,
214 0,
215 API_RESERVED,
216 API_OPTIONS,
217 CD_PBB_NAME,
218 CD_PBB_HELP,
219 mod_ctor,
220 mod_dtor,
221 },
222 nullptr, // pinit
223 nullptr, // pterm
224 nullptr, // tinit
225 nullptr, // tterm
226 ctor, // ctor
227 dtor, // dtor
228 };
229
230 SO_PUBLIC const BaseApi* snort_plugins[] =
231 {
232 &pbb_api.base,
233 nullptr
234 };
235