"Fossies" - the Fresh Open Source Software Archive

Member "snort3_extra-3.1.53.0/src/codecs/cd_pflog/cd_pflog.cc" (20 Dec 2022, 6644 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_pflog.cc" see the Fossies "Dox" file reference documentation.

    1 //--------------------------------------------------------------------------
    2 // Copyright (C) 2014-2022 Cisco and/or its affiliates. All rights reserved.
    3 // Copyright (C) 2002-2013 Sourcefire, Inc.
    4 //
    5 // This program is free software; you can redistribute it and/or modify it
    6 // under the terms of the GNU General Public License Version 2 as published
    7 // by the Free Software Foundation.  You may not use, modify or distribute
    8 // this program under any other version of the GNU General Public License.
    9 //
   10 // This program is distributed in the hope that it will be useful, but
   11 // WITHOUT ANY WARRANTY; without even the implied warranty of
   12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13 // General Public License for more details.
   14 //
   15 // You should have received a copy of the GNU General Public License along
   16 // with this program; if not, write to the Free Software Foundation, Inc.,
   17 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   18 //--------------------------------------------------------------------------
   19 
   20 #include <net/if.h>
   21 #include <daq_dlt.h>
   22 
   23 #include "framework/codec.h"
   24 
   25 using namespace snort;
   26 
   27 #define PFLOG_NAME "pflog"
   28 #define PFLOG_HELP_STR "support for OpenBSD PF log"
   29 
   30 #define PFLOG_HELP ADD_DLT(PFLOG_HELP_STR, DLT_PFLOG)
   31 
   32 namespace
   33 {
   34 /*
   35  * Snort supports 3 versions of the OpenBSD pflog header:
   36  *
   37  * Pflog1_Hdr:  CVS = 1.3,   DLT_OLD_PFLOG = 17,  Length = 28
   38  * Pflog2_Hdr:  CVS = 1.8,   DLT_PFLOG     = 117, Length = 48
   39  * Pflog3_Hdr:  CVS = 1.12,  DLT_PFLOG     = 117, Length = 64
   40  * Pflog4_Hdr:  CVS = 1.172, DLT_PFLOG     = 117, Length = 100
   41  *
   42  * Since they have the same DLT, Pflog{2,3,4}Hdr are distinguished
   43  * by their actual length.  The minimum required length excludes
   44  * padding.
   45  */
   46 /* Old OpenBSD pf firewall pflog0 header (information from pf source in kernel)
   47  * the rule, reason, and action codes tell why the firewall dropped it -fleck
   48  */
   49 
   50 class PflogCodec : public Codec
   51 {
   52 public:
   53     PflogCodec() : Codec(PFLOG_NAME) { }
   54 
   55     bool decode(const RawData&, CodecData&, DecodeData&) override;
   56     void get_data_link_type(std::vector<int>&) override;
   57 };
   58 
   59 struct Pflog1Hdr
   60 {
   61     uint32_t af;
   62     char intf[IFNAMSIZ];
   63     int16_t rule;
   64     uint16_t reason;
   65     uint16_t action;
   66     uint16_t dir;
   67 };
   68 
   69 #define PFLOG1_HDRLEN (sizeof(struct _Pflog1_hdr))
   70 
   71 /*
   72  * Note that on OpenBSD, af type is sa_family_t. On Linux, that's an unsigned
   73  * short, but on OpenBSD, that's a uint8_t, so we should explicitly use uint8_t
   74  * here.  - ronaldo
   75  */
   76 
   77 #define PFLOG_RULELEN 16
   78 #define PFLOG_PADLEN  3
   79 
   80 struct Pflog2Hdr
   81 {
   82     int8_t length;
   83     uint8_t af;
   84     uint8_t action;
   85     uint8_t reason;
   86     char ifname[IFNAMSIZ];
   87     char ruleset[PFLOG_RULELEN];
   88     uint32_t rulenr;
   89     uint32_t subrulenr;
   90     uint8_t dir;
   91     uint8_t pad[PFLOG_PADLEN];
   92 };
   93 
   94 #define PFLOG2_HDRLEN (sizeof(Pflog2Hdr))
   95 #define PFLOG2_HDRMIN (PFLOG2_HDRLEN - PFLOG_PADLEN)
   96 
   97 struct Pflog3Hdr
   98 {
   99     int8_t length;
  100     uint8_t af;
  101     uint8_t action;
  102     uint8_t reason;
  103     char ifname[IFNAMSIZ];
  104     char ruleset[PFLOG_RULELEN];
  105     uint32_t rulenr;
  106     uint32_t subrulenr;
  107     uint32_t uid;
  108     uint32_t pid;
  109     uint32_t rule_uid;
  110     uint32_t rule_pid;
  111     uint8_t dir;
  112     uint8_t pad[PFLOG_PADLEN];
  113 };
  114 
  115 #define PFLOG3_HDRLEN (sizeof(Pflog3Hdr))
  116 #define PFLOG3_HDRMIN (PFLOG3_HDRLEN - PFLOG_PADLEN)
  117 
  118 struct Pflog4Hdr
  119 {
  120     uint8_t length;
  121     uint8_t af;
  122     uint8_t action;
  123     uint8_t reason;
  124     char ifname[IFNAMSIZ];
  125     char ruleset[PFLOG_RULELEN];
  126     uint32_t rulenr;
  127     uint32_t subrulenr;
  128     uint32_t uid;
  129     uint32_t pid;
  130     uint32_t rule_uid;
  131     uint32_t rule_pid;
  132     uint8_t dir;
  133     uint8_t rewritten;
  134     uint8_t pad[2];
  135     uint8_t saddr[16];
  136     uint8_t daddr[16];
  137     uint16_t sport;
  138     uint16_t dport;
  139 };
  140 
  141 #define PFLOG4_HDRLEN sizeof(struct Pflog4Hdr)
  142 #define PFLOG4_HDRMIN sizeof(struct Pflog4Hdr)
  143 } // namespace
  144 
  145 void PflogCodec::get_data_link_type(std::vector<int>& v)
  146 { v.push_back(DLT_PFLOG); }
  147 
  148 bool PflogCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
  149 {
  150     const uint32_t cap_len = raw.len;
  151     uint8_t af, pflen;
  152     uint32_t hlen;
  153     uint32_t padlen = PFLOG_PADLEN;
  154 
  155     if (cap_len < PFLOG2_HDRMIN)
  156         return false;
  157 
  158     /* lay the pf header structure over the packet data */
  159     switch (*((const uint8_t*)raw.data))
  160     {
  161     case PFLOG2_HDRMIN:
  162     {
  163         const Pflog2Hdr* const pf2h =
  164             reinterpret_cast<const Pflog2Hdr*>(raw.data);
  165         pflen = pf2h->length;
  166         hlen = PFLOG2_HDRLEN;
  167         af = pf2h->af;
  168         break;
  169     }
  170     case PFLOG3_HDRMIN:
  171     {
  172         const Pflog3Hdr* const pf3h =
  173             reinterpret_cast<const Pflog3Hdr*>(raw.data);
  174         pflen = pf3h->length;
  175         hlen = PFLOG3_HDRLEN;
  176         af = pf3h->af;
  177         break;
  178     }
  179     case PFLOG4_HDRMIN:
  180     {
  181         const Pflog4Hdr* const pf4h =
  182             reinterpret_cast<const Pflog4Hdr*>(raw.data);
  183         pflen = pf4h->length;
  184         hlen = PFLOG4_HDRLEN;
  185         af = pf4h->af;
  186         padlen = sizeof(pf4h->pad);
  187         break;
  188     }
  189     default:
  190         return false;
  191     }
  192 
  193     /* now that we know a little more, do a little more validation */
  194     if (cap_len < hlen)
  195         return false;
  196 
  197     /* note that the pflen may exclude the padding which is always present */
  198     if (pflen < hlen - padlen || pflen > hlen)
  199         return false;
  200 
  201     /* check the network type - should only be AF_INET or AF_INET6 */
  202     switch (af)
  203     {
  204     case AF_INET:       /* IPv4 */
  205         codec.next_prot_id = ProtocolId::ETHERTYPE_IPV4;
  206         break;
  207 
  208     case AF_INET6:      /* IPv6 */
  209         codec.next_prot_id = ProtocolId::ETHERTYPE_IPV6;
  210         break;
  211 
  212     default:
  213         /* FIXIT-L add decoder drop event for unknown pflog network type
  214          * To my knowledge, pflog devices can only
  215          * pass IP and IP6 packets. -fleck
  216          */
  217         break;
  218     }
  219 
  220     codec.lyr_len = hlen;
  221     return true;
  222 }
  223 
  224 //-------------------------------------------------------------------------
  225 // api
  226 //-------------------------------------------------------------------------
  227 
  228 static Codec* ctor(Module*)
  229 { return new PflogCodec(); }
  230 
  231 static void dtor(Codec* cd)
  232 { delete cd; }
  233 
  234 static const CodecApi pflog_api =
  235 {
  236     {
  237         PT_CODEC,
  238         sizeof(CodecApi),
  239         CDAPI_VERSION,
  240         0,
  241         API_RESERVED,
  242         API_OPTIONS,
  243         PFLOG_NAME,
  244         PFLOG_HELP,
  245         nullptr, // mod_ctor
  246         nullptr  // mod_dtor
  247     },
  248     nullptr, // ginit
  249     nullptr, // gterm
  250     nullptr, // tinit
  251     nullptr, // tterm
  252     ctor,
  253     dtor,
  254 };
  255 
  256 SO_PUBLIC const BaseApi* snort_plugins[] =
  257 {
  258     &pflog_api.base,
  259     nullptr
  260 };