"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