]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
ading i4l_rawip and pflog roto codecs
authorJosh <jrosenba@cisco.com>
Thu, 11 Dec 2014 18:03:52 +0000 (12:03 -0600)
committerJosh <jrosenba@cisco.com>
Thu, 11 Dec 2014 18:03:52 +0000 (12:03 -0600)
src/codecs/codec_api.cc
src/codecs/root/CMakeLists.txt
src/codecs/root/Makefile.am
src/codecs/root/cd_i4l_rawip.cc
src/codecs/root/cd_pflog.cc [new file with mode: 0644]

index 06e4fdad81b7e46cc30820567d6ee96ba28bec29..bca940a2142165c7156d5955552b9d26eb341121 100644 (file)
@@ -69,14 +69,17 @@ extern const BaseApi* cd_transbridge;
 extern const BaseApi* cd_udp;
 extern const BaseApi* cd_vlan;
 
+
 //  Root codecs
-extern const BaseApi* cd_eth;
-extern const BaseApi* cd_raw4;
-extern const BaseApi* cd_raw6;
-extern const BaseApi* cd_null;
 extern const BaseApi* cd_eapol;
+extern const BaseApi* cd_eth;
+extern const BaseApi* cd_i4l_rawip;
 extern const BaseApi* cd_linux_sll;
+extern const BaseApi* cd_null;
+extern const BaseApi* cd_pflog;
 extern const BaseApi* cd_ppp;
+extern const BaseApi* cd_raw4;
+extern const BaseApi* cd_raw6;
 extern const BaseApi* cd_wlan;
 
 #endif
@@ -122,13 +125,15 @@ const BaseApi* codecs[] =
     cd_vlan,
 
     /* root codecs */
-    cd_eth,
-    cd_raw4,
-    cd_raw6,
-    cd_null,
     cd_eapol,
+    cd_eth,
+    cd_i4l_rawip,
     cd_linux_sll,
+    cd_null,
+    cd_pflog,
     cd_ppp,
+    cd_raw4,
+    cd_raw6,
     cd_wlan,
 #endif
 
