From: Josh Date: Thu, 11 Dec 2014 18:03:52 +0000 (-0600) Subject: ading i4l_rawip and pflog roto codecs X-Git-Tag: 3.0.0-233~1089^2~16^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7ddab7a3656c1f2197d900a191ca2d34ff326327;p=thirdparty%2Fsnort3.git ading i4l_rawip and pflog roto codecs --- diff --git a/src/codecs/codec_api.cc b/src/codecs/codec_api.cc index 06e4fdad8..bca940a21 100644 --- a/src/codecs/codec_api.cc +++ b/src/codecs/codec_api.cc @@ -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 diff --git a/src/codecs/root/CMakeLists.txt b/src/codecs/root/CMakeLists.txt index b251601d1..1f63640d4 100644 --- a/src/codecs/root/CMakeLists.txt +++ b/src/codecs/root/CMakeLists.txt @@ -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) diff --git a/src/codecs/root/Makefile.am b/src/codecs/root/Makefile.am index 06e778098..84b7625f4 100644 --- a/src/codecs/root/Makefile.am +++ b/src/codecs/root/Makefile.am @@ -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 diff --git a/src/codecs/root/cd_i4l_rawip.cc b/src/codecs/root/cd_i4l_rawip.cc index 1b6cf3ef7..4431cf8b8 100644 --- a/src/codecs/root/cd_i4l_rawip.cc +++ b/src/codecs/root/cd_i4l_rawip.cc @@ -28,11 +28,16 @@ #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&) override; @@ -50,24 +55,16 @@ public: } // namespace - +#ifdef DLT_I4L_RAWIP void I4LRawIpCodec::get_data_link_type(std::vector& 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& 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 index 000000000..046241f6c --- /dev/null +++ b/src/codecs/root/cd_pflog.cc @@ -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 +#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&) 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& 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(raw.data); + pflen = pf2h->length; + hlen = PFLOG2_HDRLEN; + af = pf2h->af; + break; + } + case PFLOG3_HDRMIN: + { + const Pflog3Hdr* const pf3h = + reinterpret_cast(raw.data); + pflen = pf3h->length; + hlen = PFLOG3_HDRLEN; + af = pf3h->af; + break; + } + case PFLOG4_HDRMIN: + { + const Pflog4Hdr* const pf4h = + reinterpret_cast(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 +