"Fossies" - the Fresh Open Source Software Archive

Member "snort3_extra-3.0.3-1/src/codecs/cd_pbb/cd_pbb.cc" (23 Sep 2020, 6931 Bytes) of package /linux/misc/snort3_extra-3.0.3-1.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 and the latest Fossies "Diffs" side-by-side code changes report: 1.0.0-beta2_vs_3.0.3-1.

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