index b251601d17d65d8c6f778ad8e68a6b1b6be6a680..1f63640d4ac0bb774cb4e56049d522c25bda5a42 100644 (file)
@@ -2,8 +2,10 @@
 if (STATIC_CODECS)
     set (PLUGIN_LIST
         cd_eth.cc
+        cd_i4l_rawip.cc
         cd_linux_sll.cc
         cd_null.cc
+        cd_pflog.cc
         cd_ppp.cc
         cd_raw4.cc
         cd_raw6.cc
@@ -13,7 +15,6 @@ if (STATIC_CODECS)
 #        cd_i4lrawip.cc
 #        cd_oldpflog.cc
 #        cd_enc.cc
-#        cd_pflog.cc
 #        cd_pppserial.cc
 #        cd_chdlc.cc
 #        cd_i4lciscoip.cc
@@ -24,8 +25,10 @@ if (STATIC_CODECS)
 
 else (STATIC_CODECS)
     add_shared_library (cd_eth codecs cd_eth.cc)
+    add_shared_library (cd_i4l_rawip codecs cd_i4l_rawip.cc)
     add_shared_library (cd_linux_sll codecs cd_linux_sll.cc)
     add_shared_library (cd_null codecs cd_null.cc)
+    add_shared_library (cd_pflog codecs cd_pflog.cc)
     add_shared_library (cd_ppp codecs cd_ppp.cc)
     add_shared_library (cd_raw4 codecs cd_raw4.cc)
     add_shared_library (cd_raw6 codecs cd_raw6.cc)
index 06e7780982ccc5c27d71b19577cd76cb49b2b942..84b7625f42024dea60794a6e9e7fda8786c2b9c3 100644 (file)
@@ -5,8 +5,10 @@ noinst_LIBRARIES = libroot_codecs.a
 
 libroot_codecs_a_SOURCES = \
 cd_eth.cc \
+cd_i4l_rawip.cc \
 cd_linux_sll.cc \
 cd_null.cc \
+cd_pflog.cc \
 cd_ppp.cc \
 cd_raw4.cc \
 cd_raw6.cc \
@@ -31,6 +33,11 @@ libcd_eth_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
 libcd_eth_la_LDFLAGS = -export-dynamic -shared
 libcd_eth_la_SOURCES =  cd_eth.cc
 
+ehlib_LTLIBRARIES += libcd_i4l_rawip.la
+libcd_i4l_rawip_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+libcd_i4l_rawip_la_LDFLAGS = -export-dynamic -shared
+libcd_i4l_rawip_la_SOURCES =  cd_i4l_rawip.cc
+
 ehlib_LTLIBRARIES += libcd_linux_sll.la
 libcd_linux_sll_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
 libcd_linux_sll_la_LDFLAGS = -export-dynamic -shared
@@ -41,6 +48,11 @@ libcd_null_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
 libcd_null_la_LDFLAGS = -export-dynamic -shared
 libcd_null_la_SOURCES =  cd_null.cc
 
+ehlib_LTLIBRARIES += libcd_pflog.la
+libcd_pflog_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+libcd_pflog_la_LDFLAGS = -export-dynamic -shared
+libcd_pflog_la_SOURCES =  cd_pflog.cc
+
 ehlib_LTLIBRARIES += libcd_ppp.la
 libcd_ppp_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
 libcd_ppp_la_LDFLAGS = -export-dynamic -shared
index 1b6cf3ef70fcf925b600088e262dd02127a13f6f..4431cf8b8155f7a7134003d48cc2e573242dff4c 100644 (file)
 #include "framework/codec.h"
 
 
-#ifdef DLT_I4L_RAWIP
 
-#define I4L_RAW_IP_NAME "i4l_rawip"
-#define I4L_RAW_IP_HELP_STR "support for I4L IP"
-#define I4L_RAW_IP_HELP ADD_DLT(I4L_RAW_IP_HELP_STR, DLT_I4L_RAWIP)
+#define I4L_RAWIP_NAME "i4l_rawip"
+#define I4L_RAWIP_HELP_STR "support for I4L IP"
+
+
+#ifdef DLT_I4L_RAWIP
+#define I4L_RAWIP_HELP ADD_DLT(I4L_RAWIP_HELP_STR, DLT_I4L_RAWIP)
+#else
+#define I4L_RAWIP_HELP I4L_RAWIP_HELP_STR
+#endif
 
 namespace
 {
@@ -40,7 +45,7 @@ namespace
 class I4LRawIpCodec : public Codec
 {
 public:
-    I4LRawIpCodec() : Codec(I4L_RAW_IP_NAME){};
+    I4LRawIpCodec() : Codec(I4L_RAWIP_NAME){};
     ~I4LRawIpCodec() {};
 
     void get_data_link_type(std::vector<int>&) override;
@@ -50,24 +55,16 @@ public:
 
 } // namespace
 
-
+#ifdef DLT_I4L_RAWIP
 void I4LRawIpCodec::get_data_link_type(std::vector<int>& v)
 { v.push_back(DLT_I4L_RAWIP); }
 
-/*
- * Function: DecodeI4LRawIPPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*)
- *
- * Purpose: Decodes packets coming in raw on layer 2, like PPP.  Coded and
- *          in by Jed Pickle (thanks Jed!) and modified for a few little tweaks
- *          by me.
- *
- * Arguments: p => pointer to decoded packet struct
- *            user => Utility pointer, unused
- *            pkthdr => ptr to the packet header
- *            pkt => pointer to the real live packet data
- *
- * Returns: void function
- */
+#else
+void I4LRawIpCodec::get_data_link_type(std::vector<int>& v)
+{ }
+
+#endif
+
 
 bool I4LRawIpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
 {
@@ -92,12 +89,12 @@ static void dtor(Codec *cd)
 { delete cd; }
 
 
-static const CodecApi i4l_raw_ip_api =
+static const CodecApi i4l_rawip_api =
 {
     {
         PT_CODEC,
-        I4L_RAW_IP_NAME,
-        I4L_RAW_IP_HELP,
+        I4L_RAWIP_NAME,
+        I4L_RAWIP_HELP,
         CDAPI_PLUGIN_V0,
         0,
         nullptr, // mod_ctor
@@ -115,11 +112,9 @@ static const CodecApi i4l_raw_ip_api =
 #ifdef BUILDING_SO
 SO_PUBLIC const BaseApi* snort_plugins[] =
 {
-    &i4l_raw_ip_api.base,
+    &i4l_rawip_api.base,
     nullptr
 };
 #else
-const BaseApi* cd_name = &i4l_raw_ip_api.base;
+const BaseApi* cd_i4l_rawip = &i4l_rawip_api.base;
 #endif
-
-#endif /* DLT_I4L_RAWIP */
diff --git a/src/codecs/root/cd_pflog.cc b/src/codecs/root/cd_pflog.cc
new file mode 100644 (file)
index 0000000..046241f
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+** Copyright (C) 2002-2013 Sourcefire, Inc.
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <pcap.h>
+#include "framework/codec.h"
+
+
+#ifndef DLT_PFLOG
+#define DLT_PFLOG 117
+#endif
+
+#define PFLOG_NAME "pflog"
+#define PFLOG_HELP_STR "support for OpenBSD PF log"
+
+
+#define PFLOG_HELP ADD_DLT(PFLOG_HELP_STR, DLT_PFLOG)
+
+
+
+namespace
+{
+
+/*
+ * Snort supports 3 versions of the OpenBSD pflog header:
+ *
+ * Pflog1_Hdr:  CVS = 1.3,  DLT_OLD_PFLOG = 17,  Length = 28
+ * Pflog2_Hdr:  CVS = 1.8,  DLT_PFLOG     = 117, Length = 48
+ * Pflog3_Hdr:  CVS = 1.12, DLT_PFLOG     = 117, Length = 64
+ * Pflog3_Hdr:  CVS = 1.172, DLT_PFLOG     = 117, Length = 100
+ *
+ * Since they have the same DLT, Pflog{2,3}Hdr are distinguished
+ * by their actual length.  The minimum required length excludes
+ * padding.
+ */
+/* Old OpenBSD pf firewall pflog0 header
+ * (information from pf source in kernel)
+ * the rule, reason, and action codes tell why the firewall dropped it -fleck
+ */
+
+class PflogCodec : public Codec
+{
+public:
+    PflogCodec() : Codec(PFLOG_NAME){};
+    ~PflogCodec() {};
+
+    bool decode(const RawData&, CodecData&, DecodeData&) override;
+    void get_data_link_type(std::vector<int>&) override;
+};
+
+
+struct Pflog1Hdr
+{
+    uint32_t af;
+    char intf[IFNAMSIZ];
+    int16_t rule;
+    uint16_t reason;
+    uint16_t action;
+    uint16_t dir;
+};
+
+#define PFLOG1_HDRLEN (sizeof(struct _Pflog1_hdr))
+
+/*
+ * Note that on OpenBSD, af type is sa_family_t. On Linux, that's an unsigned
+ * short, but on OpenBSD, that's a uint8_t, so we should explicitly use uint8_t
+ * here.  - ronaldo
+ */
+
+#define PFLOG_RULELEN 16
+#define PFLOG_PADLEN  3
+
+struct Pflog2Hdr
+{
+    int8_t   length;
+    uint8_t  af;
+    uint8_t  action;
+    uint8_t  reason;
+    char     ifname[IFNAMSIZ];
+    char     ruleset[PFLOG_RULELEN];
+    uint32_t rulenr;
+    uint32_t subrulenr;
+    uint8_t  dir;
+    uint8_t  pad[PFLOG_PADLEN];
+} ;
+
+#define PFLOG2_HDRLEN (sizeof(Pflog2Hdr))
+#define PFLOG2_HDRMIN (PFLOG2_HDRLEN - PFLOG_PADLEN)
+
+struct Pflog3Hdr
+{
+    int8_t   length;
+    uint8_t  af;
+    uint8_t  action;
+    uint8_t  reason;
+    char     ifname[IFNAMSIZ];
+    char     ruleset[PFLOG_RULELEN];
+    uint32_t rulenr;
+    uint32_t subrulenr;
+    uint32_t uid;
+    uint32_t pid;
+    uint32_t rule_uid;
+    uint32_t rule_pid;
+    uint8_t  dir;
+    uint8_t  pad[PFLOG_PADLEN];
+};
+
+#define PFLOG3_HDRLEN (sizeof(Pflog3Hdr))
+#define PFLOG3_HDRMIN (PFLOG3_HDRLEN - PFLOG_PADLEN)
+
+
+struct Pflog4Hdr
+{
+    uint8_t  length;
+    uint8_t  af;
+    uint8_t  action;
+    uint8_t  reason;
+    char     ifname[IFNAMSIZ];
+    char     ruleset[PFLOG_RULELEN];
+    uint32_t rulenr;
+    uint32_t subrulenr;
+    uint32_t uid;
+    uint32_t pid;
+    uint32_t rule_uid;
+    uint32_t rule_pid;
+    uint8_t  dir;
+    uint8_t  rewritten;
+    uint8_t  pad[2];
+    uint8_t saddr[16];
+    uint8_t daddr[16];
+    uint16_t sport;
+    uint16_t dport;
+};
+
+#define PFLOG4_HDRLEN sizeof(struct Pflog4Hdr)
+#define PFLOG4_HDRMIN sizeof(struct Pflog4Hdr)
+
+} // namespace
+
+
+void PflogCodec::get_data_link_type(std::vector<int>& v)
+{ v.push_back(DLT_PFLOG); }
+
+bool PflogCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
+{
+    const uint32_t cap_len = raw.len;
+    uint8_t af, pflen;
+    uint32_t hlen;
+    uint32_t padlen = PFLOG_PADLEN;
+
+
+    /* do a little validation */
+    if(cap_len < PFLOG2_HDRMIN)
+        return false;
+
+    /* lay the pf header structure over the packet data */
+    switch(*((uint8_t*)raw.data))
+    {
+        case PFLOG2_HDRMIN:
+        {
+            const Pflog2Hdr* const pf2h =
+                reinterpret_cast<const Pflog2Hdr*>(raw.data);
+            pflen = pf2h->length;
+            hlen = PFLOG2_HDRLEN;
+            af = pf2h->af;
+            break;
+        }
+        case PFLOG3_HDRMIN:
+        {
+            const Pflog3Hdr* const pf3h =
+                reinterpret_cast<const Pflog3Hdr*>(raw.data);
+            pflen = pf3h->length;
+            hlen = PFLOG3_HDRLEN;
+            af = pf3h->af;
+            break;
+        }
+        case PFLOG4_HDRMIN:
+        {
+            const Pflog4Hdr* const pf4h =
+                reinterpret_cast<const Pflog4Hdr*>(raw.data);
+            pflen = pf4h->length;
+            hlen = PFLOG4_HDRLEN;
+            af = pf4h->af;
+            padlen = sizeof(pf4h->pad);
+            break;
+        }
+        default:
+            return false;
+    }
+
+    /* now that we know a little more, do a little more validation */
+    if(cap_len < hlen)
+        return false;
+
+    /* note that the pflen may exclude the padding which is always present */
+    if(pflen < hlen - padlen || pflen > hlen)
+        return false;
+
+
+    /* check the network type - should only be AF_INET or AF_INET6 */
+    switch(af)
+    {
+        case AF_INET:   /* IPv4 */
+            codec.next_prot_id = ETHERTYPE_IPV4;
+            break;
+
+#if defined(AF_INET6)
+        case AF_INET6:  /* IPv6 */
+            codec.next_prot_id = ETHERTYPE_IPV6;
+            break;
+#endif
+
+        default:
+            /* To my knowledge, pflog devices can only
+             * pass IP and IP6 packets. -fleck
+             */
+            // TBD add decoder drop event for unknown pflog network type
+            break;
+    }
+
+    codec.lyr_len = hlen;
+    return true;
+}
+
+
+//-------------------------------------------------------------------------
+// api
+//-------------------------------------------------------------------------
+
+
+static Codec* ctor(Module*)
+{ return new PflogCodec(); }
+
+static void dtor(Codec *cd)
+{ delete cd; }
+
+
+static const CodecApi pflog_api =
+{
+    {
+        PT_CODEC,
+        PFLOG_NAME,
+        PFLOG_HELP,
+        CDAPI_PLUGIN_V0,
+        0,
+        nullptr, // mod_ctor
+        nullptr  // mod_dtor
+    },
+    nullptr, // ginit
+    nullptr, // gterm
+    nullptr, // tinit
+    nullptr, // tterm
+    ctor,
+    dtor,
+};
+
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+    &pflog_api.base,
+    nullptr
+};
+#else
+const BaseApi* cd_pflog = &pflog_api.base;
+#endif
+