From: Russ Combs Date: Thu, 16 Jul 2015 02:27:40 +0000 (-0400) Subject: Squashed commit of the following: X-Git-Tag: 3.0.0-233~908 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5ea479b6fbcabdd1a9e62edf2b07e6c60e424cc7;p=thirdparty%2Fsnort3.git Squashed commit of the following: additional header cleanup; add/remove config.h; consistent author lines; and other scrubbing fuchsia -> green and additional css tweaks via sed cleanup and formatting of dev_notes.txt dev notes and header scrubbing for helpers/ and protocols/ remove dead file removed hard limit on number of rules; converted sfrim to use vector Additional dev guide updates. davis: dev guide updates hui: update sip dev notes parser cleanup some C++ification of structs update events dev notes Bhagya: dev guide updates ed - dev guide updates added dev_guide.sh to doc/ remove doxygen markup packet_io dev notes tweaks spell check updates Ed: dev guide updates carter: dev guide updates Merge branch 'devdoc_file' from hui dev notes for src/search_engines/ wizard dev notes src/network_inspectors/binder/ dev notes dev notes for src/managers/ dev notes for src/main/ dev notes for src/framework/ dev notes for src/flow/ src/detection/ dev guide updates dev notes for src/ports commit 7cddb3d668f7eafce0c7c78787673932d5f45906 Author: Tom Peters Date: Tue Jul 14 14:17:18 2015 -0400 NHI Guide commit 3fd9e703ffb27353e435cfaad3f5909b85ef02ff Author: huica Date: Mon Jul 13 16:47:57 2015 -0400 update documents for sfip, sfrt, and target-based commit 1a1be2c9191a5743fd8318894586131f1b785a3b Author: Bhagyashree Bantwal Date: Mon Jul 13 13:27:45 2015 -0400 dev guide update commit aec8ca50dbdd72cec9cd7e7150d2d49e481fb811 Author: Tom Peters Date: Mon Jul 13 11:47:41 2015 -0400 Developer's Guide commit ed093eb5857e9a94aa612c652d19ec2e5ae7924f Author: huica Date: Fri Jul 10 17:26:15 2015 -0400 file API document updated --- diff --git a/ChangeLog b/ChangeLog index bed38ba1e..fd0dd8de0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +15/07/15 - build 161 + +-- added piglet plugin test harness +-- added piglet_scripts with codec and inspector examples +-- added doc/dev_guide.sh +-- added dev_notes.txt in each src/ subdir +-- scrubbed headers + 15/07/06 - build 160 - Alpha 2 -- fixed duplicate patterns in file_magic.lua diff --git a/doc/Makefile.am b/doc/Makefile.am index c956a53bc..c1221eb54 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -54,7 +54,8 @@ EXTRA_DIST = \ default_snort_manual.text \ default_snort_manual.html \ default_snort_manual.pdf \ -online_manual.sh +online_manual.sh \ +dev_guide.sh doc_DATA = \ snort_manual.text \ diff --git a/doc/dev_guide.sh b/doc/dev_guide.sh new file mode 100755 index 000000000..a9737e6d9 --- /dev/null +++ b/doc/dev_guide.sh @@ -0,0 +1,124 @@ +#!/bin/bash +# run from top of source tree (where configure.ac lives) +# this will create /tmp/dev_guide.{txt,html} +# use dev_guide.html to browse the source notes and headers +# +# FIXIT: +# -- make sidebar width draggable +# -- make snort includes in headers clickable +# -- remove header guards? (outermost #ifndef, #define, #endif) +# -- use css source instead of the sed at the end of this file? + +tmp=/tmp/dev_guide/ +out=$tmp/dev_guide.txt +notes=dev_notes.txt + +mkdir -p $tmp || exit -1 + +src_dirs=`find src -type d` + +# copy headers to temp working dir using same tree structure +# but strip out repetitive copyright blocks +for d in $src_dirs ; do + mkdir -p $tmp/$d + + ls $d/*.h &> /dev/null || + continue + + for f in $d/*.h ; do + n=`grep -m 1 -n -o "#ifndef" $f` + n=${n/:*} + [ "$n" ] || continue + n=$((n-1)) + sed -e "1,${n}d" $f > $tmp/$f + done +done + +# emit doc boilerplate +cat < $out += Snort++ Developers Guide +:author: The Snort Team +:toc: +:toc-placement: manual +:toc-title: Contents + +toc::[] + +END + +# emit copyright just once at the top +sed -ne "1,/^$/s/..//p" src/main.h >> $out +echo >> $out + +# generate source from headers and dev notes +for d in $src_dirs ; do + + # section heading + if [ ${#d} -eq 3 ] ; then + echo -e "== $d/\n" + else + echo -e "== ${d:4}/\n" + fi + + # section notes + if [ -e "$d/$notes" ] ; then + cp $d/$notes $tmp/$d/ + echo -e "include::$d/$notes[]\n" + fi + + ls $d/*.h &> /dev/null || + continue + + # now emit subsection for all headers + for h in $d/*.h ; do + [ -e "$tmp/$h" ] || continue + cat <> $out + +# now generate the dev guide from the source in $tmp +cd $tmp +asc_args="-b xhtml11 -a toc2" +asciidoc $asc_args $out + +# this results in: +#a2x_args="--copy -a linkcss -a stylesdir -a disable-javascript -a quirks! --xsltproc-opts='--stringparam chunk.tocs.and.lots 1'" +# +# Usage: a2x [OPTIONS] SOURCE_FILE +# +#a2x: error: incorrect number of arguments + +# this results in: +a2x_args="--copy -a linkcss -a stylesdir -a disable-javascript -a quirks!" + +# a2x: ERROR: "dblatex" -t pdf -p +# "/opt/local/etc/asciidoc/dblatex/asciidoc-dblatex.xsl" -s +# "/opt/local/etc/asciidoc/dblatex/asciidoc-dblatex.sty" +# "/Users/rucombs/Build/auto/doc/tmp/dev_guide.xml" returned non-zero exit +# status 1 +#a2x -f chunked $a2x_args $out + +# and this doesn't syntax highlight: +#a2x -f pdf $a2x_args $out + +# fix up some stuff +# this is quick and dirty and but not future proof +sed -i.sed \ + -e "s/color: fuchsia/color: green/" \ + -e "s/margin-left: 16em/margin-left: 20em/" \ + -e "s/width: 13em/width: 18em/" \ + dev_guide.html + +mv dev_guide.* ../ +cd .. +rm -rf $tmp + diff --git a/extra/src/search_engines/lowmem.cc b/extra/src/search_engines/lowmem.cc index 79a1271d3..4d4f871b5 100644 --- a/extra/src/search_engines/lowmem.cc +++ b/extra/src/search_engines/lowmem.cc @@ -69,17 +69,17 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return KTrieCompileWithSnortConf(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { *current_state = 0; - return KTrieSearch(obj, (unsigned char*)T, n, action, data); + return KTrieSearch(obj, (unsigned char*)T, n, match, data); } int get_pattern_count() override diff --git a/extra/src/search_engines/lowmem_q.cc b/extra/src/search_engines/lowmem_q.cc index 9f321c2a8..563392dff 100644 --- a/extra/src/search_engines/lowmem_q.cc +++ b/extra/src/search_engines/lowmem_q.cc @@ -124,17 +124,17 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return KTrieCompileWithSnortConf(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { *current_state = 0; - return KTrieSearchQ(obj, (unsigned char*)T, n, action, data); + return KTrieSearchQ(obj, (unsigned char*)T, n, match, data); } int get_pattern_count() override diff --git a/src/actions/act_replace.h b/src/actions/act_replace.h index 46a71b24c..14d9c7da9 100644 --- a/src/actions/act_replace.h +++ b/src/actions/act_replace.h @@ -21,11 +21,13 @@ #include +struct Packet; + // FIXIT-M these prevent ips replace option and action // from being dynamically built void Replace_ResetQueue(void); void Replace_QueueChange(const std::string&, unsigned); -void Replace_ModifyPacket(Packet*); +void Replace_ModifyPacket(struct Packet*); #endif diff --git a/src/actions/actions.cc b/src/actions/actions.cc index 935fb887f..c8666fa30 100644 --- a/src/actions/actions.cc +++ b/src/actions/actions.cc @@ -16,11 +16,12 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +#include "actions.h" + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "actions/actions.h" #include "main/snort_types.h" #include "main/snort_debug.h" #include "utils/util.h" diff --git a/src/actions/actions.h b/src/actions/actions.h index 0ae945641..189ed61b8 100644 --- a/src/actions/actions.h +++ b/src/actions/actions.h @@ -19,6 +19,8 @@ #ifndef ACTIONS_H #define ACTIONS_H +// Define action types and provide hooks to apply a given action to a packet + #include #define ACTION_LOG "log" @@ -28,6 +30,10 @@ #define ACTION_BLOCK "block" #define ACTION_RESET "reset" +struct Packet; +struct OptTreeNode; + +// FIXIT-L: Convert to a scoped enum enum RuleType { RULE_TYPE__NONE = 0, @@ -40,6 +46,7 @@ enum RuleType RULE_TYPE__MAX }; +// FIXIT-L: Could be static methods of class enclosing RuleType enum const char* get_action_string(RuleType); RuleType get_action_type(const char*); @@ -47,9 +54,7 @@ void action_execute(RuleType, struct Packet*, struct OptTreeNode*, uint16_t even void action_apply(RuleType, struct Packet*); static inline bool pass_action(RuleType a) -{ - return ( a == RULE_TYPE__PASS ); -} +{ return ( a == RULE_TYPE__PASS ); } #endif diff --git a/src/actions/dev_notes.txt b/src/actions/dev_notes.txt new file mode 100644 index 000000000..c7beb9699 --- /dev/null +++ b/src/actions/dev_notes.txt @@ -0,0 +1,15 @@ +IPS actions allow you to execute custom responses to events. +Unlike loggers, these are invoked before thresholding and can be used to +control external agents (including loggers). + +IPS rules have an associated type that determines what kind of action they +trigger. The rule types defined in this module are: + +* log +* pass +* alert +* drop +* block +* reset + +There is also a "none" rule type, which is a no-op. diff --git a/src/codecs/dev_notes.txt b/src/codecs/dev_notes.txt new file mode 100644 index 000000000..2c85677cb --- /dev/null +++ b/src/codecs/dev_notes.txt @@ -0,0 +1,6 @@ +This directory contains all of the codecs used for parsing raw fields contained +within captured frames. The codecs contained do not perform processing beyond +basic per-frame validation. They handle protocols from link layer through +transport. + +Codecs here conform to the API defined by src/framework/codec.h. diff --git a/src/codecs/ip/cd_esp.cc b/src/codecs/ip/cd_esp.cc index c24247d4e..d3def2530 100644 --- a/src/codecs/ip/cd_esp.cc +++ b/src/codecs/ip/cd_esp.cc @@ -85,14 +85,11 @@ void EspCodec::get_protocol_ids(std::vector& v) { v.push_back(IPPROTO_ID_ESP); } /* - * Function: DecodeESP(const uint8_t *, uint32_t, Packet *) - * - * Purpose: Attempt to decode Encapsulated Security Payload. - * The contents are probably encrypted, but ESP is sometimes used - * with "null" encryption, solely for Authentication. - * This is more of a heuristic -- there is no ESP field that specifies - * the encryption type (or lack thereof). - * + * Attempt to decode Encapsulated Security Payload. + * The contents are probably encrypted, but ESP is sometimes used + * with "null" encryption, solely for Authentication. + * This is more of a heuristic -- there is no ESP field that specifies + * the encryption type (or lack thereof). */ bool EspCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) { @@ -139,7 +136,7 @@ bool EspCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) codec.ip6_extension_count++; } - // FIXIT: Leftover from Snort. Do we really want thsi? + // FIXIT-L: Leftover from Snort. Do we really want thsi? const_cast(raw.len) -= (ESP_AUTH_DATA_LEN + ESP_TRAILER_LEN); /* Adjust the packet length to account for the padding. diff --git a/src/codecs/ip/cd_gre.cc b/src/codecs/ip/cd_gre.cc index 3e5b6b2bd..3ab839faa 100644 --- a/src/codecs/ip/cd_gre.cc +++ b/src/codecs/ip/cd_gre.cc @@ -92,18 +92,7 @@ void GreCodec::get_protocol_ids(std::vector& v) { v.push_back(IPPROTO_ID_GRE); } /* - * Function: DecodeGRE(uint8_t *, uint32_t, Packet *) - * - * Purpose: Decode Generic Routing Encapsulation Protocol - * This will decode normal GRE and PPTP GRE. - * - * Arguments: pkt => ptr to the packet data - * len => length from here to the end of the packet - * p => pointer to decoded packet struct - * - * Returns: void function - * - * Notes: see RFCs 1701, 2784 and 2637 + * see RFCs 1701, 2784 and 2637 */ bool GreCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) { diff --git a/src/codecs/ip/cd_icmp4.cc b/src/codecs/ip/cd_icmp4.cc index c5401d46a..623ce4794 100644 --- a/src/codecs/ip/cd_icmp4.cc +++ b/src/codecs/ip/cd_icmp4.cc @@ -124,21 +124,6 @@ private: void Icmp4Codec::get_protocol_ids(std::vector& v) { v.push_back(IPPROTO_ID_ICMPV4); } -//-------------------------------------------------------------------- -// decode.c::ICMP -//-------------------------------------------------------------------- - -/* - * Function: DecodeICMP(uint8_t *, const uint32_t, Packet *) - * - * Purpose: Decode the ICMP transport layer - * - * Arguments: pkt => ptr to the packet data - * len => length from here to the end of the packet - * p => pointer to the decoded packet struct - * - * Returns: void function - */ bool Icmp4Codec::decode(const RawData& raw, CodecData& codec,DecodeData& snort) { if (raw.len < icmp::ICMP_BASE_LEN) @@ -244,7 +229,6 @@ bool Icmp4Codec::decode(const RawData& raw, CodecData& codec,DecodeData& snort) break; } - /* Run a bunch of ICMP decoder rules */ ICMP4MiscTests(icmph, codec, (uint16_t)raw.len - len); snort.set_pkt_type(PktType::ICMP); @@ -591,7 +575,7 @@ void Icmp4Codec::update(const ip::IpApi&, const EncodeFlags flags, void Icmp4Codec::format(bool /*reverse*/, uint8_t* raw_pkt, DecodeData& snort) { - // TBD handle nested icmp4 layers + // FIXIT-L handle nested icmp4 layers snort.icmph = reinterpret_cast(raw_pkt); snort.set_pkt_type(PktType::ICMP); } diff --git a/src/codecs/ip/cd_icmp6.cc b/src/codecs/ip/cd_icmp6.cc index f467a20ff..cba2e13fc 100644 --- a/src/codecs/ip/cd_icmp6.cc +++ b/src/codecs/ip/cd_icmp6.cc @@ -110,10 +110,6 @@ public: void Icmp6Codec::get_protocol_ids(std::vector& v) { v.push_back(IPPROTO_ID_ICMPV6); } -//-------------------------------------------------------------------- -// decode.c::ICMP6 -//-------------------------------------------------------------------- - bool Icmp6Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) { if (raw.len < icmp::ICMP6_HEADER_MIN_LEN) @@ -307,13 +303,13 @@ void Icmp6Codec::log(TextLog* const text_log, const uint8_t* raw_pkt, namespace { -typedef struct +struct IcmpHdr { uint8_t type; uint8_t code; uint16_t cksum; uint32_t unused; -} IcmpHdr; +}; } // namespace void Icmp6Codec::update(const ip::IpApi& api, const EncodeFlags flags, diff --git a/src/codecs/ip/cd_ipv4.cc b/src/codecs/ip/cd_ipv4.cc index 1ff9f243c..12459da8d 100644 --- a/src/codecs/ip/cd_ipv4.cc +++ b/src/codecs/ip/cd_ipv4.cc @@ -145,7 +145,6 @@ bool Ipv4Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) uint32_t ip_len; /* length from the start of the ip hdr to the pkt end */ uint16_t hlen; /* ip header length */ - /* do a little validation */ if (raw.len < ip::IP4_HEADER_LEN) { if ((codec.codec_flags & CODEC_UNSURE_ENCAP) == 0) @@ -174,11 +173,9 @@ bool Ipv4Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) return false; } - /* get the IP datagram length */ ip_len = iph->len(); hlen = iph->hlen(); - /* header length sanity check */ if (hlen < ip::IP4_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, @@ -308,7 +305,6 @@ bool Ipv4Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) if ( !ip_len) codec_event(codec, DECODE_ZERO_LENGTH_FRAG); - /* set the packet fragment flag */ snort.decode_flags |= DECODE_FRAG; } else @@ -339,10 +335,6 @@ bool Ipv4Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) return true; } -//------------------------------------------------------------------ -// decode.c::IP4 misc -//-------------------------------------------------------------------- - void Ipv4Codec::IP4AddrTests( const IP4Hdr* iph, const CodecData& codec, DecodeData& snort) { @@ -467,17 +459,6 @@ void Ipv4Codec::IPMiscTests(const IP4Hdr* const ip4h, const CodecData& codec, ui codec_event(codec, DECODE_IP_OPTION_SET); } -/* - * Function: DecodeIPOptions(uint8_t *, uint32_t, Packet *) - * - * Purpose: Once again, a fairly self-explainatory name - * - * Arguments: o_list => ptr to the option list - * o_len => length of the option list - * p => pointer to decoded packet struct - * - * Returns: void function - */ void Ipv4Codec::DecodeIPOptions(const uint8_t* start, uint8_t& o_len, CodecData& codec) { uint32_t tot_len = 0; diff --git a/src/codecs/ip/cd_ipv6.cc b/src/codecs/ip/cd_ipv6.cc index a112f7c18..b18c5a972 100644 --- a/src/codecs/ip/cd_ipv6.cc +++ b/src/codecs/ip/cd_ipv6.cc @@ -226,14 +226,6 @@ void Ipv6Codec::IPV6CheckIsatap(const ip::IP6Hdr* const ip6h, } } -/* Function: IPV6MiscTests(Packet *p) - * - * Purpose: A bunch of IPv6 decoder alerts - * - * Arguments: p => the Packet to check - * - * Returns: void function - */ void Ipv6Codec::IPV6MiscTests(const DecodeData& snort, const CodecData& codec) { const sfip_t* ip_src = snort.ip_api.get_src(); @@ -266,7 +258,6 @@ void Ipv6Codec::IPV6MiscTests(const DecodeData& snort, const CodecData& codec) } } -/* Check for multiple IPv6 Multicast-related alerts */ void Ipv6Codec::CheckIPV6Multicast(const ip::IP6Hdr* const ip6h, const CodecData& codec) { ip::MulticastScope multicast_scope; diff --git a/src/codecs/ip/checksum.h b/src/codecs/ip/checksum.h index 68204f9be..530d12c7f 100644 --- a/src/codecs/ip/checksum.h +++ b/src/codecs/ip/checksum.h @@ -20,10 +20,6 @@ #ifndef CODECS_CHECKSUM_H #define CODECS_CHECKSUM_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include #include #include diff --git a/src/codecs/ip/dev_notes.txt b/src/codecs/ip/dev_notes.txt new file mode 100644 index 000000000..335bee0e8 --- /dev/null +++ b/src/codecs/ip/dev_notes.txt @@ -0,0 +1,2 @@ +All codecs under this directory handle data that would be seen directly +following or under IP headers. diff --git a/src/codecs/link/cd_arp.cc b/src/codecs/link/cd_arp.cc index 091e0284e..b3fd628b3 100644 --- a/src/codecs/link/cd_arp.cc +++ b/src/codecs/link/cd_arp.cc @@ -63,21 +63,6 @@ void ArpCodec::get_protocol_ids(std::vector& v) v.push_back(ETHERTYPE_REVARP); } -//-------------------------------------------------------------------- -// decode.c::ARP -//-------------------------------------------------------------------- - -/* - * Function: DecodeARP(uint8_t *, uint32_t, Packet *) - * - * Purpose: Decode ARP stuff - * - * Arguments: pkt => ptr to the packet data - * len => length from here to the end of the packet - * p => pointer to decoded packet struct - * - * Returns: void function - */ bool ArpCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) { if (raw.len < arp::ETHERARP_HDR_LEN) diff --git a/src/codecs/link/cd_erspan2.cc b/src/codecs/link/cd_erspan2.cc index 087dba254..ca8fdf3fd 100644 --- a/src/codecs/link/cd_erspan2.cc +++ b/src/codecs/link/cd_erspan2.cc @@ -69,19 +69,6 @@ constexpr uint16_t ETHERTYPE_ERSPAN_TYPE2 = 0x88be; void Erspan2Codec::get_protocol_ids(std::vector& v) { v.push_back(ETHERTYPE_ERSPAN_TYPE2); } -/* - * Function: DecodeERSPANType2(uint8_t *, uint32_t, Packet *) - * - * Purpose: Decode Encapsulated Remote Switch Packet Analysis Type 2 - * This will decode ERSPAN Type 2 Headers - * - * Arguments: pkt => ptr to the packet data - * len => length from here to the end of the packet - * p => pointer to decoded packet struct - * - * Returns: void function - * - */ bool Erspan2Codec::decode(const RawData& raw, CodecData& codec, DecodeData&) { const ERSpanType2Hdr* const erSpan2Hdr = diff --git a/src/codecs/link/cd_erspan3.cc b/src/codecs/link/cd_erspan3.cc index e47352622..1b40d3b4c 100644 --- a/src/codecs/link/cd_erspan3.cc +++ b/src/codecs/link/cd_erspan3.cc @@ -82,19 +82,6 @@ constexpr uint16_t ETHERTYPE_ERSPAN_TYPE3 = 0x22eb; void Erspan3Codec::get_protocol_ids(std::vector& v) { v.push_back(ETHERTYPE_ERSPAN_TYPE3); } -/* - * Function: DecodeERSPANType3(uint8_t *, uint32_t, Packet *) - * - * Purpose: Decode Encapsulated Remote Switch Packet Analysis Type 3 - * This will decode ERSPAN Type 3 Headers - * - * Arguments: pkt => ptr to the packet data - * len => length from here to the end of the packet - * p => pointer to decoded packet struct - * - * Returns: void function - * - */ bool Erspan3Codec::decode(const RawData& raw, CodecData& codec, DecodeData&) { const ERSpanType3Hdr* const erSpan3Hdr = diff --git a/src/codecs/link/cd_fabricpath.cc b/src/codecs/link/cd_fabricpath.cc index e74fa9945..28060a9d8 100644 --- a/src/codecs/link/cd_fabricpath.cc +++ b/src/codecs/link/cd_fabricpath.cc @@ -91,12 +91,11 @@ bool FabricPathCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_l if ( !raw ) { - // if not raw ip AND out buf is empty if ( buf.size() == 0) { buf.off = 0; // for alignment } - else // if not raw ip AND buf is not empty + else { // we get here for outer-most layer when not raw ip // we also get here for any encapsulated ethernet layer. diff --git a/src/codecs/link/cd_ppp_encap.cc b/src/codecs/link/cd_ppp_encap.cc index 4ae635661..d9525efa8 100644 --- a/src/codecs/link/cd_ppp_encap.cc +++ b/src/codecs/link/cd_ppp_encap.cc @@ -52,17 +52,6 @@ const static uint16_t PPP_IPX = 0x002b; /* Novell IPX Protocol */ void PppEncap::get_protocol_ids(std::vector& v) { v.push_back(ETHERTYPE_PPP); } -/* - * Function: DecodePppPktEncapsulated(Packet *, const uint32_t len, uint8_t*) - * - * Purpose: Decode PPP traffic (RFC1661 framing). - * - * Arguments: p => pointer to decoded packet struct - * len => length of data to process - * pkt => pointer to the real live packet data - * - * Returns: void function - */ bool PppEncap::decode(const RawData& raw, CodecData& codec, DecodeData&) { static THREAD_LOCAL bool had_vj = false; @@ -79,9 +68,6 @@ bool PppEncap::decode(const RawData& raw, CodecData& codec, DecodeData&) #endif /* WORDS_MUSTALIGN */ - /* do a little validation: - * - */ if (raw.len < 2) return false; diff --git a/src/codecs/link/cd_pppoe.cc b/src/codecs/link/cd_pppoe.cc index 956e424a6..3a61c8e1c 100644 --- a/src/codecs/link/cd_pppoe.cc +++ b/src/codecs/link/cd_pppoe.cc @@ -116,7 +116,6 @@ bool PPPoECodec::decode(const RawData& raw, CodecData& codec, DecodeData&) { - /* do a little validation */ if (raw.len < PPPOE_HEADER_LEN) { codec_event(codec, DECODE_BAD_PPPOE); diff --git a/src/codecs/link/cd_trans_bridge.cc b/src/codecs/link/cd_trans_bridge.cc index b1b339324..2a4e7c72f 100644 --- a/src/codecs/link/cd_trans_bridge.cc +++ b/src/codecs/link/cd_trans_bridge.cc @@ -47,22 +47,6 @@ public: void TransbridgeCodec::get_protocol_ids(std::vector& v) { v.push_back(ETHERTYPE_TRANS_ETHER_BRIDGING); } -/* - * Function: DecodeTransBridging(uint8_t *, const uint32_t, Packet) - * - * Purpose: Decode Transparent Ethernet Bridging - * - * Arguments: pkt => pointer to the real live packet data - * len => length of remaining data in packet - * p => pointer to the decoded packet struct - * - * - * Returns: void function - * - * Note: This is basically the code from DecodeEthPkt but the calling - * convention needed to be changed and the stuff at the beginning - * wasn't needed since we are already deep into the packet - */ bool TransbridgeCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) { if (raw.len < eth::ETH_HEADER_LEN) diff --git a/src/codecs/link/dev_notes.txt b/src/codecs/link/dev_notes.txt new file mode 100644 index 000000000..a9b25c9ce --- /dev/null +++ b/src/codecs/link/dev_notes.txt @@ -0,0 +1,2 @@ +These codecs handle link-layer protocols that would be presented beyond the +root encapsulation defined by the capture data-link type. diff --git a/src/codecs/misc/cd_gtp.cc b/src/codecs/misc/cd_gtp.cc index a179de7e6..ff4ba91af 100644 --- a/src/codecs/misc/cd_gtp.cc +++ b/src/codecs/misc/cd_gtp.cc @@ -68,12 +68,11 @@ public: uint16_t lyr_len, uint32_t& updated_len) override; }; -/* GTP basic Header */ struct GTPHdr { uint8_t flag; /* flag: version (bit 6-8), PT (5), E (3), S (2), PN (1) */ - uint8_t type; /* message type */ - uint16_t length; /* length */ + uint8_t type; + uint16_t length; }; } // anonymous namespace @@ -86,13 +85,6 @@ void GtpCodec::get_protocol_ids(std::vector& v) v.push_back(PROTO_GTP); } -/* Function: DecodeGTP(uint8_t *, uint32_t, Packet *) - * - * GTP (GPRS Tunneling Protocol) is layered over UDP. - * Decode these (if present) and go to DecodeIPv6/DecodeIP. - * - */ - bool GtpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) { uint8_t next_hdr_type; @@ -102,7 +94,6 @@ bool GtpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) const GTPHdr* const hdr = reinterpret_cast(raw.data); - /*Check the length*/ if (raw.len < GTP_MIN_LEN) return false; /* We only care about PDU*/ @@ -120,14 +111,12 @@ bool GtpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "GTP v0 packets.\n"); ); len = GTP_V0_HEADER_LEN; - /*Check header fields*/ if (raw.len < len) { codec_event(codec, DECODE_GTP_BAD_LEN); return false; } - /*Check the length field. */ if (raw.len != ((unsigned int)ntohs(hdr->length) + len)) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Calculated length %d != %d in header.\n", @@ -157,7 +146,6 @@ bool GtpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) while (next_hdr_type) { uint16_t ext_hdr_len; - /*check length before reading data*/ if (raw.len < (uint32_t)(len + 4)) { codec_event(codec, DECODE_GTP_BAD_LEN); @@ -174,7 +162,6 @@ bool GtpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) /*Extension header length is a unit of 4 octets*/ len += ext_hdr_len * 4; - /*check length before reading data*/ if (raw.len < len) { codec_event(codec, DECODE_GTP_BAD_LEN); @@ -189,7 +176,6 @@ bool GtpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) codec.lyr_len = len; codec.proto_bits |= PROTO_BIT__GTP; - /*Check the length field. */ if (raw.len != ((unsigned int)ntohs(hdr->length) + GTP_MIN_LEN)) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Calculated length %d != %d in header.\n", diff --git a/src/codecs/misc/cd_icmp4_ip.cc b/src/codecs/misc/cd_icmp4_ip.cc index 0b5e23280..fcd9f1d1b 100644 --- a/src/codecs/misc/cd_icmp4_ip.cc +++ b/src/codecs/misc/cd_icmp4_ip.cc @@ -55,7 +55,6 @@ void Icmp4IpCodec::get_protocol_ids(std::vector& v) bool Icmp4IpCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) { - /* do a little validation */ if (raw.len < ip::IP4_HEADER_LEN) { codec_event(codec, DECODE_ICMP_ORIG_IP_TRUNCATED); @@ -75,7 +74,7 @@ bool Icmp4IpCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snor return false; } - const uint16_t hlen = ip4h->hlen(); /* set the IP header length */ + const uint16_t hlen = ip4h->hlen(); if (raw.len < hlen) { @@ -268,7 +267,7 @@ void Icmp4IpCodec::log(TextLog* const text_log, const uint8_t* raw_pkt, break; case ICMP_REDIRECT: - // XXX-IPv6 "NOT YET IMPLEMENTED - ICMP printing" + // FIXIT-L -IPv6 "NOT YET IMPLEMENTED - ICMP printing" break; case icmp::IcmpType::ECHO_4: diff --git a/src/codecs/misc/cd_icmp6_ip.cc b/src/codecs/misc/cd_icmp6_ip.cc index f9f36866f..f314e2f0d 100644 --- a/src/codecs/misc/cd_icmp6_ip.cc +++ b/src/codecs/misc/cd_icmp6_ip.cc @@ -60,7 +60,6 @@ bool Icmp6IpCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) /* lay the IP struct over the raw data */ const ip::IP6Hdr* ip6h = reinterpret_cast(raw.data); - /* do a little validation */ if ( raw.len < ip::IP6_HEADER_LEN ) { codec_event(codec, DECODE_ICMP_ORIG_IP_TRUNCATED); diff --git a/src/codecs/misc/dev_notes.txt b/src/codecs/misc/dev_notes.txt new file mode 100644 index 000000000..0ec2141af --- /dev/null +++ b/src/codecs/misc/dev_notes.txt @@ -0,0 +1,3 @@ +This directory contains codecs that do not fall under the classifications of +the other codec directories. These codecs primarily handle IP tunnelling +protocols. diff --git a/src/codecs/root/cd_eth.cc b/src/codecs/root/cd_eth.cc index e3106a717..57143416e 100644 --- a/src/codecs/root/cd_eth.cc +++ b/src/codecs/root/cd_eth.cc @@ -85,25 +85,8 @@ void EthCodec::get_protocol_ids(std::vector& v) v.push_back(PROTO_ETHERNET_802_3); } -//-------------------------------------------------------------------- -// decode.c::Ethernet -//-------------------------------------------------------------------- - -/* - * Function: DecodeEthPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) - * - * Purpose: Decode those fun loving ethernet packets, one at a time! - * - * Arguments: p => pointer to the decoded packet struct - * user => Utility pointer (unused) - * pkthdr => ptr to the packet header - * pkt => pointer to the real live packet data - * - * Returns: void function - */ bool EthCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) { - /* do a little validation */ if (raw.len < eth::ETH_HEADER_LEN) { codec_event(codec, DECODE_ETH_HDR_TRUNC); @@ -177,7 +160,6 @@ bool EthCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/, // not raw ip -> encode layer 2 bool raw = ( enc.flags & ENC_FLAG_RAW ); - // if not raw ip AND out buf is empty if ( !raw && (buf.size() == 0) ) { // for alignment @@ -187,7 +169,6 @@ bool EthCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/, buf.off = SPARC_TWIDDLE; } - // if not raw ip OR out buf is not empty if ( !raw || (buf.size() != 0) ) { // we get here for outer-most layer when not raw ip diff --git a/src/codecs/root/cd_null.cc b/src/codecs/root/cd_null.cc index 4220071ef..204436fed 100644 --- a/src/codecs/root/cd_null.cc +++ b/src/codecs/root/cd_null.cc @@ -45,21 +45,8 @@ public: static const uint16_t NULL_HDRLEN = 4; -/* - * Function: DecodeNullPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) - * - * Purpose: Decoding on loopback devices. - * - * 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 - */ bool NullCodec::decode(const RawData& raw, CodecData& data, DecodeData&) { - /* do a little validation */ if (raw.len < NULL_HDRLEN) return false; diff --git a/src/codecs/root/cd_pflog.cc b/src/codecs/root/cd_pflog.cc index 7de01c935..b5ff8c7d4 100644 --- a/src/codecs/root/cd_pflog.cc +++ b/src/codecs/root/cd_pflog.cc @@ -158,7 +158,6 @@ bool PflogCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) uint32_t hlen; uint32_t padlen = PFLOG_PADLEN; - /* do a little validation */ if (cap_len < PFLOG2_HDRMIN) return false; @@ -219,10 +218,10 @@ bool PflogCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) #endif default: - /* To my knowledge, pflog devices can only + /* FIXIT-L add decoder drop event for unknown pflog network type + * To my knowledge, pflog devices can only * pass IP and IP6 packets. -fleck */ - // TBD add decoder drop event for unknown pflog network type break; } diff --git a/src/codecs/root/cd_raw4.cc b/src/codecs/root/cd_raw4.cc index 3c4416316..f3e47b467 100644 --- a/src/codecs/root/cd_raw4.cc +++ b/src/codecs/root/cd_raw4.cc @@ -42,23 +42,6 @@ public: }; } // namespace -//-------------------------------------------------------------------- -// decode.c::Raw packets -//-------------------------------------------------------------------- - -/* - * Function: DecodeRawPkt(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 - * pkthdr => ptr to the packet header - * pkt => pointer to the real live packet data - * - * Returns: void function - */ bool Raw4Codec::decode(const RawData&, CodecData& data, DecodeData&) { data.next_prot_id = ETHERTYPE_IPV4; diff --git a/src/codecs/root/cd_raw6.cc b/src/codecs/root/cd_raw6.cc index 20eb5777f..542710ec2 100644 --- a/src/codecs/root/cd_raw6.cc +++ b/src/codecs/root/cd_raw6.cc @@ -42,7 +42,6 @@ public: }; } // namespace -// raw packets are predetermined to be ip4 (above) or ip6 (below) by the DLT bool Raw6Codec::decode(const RawData&, CodecData& data, DecodeData&) { data.next_prot_id = ETHERTYPE_IPV6; diff --git a/src/codecs/root/cd_wlan.cc b/src/codecs/root/cd_wlan.cc index 31f5b9985..28e0232b4 100644 --- a/src/codecs/root/cd_wlan.cc +++ b/src/codecs/root/cd_wlan.cc @@ -79,7 +79,6 @@ void WlanCodec::get_protocol_ids(std::vector& v) bool WlanCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) { - /* do a little validation */ if (raw.len < MINIMAL_IEEE80211_HEADER_LEN) return false; diff --git a/src/codecs/root/dev_notes.txt b/src/codecs/root/dev_notes.txt new file mode 100644 index 000000000..715d3b326 --- /dev/null +++ b/src/codecs/root/dev_notes.txt @@ -0,0 +1,3 @@ +This directory contains codecs for all of the top-level codecs used. These +codecs represent the first layer of encapsulation encountered within a captured +frame, as defined by interface data-link types. diff --git a/src/control/dev_notes.txt b/src/control/dev_notes.txt new file mode 100644 index 000000000..cb165e525 --- /dev/null +++ b/src/control/dev_notes.txt @@ -0,0 +1,2 @@ +This module provides functions for registering and running handlers +that are called when Snort is not doing anything more important. diff --git a/src/control/idle_processing.h b/src/control/idle_processing.h index 5ac7bdef8..92ad4908d 100644 --- a/src/control/idle_processing.h +++ b/src/control/idle_processing.h @@ -20,8 +20,9 @@ #ifndef IDLE_PROCESSING_H #define IDLE_PROCESSING_H -typedef void (* IdleProcessingHandler)(void); +using IdleProcessingHandler = void (*)(); +// FIXIT-L: These should be static class methods int IdleProcessingRegisterHandler(IdleProcessingHandler); void IdleProcessingExecute(void); void IdleProcessingCleanUp(void); diff --git a/src/decompress/dev_notes.txt b/src/decompress/dev_notes.txt new file mode 100644 index 000000000..afd6938a1 --- /dev/null +++ b/src/decompress/dev_notes.txt @@ -0,0 +1,66 @@ +The components in this area implement several file decompression +mechanisms. They provide real-time decompression to permit inspection +(rules) of the decompressed content. + +In particular the components support these decompression options: + +1. Decompress SWF (Adobe Flash) files compressed with the ZLIB algorithm + +2. Optionally decompress SWF files compressed with the LZMA algorithm. + This is only available if Snort ++ is built with the optional LZMA + support. + +3. Decompress the Deflate compressed portions if PDF files. + +The three modes are individually enabled/disabled at initialization time. + +All parsing and decompression is incremental and allows inspection to +proceed as the file is received and processed. + +SWF File Processing: + +SWF files exist in three forms: 1) uncompressed, 2) ZLIB compressed, and 3) +LZMA compressed. SWF files begin with a file signature block (alway +uncompressed) to indicate the format of the balance of the file. The +balance of the file is formatted and processed as specified. + +PDF files are significantly more complex as the compressed content is +embedded within the PDF syntax and one file may contain one or many +compressed segments. + +Thus the PDF decompression engine implements a lightweight PDF file parser +to locate the PDF Stream segments and then attempt to decompress Streams +that are filtered with the FlateDecode compression. Streams are binary +objects that are used for much of the PDF actual content. A Stream object +can be labeled with a Filter option to indicate that the Steam is encoded +in some fashion, perhaps having multiple cascaded Filters. + +The current implementation supports the most common FlateDecode Filter +option and does not support cascaded Filters (including cascaded +FlateDecode's). + +The decompressor processors can indicate several error situations. There +are two mechanisms used to relay these error codes to the calling context. +Some errors terminate processing and are passed to the caller in the +decompression context structure. Other errors are inline and may be passed +back to the caller via a provided call-back function. + +Possible error conditions are: + +* FILE_DECOMP_ERR_SWF_ZLIB_FAILURE - The ZLIB decompression engine returned + an error. + +* FILE_DECOMP_ERR_SWF_LZMA_FAILURE - The LZMA decompression engine returned + an error. + +* FILE_DECOMP_ERR_PDF_DEFL_FAILURE - The Deflate (form of ZLIB) + decompression engine returned at error. + +* FILE_DECOMP_ERR_PDF_UNSUP_COMP_TYPE - An unsupported PDF Stream Filter + type was encountered, + +* FILE_DECOMP_ERR_PDF_CASC_COMP - Cascasded FlateDecode Stream Filters were + encountered. + +* FILE_DECOMP_ERR_PDF_PARSE_FAILURE - Error while parsing the PDF file. + diff --git a/src/decompress/file_decomp.h b/src/decompress/file_decomp.h index e2e6fa872..4587461d1 100644 --- a/src/decompress/file_decomp.h +++ b/src/decompress/file_decomp.h @@ -28,6 +28,8 @@ #include /* File_Decomp global typedefs (used in child objects) */ + +/* Function return codes used internally and with caller */ typedef enum fd_status { File_Decomp_DecompError = -2, /* Error from decompression */ @@ -59,16 +61,20 @@ typedef struct fd_session_s* fd_session_p_t, fd_session_t; #include #endif -/* Potential decompression modes */ +/* Potential decompression modes, passed in at initalization time. */ #define FILE_SWF_LZMA_BIT (0x00000001) #define FILE_SWF_ZLIB_BIT (0x00000002) #define FILE_PDF_DEFL_BIT (0x00000004) + +/* The FILE_REVERT and FILT_NORM functionality is currently not implemented */ #define FILE_FILT_NORM_BIT (0x40000000) /* Normalize the PDF /Filter value string */ #define FILE_REVERT_BIT (0x80000000) /* Revert to 'uncompressed' state */ #define FILE_PDF_ANY (FILE_PDF_DEFL_BIT) #define FILE_SWF_ANY (FILE_SWF_LZMA_BIT | FILE_SWF_ZLIB_BIT) +/* Error codes either passed to caller via the session->Error_Alert of + the File_Decomp_Alert() call-back function. */ enum FileDecompError { FILE_DECOMP_ERR_SWF_ZLIB_FAILURE, @@ -96,6 +102,7 @@ typedef enum states STATE_COMPLETE /* Decompression completed */ } fd_states_t; +/* Primary file decompression session state context */ struct fd_session_s { uint8_t* Next_In; /* next input byte */ @@ -137,6 +144,8 @@ struct fd_session_s /* Macros */ +/* Macros used to sync my decompression context with that + of the underlying decompression engine context. */ #ifndef SYNC_IN #define SYNC_IN(dest) \ dest->next_in = SessionPtr->Next_In; \ @@ -159,6 +168,7 @@ struct fd_session_s /* Inline Functions */ +/* If available, look at the next available byte in the input queue */ static inline bool Peek_1(fd_session_p_t SessionPtr, uint8_t* c) { if ( (SessionPtr->Next_In != NULL) && (SessionPtr->Avail_In > 0) ) @@ -170,6 +180,7 @@ static inline bool Peek_1(fd_session_p_t SessionPtr, uint8_t* c) return( false ); } +/* If available, get a byte from the input queue */ static inline bool Get_1(fd_session_p_t SessionPtr, uint8_t* c) { if ( (SessionPtr->Next_In != NULL) && (SessionPtr->Avail_In > 0) ) @@ -183,6 +194,8 @@ static inline bool Get_1(fd_session_p_t SessionPtr, uint8_t* c) return( false ); } +/* If available, get N bytes from the input queue. All N must be + availble for this call to succeed. */ static inline bool Get_N(fd_session_p_t SessionPtr, uint8_t** c, uint16_t N) { if ( (SessionPtr->Next_In != NULL) && (SessionPtr->Avail_In >= N) ) @@ -197,6 +210,7 @@ static inline bool Get_N(fd_session_p_t SessionPtr, uint8_t** c, uint16_t N) return( false ); } +/* If there's room in the output queue, put one byte. */ static inline bool Put_1(fd_session_p_t SessionPtr, uint8_t c) { if ( (SessionPtr->Next_Out != NULL) && (SessionPtr->Avail_Out > 0) ) @@ -210,6 +224,8 @@ static inline bool Put_1(fd_session_p_t SessionPtr, uint8_t c) return( false ); } +/* If the output queue has room available, place N bytes onto the queue. + The output queue must have space for N bytes for this call to succeed. */ static inline bool Put_N(fd_session_p_t SessionPtr, uint8_t* c, uint16_t N) { if ( (SessionPtr->Next_Out != NULL) && (SessionPtr->Avail_Out >= N) ) @@ -224,6 +240,8 @@ static inline bool Put_N(fd_session_p_t SessionPtr, uint8_t* c, uint16_t N) return( false ); } +/* If the input queue has at least one byte available AND there's at + space for at least one byte in the output queue, then move one byte. */ static inline bool Move_1(fd_session_p_t SessionPtr) { if ( (SessionPtr->Next_Out != NULL) && (SessionPtr->Avail_Out > 0) && @@ -242,6 +260,8 @@ static inline bool Move_1(fd_session_p_t SessionPtr) return( false ); } +/* If the input queue has at least N bytes available AND there's at + space for at least N bytes in the output queue, then move all N bytes. */ static inline bool Move_N(fd_session_p_t SessionPtr, uint16_t N) { if ( (SessionPtr->Next_Out != NULL) && (SessionPtr->Avail_Out >= N) && @@ -262,22 +282,31 @@ static inline bool Move_N(fd_session_p_t SessionPtr, uint16_t N) /* API Functions */ +/* Create a new decompression session object */ fd_session_p_t File_Decomp_New(); +/* Initialize the session */ fd_status_t File_Decomp_Init(fd_session_p_t SessionPtr); +/* Use an internal decompression buffer */ fd_status_t File_Decomp_SetBuf(fd_session_p_t SessionPtr); +/* Run the incremental decompression engine */ fd_status_t File_Decomp(fd_session_p_t SessionPtr); +/* Close the decomp session processing */ fd_status_t File_Decomp_End(fd_session_p_t SessionPtr); +/* Close the current decomp session, but setup for another */ fd_status_t File_Decomp_Reset(fd_session_p_t SessionPtr); +/* Abort and delete the session */ fd_status_t File_Decomp_StopFree(fd_session_p_t SessionPtr); +/* Delete the session object */ void File_Decomp_Free(fd_session_p_t SessionPtr); +/* Call the error alerting call-back function */ void File_Decomp_Alert(fd_session_p_t SessionPtr, int Event); #endif diff --git a/src/decompress/file_decomp_pdf.h b/src/decompress/file_decomp_pdf.h index ef52b7294..6586e2044 100644 --- a/src/decompress/file_decomp_pdf.h +++ b/src/decompress/file_decomp_pdf.h @@ -26,6 +26,9 @@ #define FILTER_SPEC_BUF_LEN (40) #define PARSE_STACK_LEN (12) +/* FIXIT-L Other than the API prototypes, the other parts of this header should + be private to file_decomp_pdf. */ + typedef enum pdf_states { PDF_STATE_NEW, @@ -73,10 +76,13 @@ typedef struct fd_PDF_s /* API Functions */ +/* Init the PDF decompressor */ fd_status_t File_Decomp_Init_PDF(fd_session_p_t SessionPtr); +/* Run the incremental PDF file parser/decompressor */ fd_status_t File_Decomp_End_PDF(fd_session_p_t SessionPtr); +/* End the decompressor */ fd_status_t File_Decomp_PDF(fd_session_p_t SessionPtr); #endif diff --git a/src/decompress/file_decomp_swf.h b/src/decompress/file_decomp_swf.h index 74391c706..b31b41314 100644 --- a/src/decompress/file_decomp_swf.h +++ b/src/decompress/file_decomp_swf.h @@ -20,11 +20,18 @@ #ifndef FILE_DECOMP_SWF_H #define FILE_DECOMP_SWF_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #ifdef HAVE_LZMA #include #endif +/* FIXIT-L Other than the API prototypes, the other parts of this header should + be private to file_decomp_swf. */ + /* Both ZLIB & LZMA files have an uncompressed eight byte header. The signature is three bytes. The header consists of a three byte sig, a one byte version, and a four byte uncompressed length (little-endian). */ @@ -67,10 +74,13 @@ typedef struct fd_SWF_s /* API Functions */ +/* Initialize the SWF file decompressor */ fd_status_t File_Decomp_Init_SWF(fd_session_p_t SessionPtr); +/* Process the file incrementally */ fd_status_t File_Decomp_SWF(fd_session_p_t SessionPtr); +/* End the SWF file decompression */ fd_status_t File_Decomp_End_SWF(fd_session_p_t SessionPtr); #endif diff --git a/src/detection/detect.h b/src/detection/detect.h index 686667ea7..9f595be73 100644 --- a/src/detection/detect.h +++ b/src/detection/detect.h @@ -18,7 +18,6 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* I N C L U D E S ************************************************/ #ifndef DETECT_H #define DETECT_H @@ -26,17 +25,16 @@ #include "config.h" #endif -#include "snort_debug.h" -#include "protocols/packet.h" -#include "rules.h" -#include "treenodes.h" -#include "parser.h" -#include "profiler.h" -#include "log.h" -#include "event.h" +#include "main/snort_debug.h" #include "main/snort_types.h" +#include "protocols/packet.h" +#include "detection/rules.h" +#include "detection/treenodes.h" +#include "parser/parser.h" +#include "time/profiler.h" +#include "log/log.h" +#include "events/event.h" -/* P R O T O T Y P E S ******************************************************/ extern SO_PUBLIC THREAD_LOCAL int do_detect; extern SO_PUBLIC THREAD_LOCAL int do_detect_content; @@ -85,9 +83,5 @@ static inline void DisableInspection(Packet*) do_detect = do_detect_content = 0; } -/* counter for number of times we evaluate rules. Used to - * cache result of check for rule option tree nodes. */ -extern THREAD_LOCAL uint64_t rule_eval_pkt_count; - #endif diff --git a/src/detection/detection_defines.h b/src/detection/detection_defines.h index be9430213..df32889bf 100644 --- a/src/detection/detection_defines.h +++ b/src/detection/detection_defines.h @@ -17,17 +17,16 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** @file detection_defines.h -** @author Steven Sturges -*/ +// detection_defines.h author Steven Sturges #ifndef DETECTION_DEFINES_H #define DETECTION_DEFINES_H +// FIXIT-L replace with bool #define DETECTION_OPTION_EQUAL 0 #define DETECTION_OPTION_NOT_EQUAL 1 +// FIXIT-L replace with IpsOption enum #define DETECTION_OPTION_NO_MATCH 0 #define DETECTION_OPTION_MATCH 1 #define DETECTION_OPTION_NO_ALERT 2 diff --git a/src/detection/detection_options.cc b/src/detection/detection_options.cc index ae8954c3c..4f4df60dc 100644 --- a/src/detection/detection_options.cc +++ b/src/detection/detection_options.cc @@ -372,8 +372,6 @@ int add_detection_option_tree( return DETECTION_OPTION_NOT_EQUAL; } -THREAD_LOCAL uint64_t rule_eval_pkt_count = 0; - int detection_option_node_evaluate( detection_option_tree_node_t* node, detection_option_eval_data_t* eval_data, Cursor& orig_cursor) diff --git a/src/detection/detection_options.h b/src/detection/detection_options.h index fead780ee..83bb1aae4 100644 --- a/src/detection/detection_options.h +++ b/src/detection/detection_options.h @@ -17,18 +17,20 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** @file detection_options.h -** @author Steven Sturges -** @brief Support functions for rule option tree -** -** This implements tree processing for rule options, evaluating common -** detection options only once per pattern match. -*/ +// detection_options.h author Steven Sturges #ifndef DETECTION_OPTIONS_H #define DETECTION_OPTIONS_H +// Support functions for rule option tree +// +// This implements tree processing for rule options, evaluating common +// detection options only once per pattern match. +// +// These trees are instantiated at parse time, one per MPSE match state. +// Eval, profiling, and ppm data are attached in an array sized per max +// packet threads. + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -42,6 +44,7 @@ struct SFXHASH; typedef int (* eval_func_t)(void* option_data, class Cursor&, Packet*); +// this is per packet thread struct dot_node_state_t { int result; @@ -79,6 +82,7 @@ struct detection_option_tree_node_t dot_node_state_t* state; }; +// this is per packet thread #ifdef PPM_MGR struct dot_root_state_t { @@ -130,5 +134,5 @@ void free_detection_option_root(void** existing_tree); detection_option_tree_node_t* new_node(option_type_t type, void* data); void free_detection_option_tree(detection_option_tree_node_t* node); -#endif /* DETECTION_OPTIONS_H */ +#endif diff --git a/src/detection/detection_util.h b/src/detection/detection_util.h index 1656f30ea..0eb700f93 100644 --- a/src/detection/detection_util.h +++ b/src/detection/detection_util.h @@ -17,19 +17,15 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Description -** This file contains the utility functions used by rule options. -*/ #ifndef DETECTION_UTIL_H #define DETECTION_UTIL_H -#include +// this is a legacy junk-drawer file that needs to be refactored +// it provides file and alt data pointers, event trace foo, and +// some http stuff. -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +#include #include "main/snort_types.h" #include "main/snort_config.h" @@ -39,6 +35,8 @@ #define DECODE_BLEN 65535 +// FIXIT-L this is now used only by http_inspect and new_http_inspect +// and should be relocated accordingly enum HTTP_BUFFER { HTTP_BUFFER_NONE, @@ -55,6 +53,8 @@ enum HTTP_BUFFER HTTP_BUFFER_MAX }; +// FIXIT-L this is now used only by http_inspect +// and should be relocated accordingly struct HttpBuffer { const uint8_t* buf; @@ -91,6 +91,7 @@ static inline void set_file_data(uint8_t* p, unsigned n) g_file_data.len = n; } +// FIXIT-L event trace should be placed in its own files void EventTrace_Init(void); void EventTrace_Term(void); diff --git a/src/detection/dev_notes.txt b/src/detection/dev_notes.txt new file mode 100644 index 000000000..e92b33979 --- /dev/null +++ b/src/detection/dev_notes.txt @@ -0,0 +1,194 @@ +Rules are grouped by ports and services. An MPSE instance is created for: + +* protocol and source port(s) +* protocol and dest ports(s) +* protocol any ports +* service to server +* service to client + +For each fast pattern match state, a detection option tree is created which +allows Snort to efficiently evaluate a set of rules. The non-leaf nodes in +this tree reference an IpsOption instance. The leaf nodes are OTNs, which +represents the rule body. Attached to the OTN is one or more RTNs, which +represent the rule head. There is one RTN for each policy in which the +rule appears. (There is just one instance of each unique RTN in each +policy to save space.) The RTN criteria are evaluated last to determine if +an event should be generated. + +Note that the fast pattern detection code refers to qualified events and +non-qualified events. The latter are just fast pattern hits for which +no rule fired. The former are fast pattern hits for which a rule actually +fired. + +Rules w/o fast patterns are grouped per the above and evaluated for each +packet for which the group is selected. These are definitely bad for +performance. + +The following was written by Norton and Roelker on 2002/05/15 and predates +the use of services but is still applicable. + +*Fast Packet Classification for Rule and Pattern Matching in SNORT* + +* Marc Norton +* Dan Roelker + +A simple method for grouping rules into lists and looking them up quickly +in realtime. + +There is a natural problem when aggregating rules into pattern groups for +performing multi-pattern matching not seen with single pattern Boyer-Moore +strategies. The problem is how to group the rules efficiently when +considering that there are multiple parameters which govern what rules to +apply to each packet or connection. The parameters sip, dip, sport, dport, +and flags form an enormous address space of possible packets that must be +tested in realtime against a subset of rule patterns. Methods to group +patterns precisely based on all of these parameters can quickly become +complicated by both algorithmic implications and implementation details. +The procedure described herein is quick and simple. + +The methodology presented here to solve this problem is based on the +premise that we can use the source and destination ports to isolate pattern +groups for pattern matching, and rely on an event validation procedure to +authenticate other parameters such as sip, dip and flags after a pattern +match is made. An instrinsic assumption here is that most sip and dip +values will be acceptable and that the big gain in performance is due to +the fact that by isolating traffic based on services (ports) we gain the +most benefit. Additionally, and just as important, is the requirement that +we can perform a multi-pattern recognition-inspection phase on a large set +of patterns many times quicker than we can apply a single pattern test +against many single patterns. + +The current implementation assumes that for each rule the src and dst ports +each have one of 2 possible values. Either a specific port number or the +ANYPORT designation. This does allow us to handle port ranges and NOT port +rules as well. + +We make the following assumptions about classifying packets based on ports: + +1. There are Unique ports which represent special services. For example, + ports 21,25,80,110,etc. + +2. Patterns can be grouped into Unique Pattern groups, and a Generic + Pattern Group + + a. Unique pattern groups exist for source ports 21,25,80,110,etc. + b. Unique pattern groups exist for destination ports 21,25,80,etc. + c. A Generic pattern group exists for rules applied to every + combination of source and destination ports. + +We make the following assumptions about packet traffic: + +1. Well behaved traffic has one Unique port and one ephemeral port for + most packets and sometimes legitimately, as in the case of DNS, has + two unique ports that are the same. But we always determine that + packets with two different but Unique ports is bogus, and should + generate an alert. For example, if you have traffic going from + port 80 to port 20. + +2. In fact, state could tell us which side of this connection is a + service and which side is a client. Than we could handle this packet + more precisely, but this is a rare situation and is still bogus. We + can choose not to do pattern inspections on these packets or to do + complete inspections. + +Rules are placed into each group as follows: + +1. Src Port == Unique Service, Dst Port == ANY -> Unique Src Port Table + Src Port == Unique Service, Dst Port == + Unique -> Unique Src & Dst Port Tables +2. Dst Port == Unqiue Service, Src Port == ANY -> Unique Dst Port Table + Dst Port == Unqiue Service, Src Port == + Unique -> Unique Dst & Src Port Tables +3. Dst Port == ANY, Src Port == ANY -> Generic Rule Set, + And add to all Unique Src/Dst Rule Sets that have entries +4. !Dst or !Src Port is the same as ANY Dst or ANY Src port respectively +5. DstA:DstB is treated as an ANY port group, same for SrcA:SrcB + +*Initialization* + +For each rule check the dst-port, if it's specific, then add it to the dst +table. If the dst-port is Any port, then do not add it to the dst port +table. Repeat this for the src-port. + +If the rule has Any for both ports then it's added generic rule list. + +Also, fill in the Unique-Conflicts array, this indicates if it's OK to have +the same Unique service port for both destination and source. This will +force an alert if it's not ok. We optionally pattern match against this +anyway. + +*Processing Rules* + +When packets arrive: + +1. Categorize the Port Uniqueness: + + a. Check the DstPort[DstPort] for possible rules, + if no entry,then no rules exist for this packet with this destination. + + b. Check the SrcPort[SrcPort] for possible rules, + if no entry,then no rules exist for this packet with this source. + +2. Process the Uniqueness: + + If a AND !b has rules or !a AND b has rules then + match against those rules + + If a AND b have rules then + if( sourcePort != DstPort ) + Alert on this traffic and optionally match both rule sets + else if( SourcePort == DstPort ) + Check the Unique-Conflicts array for allowable conflicts + if( NOT allowed ) + Alert on this traffic, optionally match the rules + else + match both sets of rules against this traffic + + If( !a AND ! b ) then + Pattern Match against the Generic Rules ( these apply to all packets) + + +*Pseudocode* + + PORT_RULE_MAP * prm; + PortGroup *src, *dst, *generic; + + RULE * prule; //user defined rule structure for user rules + + prm = prmNewMap(); + + for( each rule ) + { + prule = ....get a rule pointer + + prmAddRule( prm, prule->dport, prule->sport, prule ); + } + + prmCompileGroups( prm ); + + while( sniff-packets ) + { + .... + + stat = prmFindRuleGroup( prm, dport, sport, &src, &dst, &generic ); + switch( stat ) + { + case 0: // No rules at all + break; + case 1: // Dst Rules + // pass 'dst->pgPatData', 'dst->pgPatDataUri' to the pattern engine + break; + case 2: // Src Rules + // pass 'src->pgPatData', 'src->pgPatDataUri' to the pattern engine + break; + case 3: // Src/Dst Rules - Both ports represent Unique service ports + // pass 'src->pgPatData' ,'src->pgPatDataUri' to the pattern engine + // pass 'dst->pgPatData' 'src->pgPatDataUri' to the pattern engine + break; + case 4: // Generic Rules Only + // pass 'generic->pgPatData' to the pattern engine + // pass 'generic->pgPatDataUri' to the pattern engine + break; + } + } + diff --git a/src/detection/fp_config.h b/src/detection/fp_config.h index 752372edd..92b61e77a 100644 --- a/src/detection/fp_config.h +++ b/src/detection/fp_config.h @@ -17,15 +17,16 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// fp_config.h is derived from fp_create.h by: -/* -** Dan Roelker -** Marc Norton -*/ +// fp_config.h is derived from fpcreate.h by: +// +// Dan Roelker +// Marc Norton #ifndef FP_CONFIG_H #define FP_CONFIG_H +// this is a basically a factory for creating MPSE + #define PL_BLEEDOVER_WARNINGS_ENABLED 0x01 #define PL_DEBUG_PRINT_NC_DETECT_RULES 0x02 #define PL_DEBUG_PRINT_RULEGROUP_BUILD 0x04 diff --git a/src/detection/fp_create.cc b/src/detection/fp_create.cc index bdc84b3f6..bc2d3bdc7 100644 --- a/src/detection/fp_create.cc +++ b/src/detection/fp_create.cc @@ -1206,9 +1206,9 @@ static int fpCreatePortTablePortGroups( if (fp->get_debug_print_rule_group_build_details()) LogMessage("%d Port Groups in Port Table\n",p->pt_mpo_hash->count); - for (node=sfghash_findfirst(p->pt_mpo_hash); //p->pt_mpxo_hash + for (node=sfghash_findfirst(p->pt_mpo_hash); // p->pt_mpxo_hash node; - node=sfghash_findnext(p->pt_mpo_hash) ) //p->pt->mpxo_hash + node=sfghash_findnext(p->pt_mpo_hash) ) // p->pt->mpxo_hash { PortObject2* po = (PortObject2*)node->data; @@ -1456,7 +1456,7 @@ void fpWalkOtns(int enabled, OtnWalkFcn fcn) if ( is_network_protocol(rtn->proto) ) { - //do operation + // do operation if ( enabled && !otn->enabled ) continue; diff --git a/src/detection/fp_create.h b/src/detection/fp_create.h index c666cd6d2..434fa618e 100644 --- a/src/detection/fp_create.h +++ b/src/detection/fp_create.h @@ -16,23 +16,18 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Dan Roelker -** Marc Norton -** -** NOTES -** 5.7.02 - Initial Sourcecode. Norton/Roelker -** 6/13/05 - marc norton -** Added plugin support for fast pattern match data -*/ + +// fp_create.h is derived from fpcreate.h by: +// +// Dan Roelker +// Marc Norton + #ifndef FPCREATE_H #define FPCREATE_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// this is where rule groups are compiled and MPSE are instantiated -#include "pcrm.h" +#include "detection/pcrm.h" #include "target_based/snort_protocols.h" struct SnortConfig; diff --git a/src/detection/fp_detect.cc b/src/detection/fp_detect.cc index 97c2e398a..5bb813a94 100644 --- a/src/detection/fp_detect.cc +++ b/src/detection/fp_detect.cc @@ -83,6 +83,8 @@ THREAD_LOCAL ProfileStats ruleRTNEvalPerfStats; THREAD_LOCAL ProfileStats ruleOTNEvalPerfStats; #endif +THREAD_LOCAL uint64_t rule_eval_pkt_count = 0; + THREAD_LOCAL OTNX_MATCH_DATA t_omd; /* initialize the global OTNX_MATCH_DATA variable */ diff --git a/src/detection/fp_detect.h b/src/detection/fp_detect.h index 59d389ab8..0e7b26a08 100644 --- a/src/detection/fp_detect.h +++ b/src/detection/fp_detect.h @@ -16,23 +16,25 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Dan Roelker -** Marc Norton -** -** NOTES -** 5.15.02 - Initial Source Code. Norton/Roelker -*/ + +// fp_detect.h is derived from fpdetect.h by: +// +// Dan Roelker +// Marc Norton #ifndef FPDETECT_H #define FPDETECT_H +// this is where the high-level fast pattern matching action is +// rule groups are selected based on traffic and any fast pattern +// matches trigger rule tree evaluation. + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "fp_create.h" -#include "snort_debug.h" +#include "detection/fp_create.h" +#include "main/snort_debug.h" #include "protocols/packet.h" #include "time/profiler.h" #include "utils/sflsq.h" @@ -68,13 +70,13 @@ int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports); ** and iMatchIndex gets set to the event that holds the ** highest priority. */ -typedef struct +struct MATCH_INFO { OptTreeNode* MatchArray[MAX_EVENT_MATCH]; int iMatchCount; int iMatchIndex; int iMatchMaxLen; -}MATCH_INFO; +}; /* ** OTNX_MATCH_DATA @@ -85,7 +87,7 @@ typedef struct ** the event to log based on the event comparison ** function. */ -typedef struct +struct OTNX_MATCH_DATA { PortGroup* pg; Packet* p; @@ -93,7 +95,7 @@ typedef struct MATCH_INFO* matchInfo; int iMatchInfoArraySize; -} OTNX_MATCH_DATA; +}; void otnx_match_data_init(int); void otnx_match_data_term(); @@ -101,8 +103,9 @@ void otnx_match_data_term(); int fpAddMatch(OTNX_MATCH_DATA* omd_local, int pLen, OptTreeNode* otn); OptTreeNode* GetOTN(uint32_t gid, uint32_t sid); -#define TO_SERVER 1 -#define TO_CLIENT 0 +/* counter for number of times we evaluate rules. Used to + * cache result of check for rule option tree nodes. */ +extern THREAD_LOCAL uint64_t rule_eval_pkt_count; #endif diff --git a/src/detection/pcrm.cc b/src/detection/pcrm.cc index 894cb9ab8..3b468329a 100644 --- a/src/detection/pcrm.cc +++ b/src/detection/pcrm.cc @@ -18,6 +18,7 @@ //-------------------------------------------------------------------------- /* +** -------------------------------------------------------------------------- ** Marc Norton ** Dan Roelker ** @@ -29,167 +30,6 @@ ** ** A Fast Packet Classification method for Rule and Pattern Matching in SNORT ** -------------------------------------------------------------------------- -** -** A simple method for grouping rules into lists and looking them up quickly -** in realtime. -** -** There is a natural problem when aggregating rules into pattern groups for -** performing multi-pattern matching not seen with single pattern Boyer-Moore -** strategies. The problem is how to group the rules efficiently when -** considering that there are multiple parameters which govern what rules to -** apply to each packet or connection. The paramters, sip, dip, sport, dport, -** and flags form an enormous address space of possible packets that -** must be tested in realtime against a subset of rule patterns. Methods to -** group patterns precisely based on all of these parameters can quickly -** become complicated by both algorithmic implications and implementation -** details. The procedure described herein is quick and simple. -** -** The methodology presented here to solve this problem is based on the -** premise that we can use the source and destination ports to isolate -** pattern groups for pattern matching, and rely on an event validation -** procedure to authenticate other parameters such as sip, dip and flags after -** a pattern match is made. An instrinsic assumption here is that most sip -** and dip values will be acceptable and that the big gain in performance -** is due to the fact that by isolating traffic based on services (ports) -** we gain the most benefit. Additionally, and just as important, is the -** requirement that we can perform a multi-pattern recognition-inspection phase -** on a large set of patterns many times quicker than we can apply a single -** pattern test against many single patterns. -** -** The current implementation assumes that for each rule the src and dst ports -** each have one of 2 possible values. Either a specific port number or the -** ANYPORT designation. This does allow us to handle port ranges and NOT port -** rules as well. -** -** We make the following assumptions about classifying packets based on ports: -** -** 1) There are Unique ports which represent special services. For example, -** ports 21,25,80,110,etc. -** -** 2) Patterns can be grouped into Unique Pattern groups, and a Generic -** Pattern Group -** a) Unique pattern groups exist for source ports 21,25,80,110,etc. -** b) Unique pattern groups exist for destination ports 21,25,80,etc. -** c) A Generic pattern group exists for rules applied to every -** combination of source and destination ports. -** -** We make the following assumptions about packet traffic: -** -** 1) Well behaved traffic has one Unique port and one ephemeral port for -** most packets and sometimes legitimately, as in the case of DNS, has -** two unique ports that are the same. But we always determine that -** packets with two different but Unique ports is bogus, and should -** generate an alert. For example, if you have traffic going from -** port 80 to port 20. -** -** 2) In fact, state could tell us which side of this connection is a -** service and which side is a client. Than we could handle this packet -** more precisely, but this is a rare situation and is still bogus. We -** can choose not to do pattern inspections on these packets or to do -** complete inspections. -** -** Rules are placed into each group as follows: -** -** 1) Src Port == Unique Service, Dst Port == ANY -> Unique Src Port Table -** Src Port == Unique Service, Dst Port == -** Unique -> Unique Src & Dst Port Tables -** 2) Dst Port == Unqiue Service, Src Port == ANY -> Unique Dst Port Table -** Dst Port == Unqiue Service, Src Port == -** Unique -> Unique Dst & Src Port Tables -** 3) Dst Port == ANY, Src Port == ANY -> Generic Rule Set, -** And add to all Unique Src/Dst Rule Sets that have entries -** 4) !Dst or !Src Port is the same as ANY Dst or ANY Src port respectively -** 5) DstA:DstB is treated as an ANY port group, same for SrcA:SrcB -** -** Initialization -** -------------- -** For each rule check the dst-port, if it's specific, then add it to the -** dst table. If the dst-port is Any port, then do not add it to the dst -** port table. Repeat this for the src-port. -** -** If the rule has Any for both ports then it's added generic rule list. -** -** Also, fill in the Unique-Conflicts array, this indicates if it's OK to have -** the same Unique service port for both destination and source. This will -** force an alert if it's not ok. We optionally pattern match against this -** anyway. -** -** Processing Rules -** ----------------- -** When packets arrive: -** -** Categorize the Port Uniqueness: -** -** a)Check the DstPort[DstPort] for possible rules, -** if no entry,then no rules exist for this packet with this destination. -** -** b)Check the SrcPort[SrcPort] for possible rules, -** if no entry,then no rules exist for this packet with this source. -** -** Process the Uniqueness: -** -** If a AND !b has rules or !a AND b has rules then -** match against those rules -** -** If a AND b have rules then -** if( sourcePort != DstPort ) -** Alert on this traffic and optionally match both rule sets -** else if( SourcePort == DstPort ) -** Check the Unique-Conflicts array for allowable conflicts -** if( NOT allowed ) -** Alert on this traffic, optionally match the rules -** else -** match both sets of rules against this traffic -** -** If( !a AND ! b ) then -** Pattern Match against the Generic Rules ( these apply to all packets) -** -** -** example.c -** --------- -** -** PORT_RULE_MAP * prm; -** PortGroup *src, *dst, *generic; -** -** RULE * prule; //user defined rule structure for user rules -** -** prm = prmNewMap(); -** -** for( each rule ) -** { -** prule = ....get a rule pointer -** -** prmAddRule( prm, prule->dport, prule->sport, prule ); -** } -** -** prmCompileGroups( prm ); -** -** while( sniff-packets ) -** { -** .... -** -** stat = prmFindRuleGroup( prm, dport, sport, &src, &dst, &generic ); -** switch( stat ) -** { -** case 0: // No rules at all -** break; -** case 1: // Dst Rules -** // pass 'dst->pgPatData', 'dst->pgPatDataUri' to the pattern engine -** break; -** case 2: // Src Rules -** // pass 'src->pgPatData', 'src->pgPatDataUri' to the pattern engine -** break; -** case 3: // Src/Dst Rules - Both ports represent Unique service ports -** // pass 'src->pgPatData' ,'src->pgPatDataUri' to the pattern engine -** // pass 'dst->pgPatData' 'src->pgPatDataUri' to the pattern engine -** break; -** case 4: // Generic Rules Only -** // pass 'generic->pgPatData' to the pattern engine -** // pass 'generic->pgPatDataUri' to the pattern engine -** break; -** } -** } -** */ #include "pcrm.h" diff --git a/src/detection/pcrm.h b/src/detection/pcrm.h index 7caeea413..4bed0bd0c 100644 --- a/src/detection/pcrm.h +++ b/src/detection/pcrm.h @@ -16,15 +16,19 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Marc Norton -** Dan Roelker -** -** Packet Classification-Rule Manager -*/ + +// pcrm.h is a heavily refactored version of work by: +// +// Marc Norton +// Dan Roelker + #ifndef PCRM_H #define PCRM_H +// Packet Classification-Rule Manager +// runle groups by source and dest ports as well as any +// (generic refers to any) + #include "protocols/packet.h" #include "ports/port_group.h" diff --git a/src/detection/rule_option_types.h b/src/detection/rule_option_types.h index 79e7a7d47..0108f0503 100644 --- a/src/detection/rule_option_types.h +++ b/src/detection/rule_option_types.h @@ -20,12 +20,18 @@ #ifndef RULE_OPTION_TYPES_H #define RULE_OPTION_TYPES_H +// RULE_OPTION_* is what is left from the original code which gave each +// option a unique type. the goal is put everything in the 'other' +// category which means they are handled generically and this whole type +// can be eliminated. however, content, flowbits, and pcre still +// require special handling. + enum option_type_t { RULE_OPTION_TYPE_LEAF_NODE, RULE_OPTION_TYPE_CONTENT, RULE_OPTION_TYPE_FLOWBIT, - RULE_OPTION_TYPE_IP_PROTO, + RULE_OPTION_TYPE_IP_PROTO, // FIXIT-L this can be converted to other now RULE_OPTION_TYPE_PCRE, RULE_OPTION_TYPE_OTHER }; diff --git a/src/detection/rules.h b/src/detection/rules.h index 3211e4511..ef920c15b 100644 --- a/src/detection/rules.h +++ b/src/detection/rules.h @@ -21,9 +21,8 @@ #ifndef RULES_H #define RULES_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// misc rule and rule list support +// FIXIT-L refactor this header #include "main/snort_types.h" #include "actions/actions.h" @@ -59,6 +58,7 @@ struct ListHead struct RuleListNode* ruleListNode; }; +// for top-level rule lists by type (alert, drop, etc.) struct RuleListNode { ListHead* RuleList; /* The rule list associated with this node */ @@ -68,6 +68,7 @@ struct RuleListNode RuleListNode* next; /* the next RuleListNode */ }; +// for separately overriding rule type struct RuleState { uint32_t sid; diff --git a/src/detection/service_map.h b/src/detection/service_map.h index f1db8d2a4..a920b3fa3 100644 --- a/src/detection/service_map.h +++ b/src/detection/service_map.h @@ -18,18 +18,16 @@ //-------------------------------------------------------------------------- // service_map.h based fp_create.h by: -/* -** Dan Roelker -** Marc Norton -** -** NOTES -** 5.7.02 - Initial Sourcecode. Norton/Roelker -** 6/13/05 - marc norton -** Added plugin support for fast pattern match data -*/ +// +// Dan Roelker +// Marc Norton + #ifndef SERVICE_MAP_H #define SERVICE_MAP_H +// for managing rule groups by service +// direction to client and to server are separate + #include #include "detection/pcrm.h" diff --git a/src/detection/sfrim.cc b/src/detection/sfrim.cc index fcab926d7..c0f0f14be 100644 --- a/src/detection/sfrim.cc +++ b/src/detection/sfrim.cc @@ -17,130 +17,96 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// sfrim.c author Marc Norton +// modified to use a vector w/o a hard max + #include "sfrim.h" -/* - * sfrim.c - * - * Rule Index Map - * - * author: marc norton - * - */ +#include #include #include -/* - * Return Sid associated with index - * author: marc norton - */ -unsigned RuleIndexMapSid(rule_index_map_t* map, int index) +#include + +#include "utils/util.h" + +struct rule_number_t { - if ( !map ) - return 0; + unsigned gid; + unsigned sid; - if ( index < map->num_rules ) - { - return map->map[index].sid; - } - return 0; + rule_number_t(unsigned g, unsigned s) + { gid = g; sid = s; } +}; + +struct rule_index_map_t +{ + std::vector map; +}; + +rule_index_map_t* RuleIndexMapCreate() +{ + rule_index_map_t* rim = new rule_index_map_t; + return rim; } -/* - * Return Gid associated with index - * author: marc norton - */ -unsigned RuleIndexMapGid(rule_index_map_t* map, int index) +void RuleIndexMapFree(rule_index_map_t* rim) { - if ( !map ) - { - return 0; - } - if ( index < map->num_rules ) - { - return map->map[index].gid; - } - return 0; + assert(rim); + delete rim; } -/* - * Create a rule index map table - * author: marc norton - */ -rule_index_map_t* RuleIndexMapCreate(int max_rules) +int RuleIndexMapAdd(rule_index_map_t* rim, unsigned gid, unsigned sid) { - rule_index_map_t* p = (rule_index_map_t*)calloc(1, sizeof(rule_index_map_t) ); - if (!p) - { - return 0; - } - p->max_rules=max_rules; - p->num_rules=0; - p->map = (rule_number_t*)calloc(max_rules, sizeof(rule_number_t)); - if (!p->map ) - { - free(p); - return 0; - } - return p; + assert(rim); + + rule_number_t rn(gid, sid); + int index = rim->map.size(); + rim->map.push_back(rn); + + //printf("RuleIndexMapping: index=%d gid=%u sid=%u\n",index,gid,sid); + return index; } -/* - * Free a rule index map table - * author: marc norton - */ -void RuleIndexMapFree(rule_index_map_t** p) +unsigned RuleIndexMapSid(rule_index_map_t* rim, int index) { - if ( !p || !*p ) + if ( rim and (unsigned)index < rim->map.size() ) { - return; + return rim->map[index].sid; } - if ( (*p)->map ) - { - free((*p)->map); - } - free(*p); - - *p = 0; + return 0; } -/* - * Add a rule to a rule index map table - * author: marc norton - */ -int RuleIndexMapAdd(rule_index_map_t* p, unsigned gid, unsigned sid) +unsigned RuleIndexMapGid(rule_index_map_t* rim, int index) { - int index; + assert(rim); - if ( !p ) + if ( (unsigned)index < rim->map.size() ) { - return -1; + return rim->map[index].gid; } - if ( p->num_rules == (p->max_rules - 1) ) + return 0; +} + +void print_rule_index_map(rule_index_map_t* rim) +{ + assert(rim); + printf("***\n*** Rule Index Map (%lu entries)\n***\n",rim->map.size()); + + for (unsigned i=0; imap.size(); i++) { - return -1; + printf("rule-index-map[%d] { gid:%u sid:%u }\n", + i,rim->map[i].gid,rim->map[i].sid); } - index = p->num_rules; - p->map[ index ].gid = gid; - p->map[ index ].sid = sid; - p->num_rules++; - - //printf("RuleIndexMapping: index=%d gid=%u sid=%u\n",index,gid,sid); - return index; + printf("***end rule index map ***\n"); } -/* - * print a rule index map table to stdout - * author: marc norton - */ -void print_rule_index_map(rule_index_map_t* p) +void rule_index_map_print_index(rule_index_map_t* rim, int index, char* buf, int bufsize) { - int i; - printf("***\n*** Rule Index Map (%d entries)\n***\n",p->num_rules); - for (i=0; inum_rules; i++) + if ( (unsigned)index < rim->map.size() ) { - printf("rule-index-map[%d] { gid:%u sid:%u }\n",i,p->map[i].gid,p->map[i].sid); + SnortSnprintfAppend(buf, bufsize, "%u:%u ", + rim->map[index].gid, rim->map[index].sid); } - printf("***end rule index map ***\n"); } diff --git a/src/detection/sfrim.h b/src/detection/sfrim.h index a16a3657d..cdd2a2386 100644 --- a/src/detection/sfrim.h +++ b/src/detection/sfrim.h @@ -17,32 +17,26 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * Rule Index Map - * - * author: marc norton - */ +// sfrim.h author Marc Norton + #ifndef SFRIM_H #define SFRIM_H -typedef struct -{ - unsigned gid; - unsigned sid; -}rule_number_t; +// provides an ordinal for each rule so they can be looked up by a number +// used during parse time when rules are compiled + +struct rule_index_map_t; -typedef struct -{ - int max_rules; - int num_rules; - rule_number_t* map; -}rule_index_map_t; +rule_index_map_t* RuleIndexMapCreate(); +void RuleIndexMapFree(rule_index_map_t*); + +int RuleIndexMapAdd(rule_index_map_t*, unsigned gid, unsigned sid); unsigned RuleIndexMapSid(rule_index_map_t* map, int index); unsigned RuleIndexMapGid(rule_index_map_t* map, int index); -rule_index_map_t* RuleIndexMapCreate(int max_rules); -void RuleIndexMapFree(rule_index_map_t** p); -int RuleIndexMapAdd(rule_index_map_t* p, unsigned gid, unsigned sid); + +void print_rule_index_map(rule_index_map_t*); +void rule_index_map_print_index(rule_index_map_t*, int index, char* buf, int bufsize); #endif diff --git a/src/detection/signature.h b/src/detection/signature.h index f300edc4c..219b99b49 100644 --- a/src/detection/signature.h +++ b/src/detection/signature.h @@ -16,13 +16,13 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// Author(s): Andrew R. Baker + +// signature.h author Andrew R. Baker + #ifndef SIGNATURE_H #define SIGNATURE_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// basic non-detection signature info: gid, sid, rev, class, priority, etc. #include #include @@ -94,11 +94,10 @@ struct SigInfo ClassType* classType; uint32_t priority; char* message; - ReferenceNode* refs; + ReferenceNode* refs; // FIXIT-L delete this - stored but not used bool text_rule; unsigned int num_services; ServiceInfo* services; - const char* os; }; SFGHASH* OtnLookupNew(void); @@ -110,5 +109,5 @@ void OtnRemove(SFGHASH*, OptTreeNode*); void OtnDeleteData(void* data); void OtnFree(void* data); -#endif /* SIGNATURE */ +#endif diff --git a/src/detection/tag.h b/src/detection/tag.h index 5ecfa4b79..b50175372 100644 --- a/src/detection/tag.h +++ b/src/detection/tag.h @@ -21,9 +21,11 @@ #ifndef TAG_H #define TAG_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// rule option tag causes logging of some number of subsequent packets +// following an alert. this module is use by the tag option to implement +// that functionality. uses its own hash table. +// +// FIXIT-L convert tags to use flow instead of hash table. #include diff --git a/src/detection/treenodes.h b/src/detection/treenodes.h index a7eeda67e..def8b356f 100644 --- a/src/detection/treenodes.h +++ b/src/detection/treenodes.h @@ -20,12 +20,13 @@ #ifndef TREENODES_H #define TREENODES_H +// rule header (RTN) and body (OTN) nodes + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "main/snort_types.h" - #include "detection/signature.h" #include "detection/rule_option_types.h" #include "actions/actions.h" @@ -70,6 +71,8 @@ struct OtnState uint64_t ppm_disable_cnt; }; +// one of these for each rule +// represents body part of rule struct OptTreeNode { /* plugin/detection functions go here */ @@ -86,7 +89,7 @@ struct OptTreeNode OptTreeNode* next; - /* ptr to list of RTNs (head part) */ + // ptr to list of RTNs (head part); indexed by policyId RuleTreeNode** proto_nodes; OtnState* state; @@ -119,6 +122,8 @@ struct OptTreeNode }; /* function pointer list for rule head nodes */ +// FIXIT-L use bit mask to determine what header checks to do +// cheaper than traversing a list and uses much less memory struct RuleFpList { /* context data for this test */ @@ -131,6 +136,8 @@ struct RuleFpList RuleFpList* next; }; +// one of these per rule per policy +// represents head part of rule struct RuleTreeNode { RuleFpList* rule_func; /* match functions.. (Bidirectional etc.. ) */ @@ -149,9 +156,8 @@ struct RuleTreeNode RuleType type; - /**reference count from otn. Multiple OTNs can reference this RTN with the same - * policy. - */ + // reference count from otn. + // Multiple OTNs can reference this RTN with the same policy. unsigned int otnRefCount; }; diff --git a/src/dev_notes.txt b/src/dev_notes.txt new file mode 100644 index 000000000..62f905a88 --- /dev/null +++ b/src/dev_notes.txt @@ -0,0 +1,25 @@ +This directory contains the program entry point, thread management, and +control functions. + +* The main / foreground thread services control inputs from signals, the + command line shell (if enabled), etc. + +* The packet / background threads service one input source apiece. + +The main_loop() starts a new Pig when a new source (interface or pcap, +etc.) is available if the number of running Pigs is less than configured. + +It also does housekeeping functions like servicing signal flags, shell +commands, etc. + +The shell has to be explicitly enabled at build time to be available and +then must be configured at run time to be activated. Presently only one +remote shell at a time is supported. + +Unit test and piglet test harness build options also impact actual +execution. + +Reload is implemented by swapping a thread local config pointer by each +running Pig. The inspector manager is called to empty trash if the main +loop is not otherwise busy. + diff --git a/src/events/dev_notes.txt b/src/events/dev_notes.txt new file mode 100644 index 000000000..70a281699 --- /dev/null +++ b/src/events/dev_notes.txt @@ -0,0 +1,12 @@ +This unit manages the event queue. Widely used utility GenerateSnortEvent() is +in event_wrapper.h. + +The event queue has a configurable maximum number of events, which are +preallocated and stored in a linked list. + +There are multiple instances of the event queue accessed via a simple +stack. A push is done before processing a rebuilt packet or rebuilt +payload after which a pop is done. During that time any wire packet events +are still pending in the event queue higher up the stack. This ensures +that the events for each packet (wire or rebuilt) are processed separately. + diff --git a/src/events/event.h b/src/events/event.h index 31c26a459..48ed5308f 100644 --- a/src/events/event.h +++ b/src/events/event.h @@ -18,7 +18,6 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* D E F I N E S ************************************************************/ #ifndef EVENT_H #define EVENT_H @@ -42,16 +41,14 @@ struct sf_timeval32 struct Event { const SigInfo* sig_info; - uint32_t event_id; /* event ID */ - uint32_t event_reference; /* reference to other events that have gone off, - * such as in the case of tagged packets... - */ + uint32_t event_id; + uint32_t event_reference; // reference to other events that have gone off, + // such as in the case of tagged packets... struct sf_timeval32 ref_time; /* reference time for the event reference */ const char* alt_msg; }; -void SetEvent( -Event*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); +void SetEvent(Event*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); #endif diff --git a/src/file_api/circular_buffer.h b/src/file_api/circular_buffer.h index cac581afd..ea377d23b 100644 --- a/src/file_api/circular_buffer.h +++ b/src/file_api/circular_buffer.h @@ -16,113 +16,59 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - ** Circular buffer is thread safe for one writer and one reader thread - ** - ** This implementation is inspired by one slot open approach. - ** See http://en.wikipedia.org/wiki/Circular_buffer - ** - ** Author(s): Hui Cao - ** - ** NOTES - ** 5.25.13 - Initial Source Code. Hui Cao - */ + +// circular_buffer.h author Hui Cao #ifndef CIRCULAR_BUFFER_H #define CIRCULAR_BUFFER_H +// Circular buffer is thread safe for one writer and one reader thread +// This implementation is inspired by one slot open approach. +// See http://en.wikipedia.org/wiki/Circular_buffer + +// FIXIT-L use bool or enum #define CB_SUCCESS 0 #define CB_FAIL -1 -/* Opaque buffer element type. This would be defined by the application. */ +// Opaque buffer element type. This would be defined by the application. typedef void* ElemType; struct _CircularBuffer; typedef struct _CircularBuffer CircularBuffer; -/* - * Initialize buffer based on number of elements - * - * Args: - * uint64_t size: number of elements * - * Return: - * CircularBuffer *: pointer to the buffer - * NULL: failed - * - */ +// Initialize buffer based on number of elements CircularBuffer* cbuffer_init(uint64_t size); -/* Release all memory used*/ void cbuffer_free(CircularBuffer* cb); -/* - * Check whether buffer is full - * - * Return: - * 1: full - * 0: not full - */ +// FIXIT-L use bool int cbuffer_is_full(CircularBuffer* cb); -/* - * Check whether buffer is empty - * - * Return: - * 1: empty - * 0: not empty - */ +// FIXIT-L use bool int cbuffer_is_empty(CircularBuffer* cb); -/* Returns number of elements in use*/ +// Returns number of elements in use uint64_t cbuffer_used(CircularBuffer* cb); -/* Returns number of free elements*/ +// Returns number of free elements uint64_t cbuffer_available(CircularBuffer* cb); -/* Returns total number of elements*/ +// Returns total number of elements uint64_t cbuffer_size(CircularBuffer* cb); -/* - * Add one element to the buffer - * - * Args: - * CircularBuffer *: buffer - * ElemType elem: the element to be added - * Return: - * CB_FAIL - * CB_SUCCESS - */ +// Returns CB_SUCCESS or CB_FAIL int cbuffer_write(CircularBuffer* cb, const ElemType elem); -/* - * Read one element from the buffer and remove it from buffer - * - * Args: - * CircularBuffer *: buffer - * ElemType *elem: the element pointer to be stored - * Return: - * CB_FAIL - * CB_SUCCESS - */ +// Read one element from the buffer and remove it from buffer +// Returns CB_SUCCESS or CB_FAIL int cbuffer_read(CircularBuffer* cb, ElemType* elem); -/* - * Read one element from the buffer and no change on buffer - * - * Args: - * CircularBuffer *: buffer - * ElemType *elem: the element pointer to be stored - * Return: - * CB_FAIL - * CB_SUCCESS - */ - +// Read one element from the buffer and no change on buffer +// Returns CB_SUCCESS or CB_FAIL int cbuffer_peek(CircularBuffer* cb, ElemType* elem); -/* Returns total number of reads*/ uint64_t cbuffer_num_reads(CircularBuffer* cb); -/* Returns total number of writes*/ uint64_t cbuffer_num_writes(CircularBuffer* cb); /* Returns total number of writer overruns*/ diff --git a/src/file_api/dev_notes.txt b/src/file_api/dev_notes.txt new file mode 100644 index 000000000..d18cb136c --- /dev/null +++ b/src/file_api/dev_notes.txt @@ -0,0 +1,15 @@ +This directory contains all the file processing related classes and APIs + +* file_api: provides the interfaces for file processing, used by service +inpsectors such as HTTP, SMTP, POP, IMAP, SMB, and FTP etc. + +* MIME processing: provides the common MIME header and MIME body processing for +service inpsectors such as HTTP, SMTP, POP, and IMAP. If configured, it decodes +file data that are encoded in Base64, UU-encoding, QP-encoding, and Bit-encoding. + +* File capture: provides the ability to capture file data and save them in the +mempool, then they can be stored to disk. + +* File libraries: provides file type identification and file signature +calculation + diff --git a/src/file_api/file_api.h b/src/file_api/file_api.h index b8f45f442..b938d7389 100644 --- a/src/file_api/file_api.h +++ b/src/file_api/file_api.h @@ -16,21 +16,17 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- - -/* file_api.h - * - * Purpose: Definition of the FileAPI. To be used as a common interface - * for file process access for other preprocessors and detection plugins. - * - * Author(s): Hui Cao - * - * NOTES - * 5.25.12 - Initial Source Code. Hui Cao - */ +// file_api.h author Hui Cao +// 5.25.12 - Initial Source Code. Hui Cao #ifndef FILE_API_H #define FILE_API_H +// File API provides all the convenient functions that are used by inspectors. +// Currently, it provides three sets of APIs: file processing, MIME processing, +// and configurations. +// FIXIT-L file api will be replaced by file class and mime class soon + #include #include "stream/stream_api.h" @@ -252,7 +248,7 @@ typedef uint8_t*(*Get_file_sig_sha256_func)(Flow* flow); typedef void (*Set_file_name_func)(Flow* flow, uint8_t*, uint32_t); typedef void (*Set_file_direction_func)(Flow* flow, bool); -typedef int64_t (*Get_file_depth_func)(void); +typedef int64_t (*Get_file_depth_func)(); typedef void (*Set_file_policy_func)(File_policy_callback_func); typedef void (*Enable_file_type_func)(File_type_callback_func); @@ -288,7 +284,7 @@ typedef FileCaptureInfo* (*Get_file_func)(FileCaptureInfo* file_mem, uint8_t** b typedef void (*Release_file_func)(FileCaptureInfo* data); typedef size_t (*File_capture_size_func)(FileCaptureInfo* file_mem); -typedef bool (*Is_file_service_enabled)(void); +typedef bool (*Is_file_service_enabled)(); typedef bool (*Check_paf_abort_func)(Flow* ssn); typedef FilePosition (*GetFilePosition)(Packet* pkt); typedef void (*Reset_mime_paf_state_func)(MimeDataPafInfo* data_info); diff --git a/src/file_api/file_capture.h b/src/file_api/file_capture.h index b80ba1cb0..8ccbdd1e8 100644 --- a/src/file_api/file_capture.h +++ b/src/file_api/file_capture.h @@ -16,17 +16,21 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - ** - ** Author(s): Hui Cao - ** - ** NOTES - ** 5.05.2013 - Initial Source Code. Hui Cao - */ + +// file_capture.h author Hui Cao #ifndef FILE_CAPTURE_H #define FILE_CAPTURE_H +// There are several steps for file capture: +// 1) To improve performance, file data are stored in file mempool first by +// calling file_capture_process() during file data processing. +// 2) If file capture is needed, file_capture_reserve() should be called to +// allow file data remains in mempool. Even if a session is closed, the file +// data will stay in the mempool. +// 3) Then file data can be read through file_capture_read() +// 4) Finally, fila data must be released from mempool file_capture_release() + #include "file_api.h" #include "libs/file_lib.h" @@ -62,104 +66,46 @@ typedef struct _File_Capture_Stats extern File_Capture_Stats file_capture_stats; -/* - * Initialize the file memory pool - * - * Arguments: - * int64_t max_file_mem: memcap in bytes - * int64_t block_size: file block size - * - * Returns: NONE - */ +// this must be called during snort init void file_capture_init_mempool(int64_t max_file_mem, int64_t block_size); -/* - * Capture file data to local buffer - * This is the main function call to enable file capture - * - * Arguments: - * FileContext* context: current file context - * uint8_t *file_data: current file data - * int data_size: current file data size - * FilePosition position: position of file data - * - * Returns: - * 0: successful - * 1: fail to capture the file or file capture is disabled - */ +// Capture file data to local buffer +// This is the main function call to enable file capture +// Returns: +// 0: successful +// 1: fail to capture the file or file capture is disabled int file_capture_process(FileContext* context, uint8_t* file_data, int data_size, FilePosition position); -/* - * Stop file capture, memory resource will be released if not reserved - * - * Returns: NONE - */ +// Stop file capture, memory resource will be released if not reserved void file_capture_stop(FileContext* context); -/* - * Preserve the file in memory until it is released - * - * Arguments: - * Flow *ssnptr: flow pointer - * FileCaptureInfo **file_mem: the pointer to store the memory block - * that stores file and its metadata. - * It will set NULL if no memory or fail to store - * - * Returns: - * FileCaptureState: - * FILE_CAPTURE_SUCCESS = 0, - * FILE_CAPTURE_MIN, - * FILE_CAPTURE_MAX, - * FILE_CAPTURE_MEMCAP, - * FILE_CAPTURE_FAIL - */ +// Preserve the file in memory until it is released FileCaptureState file_capture_reserve(Flow* flow, FileCaptureInfo** file_mem); -/* - * Get the file that is reserved in memory - * - * Arguments: - * FileCaptureInfo *file_mem: the memory block working on - * uint8_t **buff: address to store buffer address - * int *size: address to store size of file - * - * Returns: - * the next memory block - * NULL: end of file or fail to get file - */ +// Get the file that is reserved in memory, this should be called repeatedly +// until NULL is returned to get the full file +// Returns: +// the next memory block +// NULL: end of file or fail to get file FileCaptureInfo* file_capture_read(FileCaptureInfo* file_mem, uint8_t** buff, int* size); -/* - * Get the file size captured in the file buffer - * - * Arguments: - * FileCaptureInfo *file_mem: the first memory block of file buffer - * - * Returns: - * the size of file - * 0: no memory or fail to get file - */ +// Get the file size captured in the file buffer +// Returns: +// the size of file +// 0: no memory or fail to get file size_t file_capture_size(FileCaptureInfo* file_mem); -/* - * Release the file that is reserved in memory, this function might be - * called in a different thread. - * - * Arguments: - * FileCaptureInfo *data: the memory block that stores file and its metadata - */ +// Release the file that is reserved in memory, this function might be +// called in a different thread. void file_capture_release(FileCaptureInfo* data); -/*Log file capture mempool usage*/ - +// Log file capture mempool usage void file_capture_mem_usage(void); -/* - * Exit file capture, release all file capture memory etc, - * this must be called when snort exits - */ -void file_caputure_close(void); +// Exit file capture, release all file capture memory etc, +// this must be called when snort exits + void file_caputure_close(void); #endif diff --git a/src/file_api/file_mempool.h b/src/file_api/file_mempool.h index 4d9526a51..cbeb4cf4d 100644 --- a/src/file_api/file_mempool.h +++ b/src/file_api/file_mempool.h @@ -16,27 +16,22 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - ** - ** Author(s): Hui Cao - ** - ** This mempool implementation has very efficient alloc/free operations. - ** In addition, it provides thread-safe alloc/free for one allocation/free - ** thread and one release thread. - ** One more bonus: Double free detection is also added into this library - ** - ** NOTES - ** 5.25.13 - Initial Source Code. Hui Cao - ** - ** This is a thread safe version of memory pool for one writer and one reader thread - */ + +// file_mempool.h author Hui Cao #ifndef FILE_MEMPOOL_H #define FILE_MEMPOOL_H + // This mempool implementation has very efficient alloc/free operations. + // In addition, it provides thread-safe alloc/free for one allocation/free + // thread and one release thread. + // One more bonus: Double free detection is also added into this library + // This is a thread safe version of memory pool for one writer and one reader thread + #include "snort_types.h" #include "circular_buffer.h" +// FIXIT-L use bool or enum #define FILE_MEM_SUCCESS 0 #define FILE_MEM_FAIL -1 @@ -51,79 +46,34 @@ typedef struct _FileMemPool size_t obj_size; } FileMemPool; -/* Initialize mempool - * - * Args: - * FileMemPool: pointer to a FileMemPool struct - * uint64_t num_objects: number of objects - * size_t obj_size: size of object - * - * Return: - * FILE_MEM_SUCCESS - * FILE_MEM_FAIL - */ -int file_mempool_init(FileMemPool* mempool, uint64_t num_objects, - size_t obj_size); - -/* Free mempool memory objects - * - * Args: - * FileMemPool: pointer to a FileMemPool struct - * - * Return: - * FILE_MEM_SUCCESS - * FILE_MEM_FAIL - */ +// This must be called before file mempool is used +// Return: FILE_MEM_SUCCESS or FILE_MEM_FAIL +int file_mempool_init(FileMemPool* mempool, uint64_t num_objects, size_t obj_size); + +// This must be called during snort exits +// Return: FILE_MEM_SUCCESS or FILE_MEM_FAIL int file_mempool_destroy(FileMemPool* mempool); -/* - * Allocate a new object from the FileMemPool - * Memory block will not be zeroed for performance - * - * Args: - * FileMemPool: pointer to a FileMemPool struct - * - * Returns: a pointer to the FileMemPool object on success, NULL on failure - */ +// Allocate a new object from the FileMemPool +// Note: Memory block will not be zeroed for performance +// Returns: a pointer to the FileMemPool object on success, NULL on failure void* file_mempool_alloc(FileMemPool* mempool); -/* - * Free a new object from the FileMemPool - * This must be called by the same thread calling - * file_mempool_alloc() - * - * Args: - * FileMemPool: pointer to a FileMemPool struct - * void *obj : memory object - * - * Return: - * FILE_MEM_SUCCESS - * FILE_MEM_FAIL - */ +// This must be called by the same thread calling file_mempool_alloc() +// Return: FILE_MEM_SUCCESS or FILE_MEM_FAIL int file_mempool_free(FileMemPool* mempool, void* obj); -/* - * Release a new object from the FileMemPool - * This can be called by a different thread calling - * file_mempool_alloc() - * - * Args: - * FileMemPool: pointer to a FileMemPool struct - * void *obj : memory object - * - * Return: - * FILE_MEM_SUCCESS - * FILE_MEM_FAIL - */ +// This can be called by a different thread calling file_mempool_alloc() +// Return: FILE_MEM_SUCCESS or FILE_MEM_FAIL int file_mempool_release(FileMemPool* mempool, void* obj); -/* Returns number of elements allocated in current buffer*/ +//Returns number of elements allocated in current buffer uint64_t file_mempool_allocated(FileMemPool* mempool); -/* Returns number of elements freed in current buffer*/ +// Returns number of elements freed in current buffer uint64_t file_mempool_freed(FileMemPool* mempool); -/* Returns number of elements released in current buffer*/ +// Returns number of elements released in current buffer uint64_t file_mempool_released(FileMemPool* mempool); #endif diff --git a/src/file_api/file_mime_config.h b/src/file_api/file_mime_config.h index 30402bb72..a888280e5 100644 --- a/src/file_api/file_mime_config.h +++ b/src/file_api/file_mime_config.h @@ -16,17 +16,16 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Author(s): Hui Cao -** -** NOTES -** 9.25.2012 - Initial Source Code. Hui Cao -*/ + +// file_mime_config.h author Hui Cao #ifndef FILE_MIME_CONFIG_H #define FILE_MIME_CONFIG_H -#include "file_api.h" +// List of MIME decode and log configuration functions +// FIXIT-L This will be refactored soon + +#include "file_api/file_api.h" /* Function prototypes */ void set_mime_decode_config_defauts(DecodeConfig*); diff --git a/src/file_api/file_mime_process.h b/src/file_api/file_mime_process.h index c28664363..bc70e1997 100644 --- a/src/file_api/file_mime_process.h +++ b/src/file_api/file_mime_process.h @@ -16,19 +16,19 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Author(s): Hui Cao -** -** NOTES -** 9.25.2012 - Initial Source Code. Hui Cao -*/ + +// file_mime_process.h author Hui Cao #ifndef FILE_MIME_PROCESS_H #define FILE_MIME_PROCESS_H +// Provides list of MIME processing functions. Encoded file data will be decoded +// and file name will be extracted from MIME header +// FIXIT-L This will be refactored soon + #include -#include "file_api.h" -#include "sf_email_attach_decode.h" +#include "file_api/file_api.h" +#include "utils/sf_email_attach_decode.h" #define BOUNDARY 0 diff --git a/src/file_api/file_resume_block.h b/src/file_api/file_resume_block.h index 6d0140d6c..fb807717f 100644 --- a/src/file_api/file_resume_block.h +++ b/src/file_api/file_resume_block.h @@ -16,18 +16,18 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Author(s): Hui Cao -** -** NOTES -** 9.25.2012 - Initial Source Code. Hui Cao -*/ + +// file_resume_block.h author Hui Cao #ifndef FILE_RESUME_BLOCK_H #define FILE_RESUME_BLOCK_H +// If a file transfered through HTTP is blocked, a new session might be created +// to request the file data left. To block the new session, we use URL and IPs +// to continue blocking the same file. + #include "protocols/packet.h" -#include "file_api.h" +#include "file_api/file_api.h" void file_resume_block_init(void); void file_resume_block_cleanup(void); diff --git a/src/file_api/file_service.h b/src/file_api/file_service.h index b0f746cd4..8c001ec0c 100644 --- a/src/file_api/file_service.h +++ b/src/file_api/file_service.h @@ -16,16 +16,15 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Author(s): Hui Cao -** -** NOTES -** 5.25.12 - Initial Source Code. Hui Cao -*/ + +// file_service.h author author Hui Cao #ifndef FILE_SERVICE_H #define FILE_SERVICE_H +// This provides a wrapper to start/stop file API +// FIXIT-L This will be refactored soon + #include "libs/file_lib.h" /* Initialize file API, this must be called when snort restarts */ diff --git a/src/file_api/file_service_config.h b/src/file_api/file_service_config.h index 7368391cb..156be7e59 100644 --- a/src/file_api/file_service_config.h +++ b/src/file_api/file_service_config.h @@ -16,16 +16,17 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Author(s): Hui Cao -** -** NOTES -** 5.25.2012 - Initial Source Code. Hui Cao -*/ + +// file_service_config.h author Hui Cao + #ifndef FILE_SERVICE_CONFIG_H #define FILE_SERVICE_CONFIG_H -#include "file_service.h" + +// FIXIT-L This will be refactored soon +#include "file_api/file_service.h" + /*configure file services*/ void file_service_config(const char* args, void** file_config); + #endif diff --git a/src/file_api/file_stats.h b/src/file_api/file_stats.h index 522369c51..e7c56f9e9 100644 --- a/src/file_api/file_stats.h +++ b/src/file_api/file_stats.h @@ -16,25 +16,23 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - ** - ** Author(s): Hui Cao - ** - ** NOTES - ** 5.25.13 - Initial Source Code. Hui Cao - */ + +// file_stats.h author Hui Cao #ifndef FILE_STATS_H #define FILE_STATS_H +#include +#include + +// FIXIT-L This will be refactored soon + #include "target_based/snort_protocols.h" #include "target_based/sftarget_reader.h" #include "main/snort_debug.h" #include "libs/file_config.h" -#include "file_api.h" -#include -#include +#include "file_api/file_api.h" #define MAX_PROTOCOL_ORDINAL 8192 // FIXIT-L use std::vector and get_protocol_count() diff --git a/src/file_api/libs/file_config.h b/src/file_api/libs/file_config.h index 24aff0fdb..40bdad475 100644 --- a/src/file_api/libs/file_config.h +++ b/src/file_api/libs/file_config.h @@ -16,19 +16,15 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Author(s): Hui Cao -** -** NOTES -** 5.25.2012 - Initial Source Code. Hui Cao -*/ + +// file_config.h author Hui Cao + #ifndef FILE_CONFIG_H #define FILE_CONFIG_H -#include "file_lib.h" -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// This provides the basic configuration for file processing + +#include "file_lib.h" #include "file_identifier.h" #define DEFAULT_FILE_TYPE_DEPTH 1460 diff --git a/src/file_api/libs/file_identifier.h b/src/file_api/libs/file_identifier.h index 326f40f01..0203f9447 100644 --- a/src/file_api/libs/file_identifier.h +++ b/src/file_api/libs/file_identifier.h @@ -16,22 +16,19 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Author(s): Hui Cao -** -** NOTES -** 5.25.2012 - Initial Source Code. Hui Cao -*/ + +// file_identifier.h author Hui Cao #ifndef FILE_IDENTIFIER_H #define FILE_IDENTIFIER_H -#include "file_lib.h" -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "sfghash.h" +// File type identification is based on file magic. To improve the detection +// performance, a trie is created to scan file data once. Currently, only the +// most specific file type is returned. + #include +#include "file_lib.h" +#include "hash/sfghash.h" #define FILE_ID_MAX 1024 diff --git a/src/file_api/libs/file_lib.h b/src/file_api/libs/file_lib.h index 2e39f5728..59aae7d74 100644 --- a/src/file_api/libs/file_lib.h +++ b/src/file_api/libs/file_lib.h @@ -16,21 +16,16 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Author(s): Hui Cao -** -** NOTES -** 5.25.12 - Initial Source Code. Hui Cao -*/ + +// file_lib.h author Hui Cao #ifndef FILE_LIB_H #define FILE_LIB_H +// This will be basis of file class +// FIXIT-L This will be refactored soon #include -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include "file_api/file_api.h" #include "flow/flow.h" diff --git a/src/filters/dev_notes.txt b/src/filters/dev_notes.txt new file mode 100644 index 000000000..73b75091b --- /dev/null +++ b/src/filters/dev_notes.txt @@ -0,0 +1,32 @@ +A collection of several different event and detection filtering function. +The types of filters implemented here include: + +Detection Filter - One of the last steps of the rule evaluation process. A +detection filter can prevent a rule from firing based on a simple +threshold. For example, only generate an alert if the filter has been +evaluated N times in M time period. + +Rate Filter - Based on configuration options, generically track multiple +occurrences of the same event/address tuples. The configuration can +specify a limit where-by if the tracked limit is exceeded, the action of +the event is changed. For instance, the first N occurrences of Event X in +time period Y can Alert, but if this rate is exceeded subsequent occurrence +will Drop. This function can be used to protect against DOS type of +attacks. + +Event Filter - After the rules engine generates whatever actions it needs +to, the Event Filter is then invoked to filter the logging of these events. +Once again, tracking by event/address tuples, block the logging of events +if the configured counts per time is exceeded. This will tend to reduce +the logging system load for rules that fire too often. + +All of the filters in this area are a collection of similar services +brought together to share the same event tracking logic. sfthreshold.cc +implements a generic threshold tracking mechanism using a hash table. This +hash structure permits the various filter/threshold components to build +event tracking facilities. + +Detection filter support the detection_filter rule option. Rate and event +filters have builtin modules defined in main/modules.cc. Those module +definitions should be refactored into the appropriate filter directory. + diff --git a/src/filters/rate_filter.cc b/src/filters/rate_filter.cc index 8bf44aa81..7615b7218 100644 --- a/src/filters/rate_filter.cc +++ b/src/filters/rate_filter.cc @@ -17,16 +17,12 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* @file rate_filter.c - * @brief rate filter interface for Snort - * @ingroup rate_filter - * @author Dilbagh Chahal - */ -/* @ingroup rate_filter - * @{ - */ +// rate_filter.cc author Dilbagh Chahal + #include "rate_filter.h" +// rate filter interface for Snort + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -56,9 +52,7 @@ RateFilterConfig* RateFilter_ConfigNew(void) return rf_config; } -/* Free threshold context - * @param pContext pointer to global threshold context. - */ +/* Free threshold context */ void RateFilter_ConfigFree(RateFilterConfig* config) { int i; diff --git a/src/filters/rate_filter.h b/src/filters/rate_filter.h index 81b689ab1..61adf5330 100644 --- a/src/filters/rate_filter.h +++ b/src/filters/rate_filter.h @@ -17,18 +17,12 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// rate_filter.h author Dilbagh Chahal + #ifndef RATE_FILTER_H #define RATE_FILTER_H -/* @file rate_filter.h - * @brief rate filter interface for Snort - * @ingroup rate_filter - * @author Dilbagh Chahal -*/ - -/* @ingroup rate_filter - * @{ - */ +// rate filter interface for Snort struct RateFilterConfig; struct SnortConfig; @@ -47,6 +41,5 @@ void RateFilter_PrintConfig(RateFilterConfig*); int RateFilter_Test(OptTreeNode*, Packet*); void RateFilter_ResetActive(void); -/*@}*/ #endif diff --git a/src/filters/sfrf.cc b/src/filters/sfrf.cc index 0a289b8df..495d43290 100644 --- a/src/filters/sfrf.cc +++ b/src/filters/sfrf.cc @@ -17,14 +17,8 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* @file sfrf.c - * @brief rate filter implementation for Snort - * @ingroup rate_filter - * @author Dilbagh Chahal - */ -/* @ingroup rate_filter - * @{ - */ +// sfrf.cc author Dilbagh Chahal +// rate filter implementation for Snort #include "sfrf.h" diff --git a/src/filters/sfrf.h b/src/filters/sfrf.h index 9e456fc79..9d84f7770 100644 --- a/src/filters/sfrf.h +++ b/src/filters/sfrf.h @@ -17,17 +17,12 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// sfrf.h author Dilbagh Chahal + #ifndef SFRF_H #define SFRF_H -/* @file sfrf.h - * @brief rate filter implementation for Snort - * @ingroup rate_filter - * @author Dilbagh Chahal - */ -/* @defgroup rate_filter sourcefire.rate_filter - * Implements rate_filter feature for snort - * @{ - */ + +// Implements rate_filter feature for snort #include "main/policy.h" #include "actions/actions.h" diff --git a/src/filters/sfthd.h b/src/filters/sfthd.h index de292430e..4eb54450d 100644 --- a/src/filters/sfthd.h +++ b/src/filters/sfthd.h @@ -27,9 +27,9 @@ #include "config.h" #endif -#include "sflsq.h" -#include "sfghash.h" -#include "sfxhash.h" +#include "utils/sflsq.h" +#include "hash/sfghash.h" +#include "hash/sfxhash.h" #include "main/policy.h" #include "sfip/sfip_t.h" diff --git a/src/flow/dev_notes.txt b/src/flow/dev_notes.txt new file mode 100644 index 000000000..117e29872 --- /dev/null +++ b/src/flow/dev_notes.txt @@ -0,0 +1,22 @@ +Flows are preallocated at startup and stored in protocol specific caches. +FlowKey is used for quick look up in the cache hash table. + +Each flow may have associated inspectors: + +* clouseau is the Wizard bound to the flow to help determine the + appropriate service inspector + +* gadget is the service inspector + +* data is a passive service inspector such as a client config. + +FlowData is used by various inspectors to store specific data on the flow +for later use. Any inspector may store data on the flow, not just clouseau +gadget. + +FlowData reference counts the associated inspector so that the inspector +can be freed (via garbage collection) after a reload. + +There are many flags that may be set on a flow to indicate session tracking +state, disposition, etc. + diff --git a/src/flow/expect_cache.h b/src/flow/expect_cache.h index c9c8975d3..4f3cd5dca 100644 --- a/src/flow/expect_cache.h +++ b/src/flow/expect_cache.h @@ -17,9 +17,14 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// expect_cache.h author Russ Combs + #ifndef EXPECT_CACHE_H #define EXPECT_CACHE_H +// ExpectCache is used to track anticipated flows (like ftp data channels). +// when the flow is found, it updated with the given info. + #include "sfip/sfip_t.h" #include "flow/flow.h" diff --git a/src/flow/flow.h b/src/flow/flow.h index de3a9ee33..2b6910099 100644 --- a/src/flow/flow.h +++ b/src/flow/flow.h @@ -16,14 +16,18 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// flow.h author Russ Combs + #ifndef FLOW_H #define FLOW_H -#include +// Flow is the object that captures all the data we know about a session, +// including IP for defragmentation and TCP for desegmentation. For all +// protocols, it used to track connection status bindings, and inspector +// state. Inspector state is stored in FlowData, and Flow manages a list +// of FlowData items. -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +#include #include "utils/bitop.h" #include "sfip/sfip_t.h" diff --git a/src/flow/flow_cache.h b/src/flow/flow_cache.h index 6401830f0..dc774ba5d 100644 --- a/src/flow/flow_cache.h +++ b/src/flow/flow_cache.h @@ -17,9 +17,14 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// flow_cache.h author Russ Combs + #ifndef FLOW_CACHE_H #define FLOW_CACHE_H +// there is a FlowCache instance for each protocol. +// Flows are stored in a ZHash instance by FlowKey. + #include "flow/flow_config.h" #include "flow/flow_key.h" #include "flow/memcap.h" diff --git a/src/flow/flow_config.h b/src/flow/flow_config.h index a094f5a8b..5c0be05e4 100644 --- a/src/flow/flow_config.h +++ b/src/flow/flow_config.h @@ -21,6 +21,8 @@ #ifndef FLOW_CONFIG_H #define FLOW_CONFIG_H +// configured by the stream module for each cache instance + struct FlowConfig { unsigned max_sessions = 0; diff --git a/src/flow/flow_control.h b/src/flow/flow_control.h index 0c127fb4b..41486cd4b 100644 --- a/src/flow/flow_control.h +++ b/src/flow/flow_control.h @@ -17,9 +17,14 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// flow_control.h author Russ Combs + #ifndef FLOW_CONTROL_H #define FLOW_CONTROL_H +// this is where all the flow caches are managed and where all flows are +// processed. flows are pruned as needed to process new flows. + #include "flow/flow.h" #include "flow/flow_config.h" #include "utils/stats.h" @@ -90,6 +95,7 @@ private: FlowCache* user_cache; FlowCache* file_cache; + // preallocated arrays Flow* ip_mem; Flow* icmp_mem; Flow* tcp_mem; diff --git a/src/flow/flow_key.cc b/src/flow/flow_key.cc index 8bfea41ed..75e84e0fe 100644 --- a/src/flow/flow_key.cc +++ b/src/flow/flow_key.cc @@ -16,7 +16,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// AUTHOR: Steven Sturges +// flow_key.cc author Steven Sturges #include "flow/flow_key.h" @@ -345,8 +345,8 @@ int FlowKey::compare(const void* s1, const void* s2, size_t) uint32_t* x, * y; x = (uint32_t*)a; y = (uint32_t*)b; - //x++; - //y++; + // x++; + // y++; if (*x - *y) return 1; /* Compares mpls label, no pad */ } @@ -390,8 +390,8 @@ int FlowKey::compare(const void* s1, const void* s2, size_t) uint32_t* x, * y; x = (uint32_t*)a; y = (uint32_t*)b; - //x++; - //y++; + // x++; + // y++; if (*x - *y) return 1; /* Compares mpls label */ } @@ -402,8 +402,8 @@ int FlowKey::compare(const void* s1, const void* s2, size_t) uint16_t* x, * y; x = (uint16_t*)a; y = (uint16_t*)b; - //x++; - //y++; + // x++; + // y++; if (*x - *y) return 1; /* Compares addressSpaceID, no pad */ } diff --git a/src/flow/flow_key.h b/src/flow/flow_key.h index 77c4a2208..0729a800a 100644 --- a/src/flow/flow_key.h +++ b/src/flow/flow_key.h @@ -20,6 +20,9 @@ #ifndef FLOW_KEY_H #define FLOW_KEY_H +// FlowKey is used to store Flows in the caches. the data members are +// sequenced to avoid void space. + #include "main/snort_types.h" #include "hash/sfhashfcn.h" #include "sfip/sfip_t.h" diff --git a/src/flow/memcap.h b/src/flow/memcap.h index fe4bb23d5..0fac51963 100644 --- a/src/flow/memcap.h +++ b/src/flow/memcap.h @@ -21,6 +21,9 @@ #ifndef MEMCAP_H #define MEMCAP_H +// this memcap is just a basic tracker to compare a current total against a +// limit. this will be updated when memory management is implemented. + #include class Memcap diff --git a/src/flow/session.h b/src/flow/session.h index 041cadd0f..61bd253be 100644 --- a/src/flow/session.h +++ b/src/flow/session.h @@ -20,6 +20,9 @@ #ifndef SESSION_H #define SESSION_H +// Session is an abstract base class for the various protocol subclasses. +// the subclasses do the actual work of tracking, reassembly, etc. + #include "sfip/sfip_t.h" #include "stream/stream_api.h" diff --git a/src/framework/base_api.h b/src/framework/base_api.h index 6a6f09a99..53618c349 100644 --- a/src/framework/base_api.h +++ b/src/framework/base_api.h @@ -20,6 +20,11 @@ #ifndef BASE_API_H #define BASE_API_H +// BaseApi is the struct at the front of every plugin api and provides the +// data necessary for common management of plugins. in addition to basic +// usage fields, it provides module instantiation and release functions, as +// well as additional data to help detect mismatched builds etc. + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/framework/bits.h b/src/framework/bits.h index 3cb4b04de..7f12a3d02 100644 --- a/src/framework/bits.h +++ b/src/framework/bits.h @@ -20,6 +20,8 @@ #ifndef BITS_H #define BITS_H +// common types used throughout the code + #include typedef std::bitset<65536> PortBitSet; diff --git a/src/framework/codec.h b/src/framework/codec.h index 8a7b8b42d..278fb723e 100644 --- a/src/framework/codec.h +++ b/src/framework/codec.h @@ -20,6 +20,9 @@ #ifndef FRAMEWORK_CODEC_H #define FRAMEWORK_CODEC_H +// Codec is a type of plugin that provides protocol-specific encoding and +// decoding. + #include #include #include diff --git a/src/framework/counts.h b/src/framework/counts.h index ecebed2fe..00a5ca45d 100644 --- a/src/framework/counts.h +++ b/src/framework/counts.h @@ -21,6 +21,10 @@ #ifndef COUNTS_H #define COUNTS_H +// basic stats support - note that where these are used, the number of +// elements in stats must be the same as the number of elements in the peg +// info. + #include "main/snort_types.h" typedef uint64_t PegCount; diff --git a/src/framework/cursor.h b/src/framework/cursor.h index 1470fc505..0c0f3d2c3 100644 --- a/src/framework/cursor.h +++ b/src/framework/cursor.h @@ -22,6 +22,9 @@ #ifndef CURSOR_H #define CURSOR_H +// Cursor provides a formal way of using buffers when doing detection with +// IpsOptions. + #include #include #include diff --git a/src/framework/data_bus.h b/src/framework/data_bus.h index 4d2b985d2..37fe1ad6f 100644 --- a/src/framework/data_bus.h +++ b/src/framework/data_bus.h @@ -20,6 +20,13 @@ #ifndef DATA_BUS_H #define DATA_BUS_H +// DataEvents are the product of inspection, not detection. They can be +// used to implement flexible processing w/o hardcoding the logic to call +// specific functions under specific conditions. By using DataEvents with +// a publish-subscribe mechanism, it is possible to add custom processing +// at arbitrary points, eg when service is identified, or when a URI is +// available, or when a flow clears. + #include #include #include diff --git a/src/framework/decode_data.h b/src/framework/decode_data.h index 64c067b14..0541be14b 100644 --- a/src/framework/decode_data.h +++ b/src/framework/decode_data.h @@ -20,6 +20,8 @@ #ifndef FRAMEWORK_DECODE_DATA_H #define FRAMEWORK_DECODE_DATA_H +// Captures decode information from Codecs. + #include #include "protocols/mpls.h" diff --git a/src/framework/dev_notes.txt b/src/framework/dev_notes.txt new file mode 100644 index 000000000..c13906b55 --- /dev/null +++ b/src/framework/dev_notes.txt @@ -0,0 +1,12 @@ +This directory provides base classes and support for the various Snort++ +plugins. Module provides an abstracted interface to the common plugin +features such as configuration. Module corresponds to a top-level Lua +table of the same name. + +Note that plugins must keep configuration (parse time) separate from state +(run time). A plugin must store its state on the flow in FlowData or in +thread local data. In some cases thread local data is handled by an array +attached to configuration with one element per packet thread, however those +cases are rare and should only be needed by the framework code, not the +plugins. + diff --git a/src/framework/inspector.h b/src/framework/inspector.h index 0cfac00d5..9c27d0693 100644 --- a/src/framework/inspector.h +++ b/src/framework/inspector.h @@ -20,6 +20,10 @@ #ifndef INSPECTOR_H #define INSPECTOR_H +// Inspectors are the workhorse that do all the heavy lifting between +// decoding a packet and detection. There are several types that operate +// in different ways. These correspond to Snort 2X preprocessors. + #include "main/snort_types.h" #include "main/thread.h" #include "framework/base_api.h" diff --git a/src/framework/ips_action.h b/src/framework/ips_action.h index 8f25d59bb..d3b2a91a4 100644 --- a/src/framework/ips_action.h +++ b/src/framework/ips_action.h @@ -20,6 +20,11 @@ #ifndef IPS_ACTION_H #define IPS_ACTION_H +// IpsAction provides custom rule actions that are executed when a +// detection event is generated regardless of whether the event is logged. +// These can be used to execute external controls like updating an external +// firewall. + #include "main/snort_types.h" #include "framework/base_api.h" #include "actions/actions.h" diff --git a/src/framework/ips_option.h b/src/framework/ips_option.h index 71e621afc..35c231ed6 100644 --- a/src/framework/ips_option.h +++ b/src/framework/ips_option.h @@ -20,6 +20,9 @@ #ifndef IPS_OPTION_H #define IPS_OPTION_H +// All IPS rule keywords are realized as IpsOptions instantiated when rules +// are parsed. + #include "main/snort_types.h" #include "framework/base_api.h" #include "detection/rule_option_types.h" diff --git a/src/framework/logger.h b/src/framework/logger.h index 1cea36c32..5b62e48b9 100644 --- a/src/framework/logger.h +++ b/src/framework/logger.h @@ -20,9 +20,9 @@ #ifndef LOGGER_H #define LOGGER_H -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +// Logger is used to log packets and events. Events are thresholded before +// they reach the Logger. Packets may be logged along with events or as a +// result of tagging. #include "main/snort_types.h" #include "events/event.h" diff --git a/src/framework/lua_api.h b/src/framework/lua_api.h index 71c79b5d8..8ef851146 100644 --- a/src/framework/lua_api.h +++ b/src/framework/lua_api.h @@ -20,9 +20,11 @@ #ifndef LUA_API_H #define LUA_API_H +// LuaApi makes Lua scripts standard plugins + #include -#include "base_api.h" +#include "framework/base_api.h" class LuaApi { diff --git a/src/framework/module.h b/src/framework/module.h index 5b5d7fd2d..80c167a43 100644 --- a/src/framework/module.h +++ b/src/framework/module.h @@ -24,6 +24,20 @@ #ifndef MODULE_H #define MODULE_H +// Module provides a data-driven way to manage much of Snort++. For +// example, it provides an interface to configured components. There is at +// most one instance of a Module at any time. A given module instance is +// used to configure all related components. As such it stores data only +// for the sake of constructing the next component instance. +// +// Module will set all parameter defaults immediately after calling +// begin() so defaults should not be explicitly set in begin() or a ctor +// called by begin, except as needed for infrastructure and sanity. +// +// Note that there are no internal default lists. Put appropriate default +// lists in snort_defaults.lua or some such. Each list item, however, will +// have any defaults applied. + #include #include diff --git a/src/framework/mpse.cc b/src/framework/mpse.cc index 0e812258c..0c0ef642b 100644 --- a/src/framework/mpse.cc +++ b/src/framework/mpse.cc @@ -47,13 +47,13 @@ Mpse::Mpse(const char* m, bool use_gc) } int Mpse::search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) { PROFILE_VARS; MODULE_PROFILE_START(mpsePerfStats); - int ret = _search(T, n, action, data, current_state); + int ret = _search(T, n, match, data, current_state); if ( inc_global_counter ) s_bcnt += n; @@ -63,10 +63,10 @@ int Mpse::search( } int Mpse::search_all( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) { - return _search(T, n, action, data, current_state); + return _search(T, n, match, data, current_state); } uint64_t Mpse::get_pattern_byte_count() diff --git a/src/framework/mpse.h b/src/framework/mpse.h index afbba55a5..dd254e8de 100644 --- a/src/framework/mpse.h +++ b/src/framework/mpse.h @@ -20,6 +20,10 @@ #ifndef MPSE_H #define MPSE_H +// MPSE = Multi-Pattern Search Engine - ie fast pattern matching The key +// methods of an MPSE are the ability to add patterns, compile a state +// machine from the patterns, and search a buffer for patterns. + #include #ifdef HAVE_CONFIG_H @@ -45,9 +49,9 @@ struct SnortConfig; struct MpseApi; -typedef int (* mpse_build_f)(SnortConfig*, void* id, void** existing_tree); -typedef int (* mpse_negate_f)(void* id, void** list); -typedef int (* mpse_action_f)(void* id, void* tree, int index, void* data, void* neg_list); +typedef int (* MpseBuild)(SnortConfig*, void* id, void** existing_tree); +typedef int (* MpseNegate)(void* id, void** list); +typedef int (* MpseMatch)(void* id, void* tree, int index, void* data, void* neg_list); class SO_PUBLIC Mpse { @@ -63,14 +67,14 @@ public: bool noCase, bool negate, void* ID, int IID) = 0; virtual int prep_patterns( - SnortConfig*, mpse_build_f, mpse_negate_f) = 0; + SnortConfig*, MpseBuild, MpseNegate) = 0; int search( - const unsigned char* T, int n, mpse_action_f, + const unsigned char* T, int n, MpseMatch, void* data, int* current_state); virtual int search_all( - const unsigned char* T, int n, mpse_action_f, + const unsigned char* T, int n, MpseMatch, void* data, int* current_state); virtual void set_opt(int) { } @@ -87,7 +91,7 @@ protected: Mpse(const char* method, bool use_gc); virtual int _search( - const unsigned char* T, int n, mpse_action_f, + const unsigned char* T, int n, MpseMatch, void* data, int* current_state) = 0; private: diff --git a/src/framework/parameter.h b/src/framework/parameter.h index eb73002a1..42aa983b9 100644 --- a/src/framework/parameter.h +++ b/src/framework/parameter.h @@ -20,6 +20,9 @@ #ifndef PARAMETER_H #define PARAMETER_H +// Parameter provides basic parsing from Lua types into meaningful C++ +// types. Modules support a list of parameters. +// // number ranges are given by: // nullptr -> any // # | #: | :# | #:# diff --git a/src/framework/range.h b/src/framework/range.h index ac176f980..918975de8 100644 --- a/src/framework/range.h +++ b/src/framework/range.h @@ -20,6 +20,8 @@ #ifndef FRAMEWORK_RANGE_H #define FRAMEWORK_RANGE_H +// RangeCheck supports common IpsOption evaluation syntax and semantics. + #include "main/snort_types.h" // unfortunately, <> was implemented inconsistently. eg: diff --git a/src/framework/so_rule.h b/src/framework/so_rule.h index ba1e64184..47adf6cb0 100644 --- a/src/framework/so_rule.h +++ b/src/framework/so_rule.h @@ -20,6 +20,11 @@ #ifndef SO_RULE_H #define SO_RULE_H +// SO rule = shared object rule; allows implementing arbitrary C++ for +// detection below and beyond the text rule options. An SO rule is just +// like a text rule except that it can call function hooks. It can also +// define its own rule options and any other plugins it may need. + #include "main/snort_types.h" #include "framework/base_api.h" #include "framework/ips_option.h" diff --git a/src/framework/value.h b/src/framework/value.h index e7af0232b..07fe5cc30 100644 --- a/src/framework/value.h +++ b/src/framework/value.h @@ -20,6 +20,8 @@ #ifndef VALUE_H #define VALUE_H +// Value is used to represent Lua bool, number, and string. + #include #include diff --git a/src/hash/dev_notes.txt b/src/hash/dev_notes.txt new file mode 100644 index 000000000..cdbf02864 --- /dev/null +++ b/src/hash/dev_notes.txt @@ -0,0 +1,16 @@ +Message digests and hash maps/table implementations: + +* md5: open source implementation based on Colin Plumb's code. + +* sha2: open source implementation by Aaron Gifford. + +* sfghash: Generic hash table + +* sfxhash: Hash table with supports memcap and automatic memory recovery + when out of memory. + +* zhash: zero runtime allocations/preallocated hash table. + +Use of these hashing utilities is primarily for use by pre-existing code. +For new code, use standard template library and C++11 features. + diff --git a/src/hash/md5.h b/src/hash/md5.h index 9fe86d08c..b0ad2db1e 100644 --- a/src/hash/md5.h +++ b/src/hash/md5.h @@ -4,10 +4,16 @@ * -- moved #endif for !MD5_H to end of file * -- added include stdint.h * -- added typedef for __u32 + * -- added config.h foo */ #ifndef MD5_H #define MD5_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef HEADER_MD5_H /* Try to avoid clashes with OpenSSL */ #define HEADER_MD5_H @@ -50,5 +56,5 @@ void hmac_md5_final(unsigned char* digest, struct HMACMD5Context* ctx); /* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, unsigned char *digest);*/ -#endif /* !MD5_H */ +#endif diff --git a/src/hash/sfghash.h b/src/hash/sfghash.h index aaf25828e..a5af6248b 100644 --- a/src/hash/sfghash.h +++ b/src/hash/sfghash.h @@ -17,53 +17,36 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -* -* sfghash.h -* -* generic hash table - stores and maps key + data pairs -* -* Author: Marc Norton -* -*/ +// sfghash.h author Marc Norton #ifndef SFGHASH_H #define SFGHASH_H +// generic hash table - stores and maps key + data pairs + #include #include #include struct SFHASHFCN; -/* -* ERROR DEFINES -*/ #define SFGHASH_NOMEM -2 #define SFGHASH_ERR -1 #define SFGHASH_OK 0 #define SFGHASH_INTABLE 1 -/* -* Flags for ghash_new: userkeys -*/ +// Flags for ghash_new: userkeys #define GH_COPYKEYS 0 #define GH_USERKEYS 1 -/* -* Generic HASH NODE -*/ struct SFGHASH_NODE { struct SFGHASH_NODE* next, * prev; const void* key; /* Copy of, or Pointer to, the Users key */ - void* data; /* The users data, this is never copied! */ + void* data; /* The users data, this is never copied! */ }; -/* -* Generic HASH table -*/ struct SFGHASH { SFHASHFCN* sfhashfcn; @@ -73,36 +56,31 @@ struct SFGHASH SFGHASH_NODE** table; /* array of node ptr's */ int nrows; /* # rows int the hash table use a prime number 211, 9871 */ - unsigned count; /* total # nodes in table */ + unsigned count; /* total # nodes in table */ void (* userfree)(void*); int crow; /* findfirst/next row in table */ - SFGHASH_NODE* cnode; /* findfirst/next node ptr */ + SFGHASH_NODE* cnode; /* findfirst/next node ptr */ int splay; }; -/* -* HASH PROTOTYPES -*/ SFGHASH* sfghash_new(int nrows, int keysize, int userkeys, void (* userfree)(void* p) ); -void sfghash_delete(SFGHASH* h); -int sfghash_add(SFGHASH* t, const void* const key, void* const data); -int sfghash_remove(SFGHASH* h, const void* const key); -int sfghash_count(SFGHASH* h); -void* sfghash_find(SFGHASH* h, const void* const key); + +void sfghash_delete(SFGHASH*); +int sfghash_add(SFGHASH*, const void* const key, void* const data); +int sfghash_remove(SFGHASH*, const void* const key); +int sfghash_count(SFGHASH*); +void* sfghash_find(SFGHASH*, const void* const key); int sfghash_find2(SFGHASH*, const void*, void**); -SFGHASH_NODE* sfghash_findfirst(SFGHASH* h); -SFGHASH_NODE* sfghash_findnext(SFGHASH* h); - -int sfghash_set_keyops(SFGHASH* h, - unsigned (* hash_fcn)(SFHASHFCN* p, - unsigned char* d, - int n), - int (* keycmp_fcn)(const void* s1, - const void* s2, - size_t n)); + +SFGHASH_NODE* sfghash_findfirst(SFGHASH*); +SFGHASH_NODE* sfghash_findnext(SFGHASH*); + +int sfghash_set_keyops(SFGHASH*, + unsigned (* hash_fcn)(SFHASHFCN* p, unsigned char* d, int n), + int (* keycmp_fcn)(const void* s1, const void* s2, size_t n)); #endif diff --git a/src/hash/sfxhash.cc b/src/hash/sfxhash.cc index f1cc9d803..cbe9baaff 100644 --- a/src/hash/sfxhash.cc +++ b/src/hash/sfxhash.cc @@ -17,7 +17,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/*!@file sfxhash.c +/* sfxhash.c * * A Customized hash table library for storing and accessing key + data pairs. * @@ -101,9 +101,8 @@ #include "sfprimetable.h" #include "hash/sfhashfcn.h" -/**@defgroup sfxhash sourcefire.container.sfxhash +/* * Implements SFXHASH as specialized hash container - * @{ */ /* @@ -150,24 +149,22 @@ int sfxhash_calcrows(int num) // return sf_nearest_prime( nrows ); } -/*! - * +/* * Create a new hash table * * By default, this will "splay" nodes to the top of a free list. * - * @param nrows number of rows in hash table - * @param keysize key size in bytes, same for all keys - * @param datasize datasize in bytes, zero indicates user manages data - * @param maxmem maximum memory to use in bytes - * @param anr_flag Automatic Node Recovery boolean flag - * @param anrfree users Automatic Node Recovery memory release function - * @param usrfree users standard memory release function - * - * @return SFXHASH* - * @retval 0 out of memory - * @retval !0 Valid SFXHASH pointer - * + * nrows number of rows in hash table + * keysize key size in bytes, same for all keys + * datasize datasize in bytes, zero indicates user manages data + * maxmem maximum memory to use in bytes + * anr_flag Automatic Node Recovery boolean flag + * anrfree users Automatic Node Recovery memory release function + * usrfree users standard memory release function + * + * return SFXHASH* + * retval 0 out of memory + * retval !0 Valid SFXHASH pointer */ /* Notes: @@ -262,12 +259,12 @@ SFXHASH* sfxhash_new(int nrows, int keysize, int datasize, unsigned long maxmem, return h; } -/*! +/* * Set the maximum nodes used in this hash table. * Specifying 0 is unlimited (or otherwise limited by memcap). * - * @param h SFXHASH table pointer - * @param max_nodes maximum nodes to allow. + * h SFXHASH table pointer + * max_nodes maximum nodes to allow. * */ void sfxhash_set_max_nodes(SFXHASH* h, int max_nodes) @@ -281,8 +278,8 @@ void sfxhash_set_max_nodes(SFXHASH* h, int max_nodes) /*! * Set Splay mode : Splays nodes to front of list on each access * - * @param t SFXHASH table pointer - * @param n boolean flag toggles splaying of hash nodes + * t SFXHASH table pointer + * n boolean flag toggles splaying of hash nodes * */ void sfxhash_splaymode(SFXHASH* t, int n) @@ -297,7 +294,7 @@ void sfxhash_splaymode(SFXHASH* t, int n) * No need to call the user free, since that should've been * done when those nodes were put back in the free list. * - * @param h SFXHASH table pointer + * h SFXHASH table pointer */ static void sfxhash_delete_free_list(SFXHASH* t) { @@ -325,7 +322,7 @@ static void sfxhash_delete_free_list(SFXHASH* t) * * free key's, free node's, and free the users data. * - * @param h SFXHASH table pointer + * h SFXHASH table pointer * */ void sfxhash_delete(SFXHASH* h) @@ -367,9 +364,9 @@ void sfxhash_delete(SFXHASH* h) /*! * Empty out the hash table * - * @param h SFXHASH table pointer + * h SFXHASH table pointer * - * @return -1 on error + * return -1 on error */ int sfxhash_make_empty(SFXHASH* h) { @@ -683,14 +680,14 @@ static SFXHASH_NODE* sfxhash_find_node_row(SFXHASH* t, const void* key, int* rin * * This is done because of the successful find. * - * @param t SFXHASH table pointer - * @param key users key pointer - * @param data users data pointer + * t SFXHASH table pointer + * key users key pointer + * data users data pointer * - * @return integer - * @retval SFXHASH_OK success - * @retval SFXHASH_INTABLE already in the table, t->cnode points to the node - * @retval SFXHASH_NOMEM not enough memory + * eturn integer + * retval SFXHASH_OK success + * retval SFXHASH_INTABLE already in the table, t->cnode points to the node + * retval SFXHASH_NOMEM not enough memory */ static int sfxhash_add_ex(SFXHASH* t, const void* key, void* data, void** data_ptr) { @@ -770,13 +767,13 @@ int sfxhash_add(SFXHASH* t, void* key, void* data) * * This is done because of the successful find. * - * @param t SFXHASH table pointer - * @param key users key pointer + * t SFXHASH table pointer + * key users key pointer * - * @return integer - * @retval SFXHASH_OK success - * @retval SFXHASH_INTABLE already in the table, t->cnode points to the node - * @retval SFXHASH_NOMEM not enough memory + * return integer + * retval SFXHASH_OK success + * retval SFXHASH_INTABLE already in the table, t->cnode points to the node + * retval SFXHASH_NOMEM not enough memory */ SFXHASH_NODE* sfxhash_get_node(SFXHASH* t, const void* key) { @@ -837,11 +834,11 @@ SFXHASH_NODE* sfxhash_get_node(SFXHASH* t, const void* key) /*! * Find a Node based on the key * - * @param t SFXHASH table pointer - * @param key users key pointer + * t SFXHASH table pointer + * key users key pointer * - * @return SFXHASH_NODE* valid pointer to the hash node - * @retval 0 node not found + * return SFXHASH_NODE* valid pointer to the hash node + * retval 0 node not found * */ SFXHASH_NODE* sfxhash_find_node(SFXHASH* t, const void* key) @@ -854,11 +851,11 @@ SFXHASH_NODE* sfxhash_find_node(SFXHASH* t, const void* key) /*! * Find the users data based associated with the key * - * @param t SFXHASH table pointer - * @param key users key pointer + * t SFXHASH table pointer + * key users key pointer * - * @return void* valid pointer to the users data - * @retval 0 node not found + * return void* valid pointer to the users data + * retval 0 node not found * */ void* sfxhash_find(SFXHASH* t, void* key) @@ -877,9 +874,9 @@ void* sfxhash_find(SFXHASH* t, void* key) /** * Get the HEAD of the in use list * - * @param t table pointer + * t table pointer * - * @return the head of the list or NULL + * return the head of the list or NULL */ SFXHASH_NODE* sfxhash_ghead(SFXHASH* t) { @@ -894,9 +891,9 @@ SFXHASH_NODE* sfxhash_ghead(SFXHASH* t) /** * Walk the global list * - * @param n current node + * n current node * - * @return the next node in the list or NULL when at the end + * return the next node in the list or NULL when at the end */ SFXHASH_NODE* sfxhash_gnext(SFXHASH_NODE* n) { @@ -911,9 +908,9 @@ SFXHASH_NODE* sfxhash_gnext(SFXHASH_NODE* n) /** * Walk the global list * - * @param n current node + * n current node * - * @return the next node in the list or NULL when at the end + * return the next node in the list or NULL when at the end */ SFXHASH_NODE* sfxhash_gfindnext(SFXHASH* t) { @@ -928,9 +925,9 @@ SFXHASH_NODE* sfxhash_gfindnext(SFXHASH* t) /** * Get the HEAD of the in use list * - * @param t table pointer + * t table pointer * - * @return the head of the list or NULL + * return the head of the list or NULL */ SFXHASH_NODE* sfxhash_gfindfirst(SFXHASH* t) { @@ -948,10 +945,10 @@ SFXHASH_NODE* sfxhash_gfindfirst(SFXHASH* t) /*! * Return the most recently used data from the global list * - * @param t SFXHASH table pointer + * t SFXHASH table pointer * - * @return void* valid pointer to the users data - * @retval 0 node not found + * return void* valid pointer to the users data + * retval 0 node not found * */ void* sfxhash_mru(SFXHASH* t) @@ -969,10 +966,10 @@ void* sfxhash_mru(SFXHASH* t) /*! * Return the least recently used data from the global list * - * @param t SFXHASH table pointer + * t SFXHASH table pointer * - * @return void* valid pointer to the users data - * @retval 0 node not found + * return void* valid pointer to the users data + * retval 0 node not found * */ void* sfxhash_lru(SFXHASH* t) @@ -990,10 +987,10 @@ void* sfxhash_lru(SFXHASH* t) /*! * Return the most recently used node from the global list * - * @param t SFXHASH table pointer + * t SFXHASH table pointer * - * @return SFXHASH_NODE* valid pointer to a node - * @retval 0 node not found + * return SFXHASH_NODE* valid pointer to a node + * retval 0 node not found * */ SFXHASH_NODE* sfxhash_mru_node(SFXHASH* t) @@ -1011,10 +1008,10 @@ SFXHASH_NODE* sfxhash_mru_node(SFXHASH* t) /*! * Return the least recently used node from the global list * - * @param t SFXHASH table pointer + * t SFXHASH table pointer * - * @return SFXHASH_NODE* valid pointer to a node - * @retval 0 node not found + * return SFXHASH_NODE* valid pointer to a node + * retval 0 node not found * */ SFXHASH_NODE* sfxhash_lru_node(SFXHASH* t) @@ -1033,10 +1030,10 @@ SFXHASH_NODE* sfxhash_lru_node(SFXHASH* t) * Get some hash table statistics. NOT FOR REAL TIME USE. * * - * @param t SFXHASH table pointer - * @param filled how many + * t SFXHASH table pointer + * param filled how many * - * @return max depth of the table + * return max depth of the table * */ unsigned sfxhash_maxdepth(SFXHASH* t) @@ -1093,11 +1090,11 @@ int sfxhash_free_node(SFXHASH* t, SFXHASH_NODE* hnode) /*! * Remove a Key + Data Pair from the table. * - * @param t SFXHASH table pointer - * @param key users key pointer + * t SFXHASH table pointer + * key users key pointer * - * @return 0 success - * @retval !0 failed + * return 0 success + * retval !0 failed * */ int sfxhash_remove(SFXHASH* t, void* key) @@ -1154,10 +1151,10 @@ static void sfxhash_next(SFXHASH* t) /*! * Find and return the first hash table node * - * @param t SFXHASH table pointer + * t SFXHASH table pointer * - * @return 0 failed - * @retval !0 valid SFXHASH_NODE * + * return 0 failed + * retval !0 valid SFXHASH_NODE * * */ SFXHASH_NODE* sfxhash_findfirst(SFXHASH* t) @@ -1186,10 +1183,10 @@ SFXHASH_NODE* sfxhash_findfirst(SFXHASH* t) /*! * Find and return the next hash table node * - * @param t SFXHASH table pointer + * t SFXHASH table pointer * - * @return 0 failed - * @retval !0 valid SFXHASH_NODE * + * return 0 failed + * retval !0 valid SFXHASH_NODE * * */ SFXHASH_NODE* sfxhash_findnext(SFXHASH* t) @@ -1213,9 +1210,9 @@ SFXHASH_NODE* sfxhash_findnext(SFXHASH* t) /** * Make sfhashfcn use a separate set of opcodes for the backend. * - * @param h sfhashfcn ptr - * @param hash_fcn user specified hash function - * @param keycmp_fcn user specified key comparisoin function + * h sfhashfcn ptr + * hash_fcn user specified hash function + * keycmp_fcn user specified key comparisoin function */ int sfxhash_set_keyops(SFXHASH* h, @@ -1385,5 +1382,4 @@ int main(int argc, char** argv) } #endif -/**@}*/ diff --git a/src/hash/sfxhash.h b/src/hash/sfxhash.h index 5941f610a..a3036e952 100644 --- a/src/hash/sfxhash.h +++ b/src/hash/sfxhash.h @@ -17,20 +17,14 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -* -* sfxhash.h -* -* generic hash table - stores and maps key + data pairs -* (supports memcap and automatic memory recovery when out of memory) -* -* Author: Marc Norton -* -*/ +// sfxhash.h author Marc Norton #ifndef SFXHASH_H #define SFXHASH_H +// generic hash table - stores and maps key + data pairs +// (supports memcap and automatic memory recovery when out of memory) + #include #include #include @@ -40,74 +34,65 @@ struct SFHASHFCN; -/* -* ERROR DEFINES -*/ #define SFXHASH_NOMEM -2 #define SFXHASH_ERR -1 #define SFXHASH_OK 0 #define SFXHASH_INTABLE 1 -/** -* HASH NODE -*/ struct SFXHASH_NODE { - struct SFXHASH_NODE* gnext, * gprev; /// global node list - used for ageing nodes - struct SFXHASH_NODE* next, * prev; /// row node list + struct SFXHASH_NODE* gnext, * gprev; // global node list - used for ageing nodes + struct SFXHASH_NODE* next, * prev; // row node list - int rindex; /// row index of table this node belongs to. + int rindex; // row index of table this node belongs to. - void* key; /// Pointer to the key. - void* data; /// Pointer to the users data, this is not copied ! + void* key; // Pointer to the key. + void* data; // Pointer to the users data, this is not copied ! }; typedef int (* SFXHASH_FREE_FCN)(void* key, void* data); -/** -* SFGX HASH Table -*/ + struct SFXHASH { - SFHASHFCN* sfhashfcn; /// hash function - int keysize; /// bytes in key, if <= 0 -> keys are strings - int datasize; /// bytes in key, if == 0 -> user data - SFXHASH_NODE** table; /// array of node ptr's */ - unsigned nrows; /// # rows int the hash table use a prime number 211, 9871 - unsigned count; /// total # nodes in table - - unsigned crow; /// findfirst/next row in table + SFHASHFCN* sfhashfcn; // hash function + int keysize; // bytes in key, if <= 0 -> keys are strings + int datasize; // bytes in key, if == 0 -> user data + SFXHASH_NODE** table; // array of node ptr's */ + unsigned nrows; // # rows int the hash table use a prime number 211, 9871 + unsigned count; // total # nodes in table + + unsigned crow; // findfirst/next row in table unsigned pad; - SFXHASH_NODE* cnode; /// findfirst/next node ptr - int splay; /// whether to splay nodes with same hash bucket + SFXHASH_NODE* cnode; // findfirst/next node ptr + int splay; // whether to splay nodes with same hash bucket - unsigned max_nodes; ///maximum # of nodes within a hash + unsigned max_nodes; // maximum # of nodes within a hash MEMCAP mc; - unsigned overhead_bytes; /// # of bytes that will be unavailable for nodes inside the - // table - unsigned overhead_blocks; /// # of blocks consumed by the table + unsigned overhead_bytes; // # of bytes that will be unavailable for nodes inside the + // table + unsigned overhead_blocks; // # of blocks consumed by the table unsigned find_fail; unsigned find_success; - SFXHASH_NODE* ghead, * gtail; /// global - root of all nodes allocated in table + SFXHASH_NODE* ghead, * gtail; // global - root of all nodes allocated in table - SFXHASH_NODE* fhead, * ftail; /// list of free nodes, which are recyled - SFXHASH_NODE* gnode; /* gfirst/gnext node ptr */ - int recycle_nodes; /// recycle nodes. Nodes are not freed, but are used for + SFXHASH_NODE* fhead, * ftail; // list of free nodes, which are recyled + SFXHASH_NODE* gnode; // gfirst/gnext node ptr */ + int recycle_nodes; // recycle nodes. Nodes are not freed, but are used for // subsequent new nodes - /**Automatic Node Recover (ANR): When number of nodes in hash is equal to max_nodes, remove the least recently - * used nodes and use it for the new node. anr_tries indicates # of ANR tries.*/ + /* Automatic Node Recover (ANR): When number of nodes in hash is equal + * to max_nodes, remove the least recently used nodes and use it for + * the new node. anr_tries indicates # of ANR tries.*/ + unsigned anr_tries; - unsigned anr_count; /// # ANR ops performaed - int anr_flag; /// 0=off, !0=on + unsigned anr_count; // # ANR ops performaed + int anr_flag; // 0=off, !0=on SFXHASH_FREE_FCN anrfree; SFXHASH_FREE_FCN usrfree; }; -/* -* HASH PROTOTYPES -*/ SO_PUBLIC int sfxhash_calcrows(int num); SO_PUBLIC SFXHASH* sfxhash_new(int nrows, int keysize, int datasize, unsigned long memcap, int anr_flag, @@ -124,82 +109,33 @@ SO_PUBLIC int sfxhash_add(SFXHASH* h, void* key, void* data); SO_PUBLIC SFXHASH_NODE* sfxhash_get_node(SFXHASH* t, const void* key); SO_PUBLIC int sfxhash_remove(SFXHASH* h, void* key); -/*! - * Get the # of Nodes in HASH the table - * - * @param t SFXHASH table pointer - * - */ +// Get the # of Nodes in HASH the table static inline unsigned sfxhash_count(SFXHASH* t) -{ - return t->count; -} - -/*! - * Get the # auto recovery - * - * @param t SFXHASH table pointer - * - */ +{ return t->count; } + +// Get the # auto recovery static inline unsigned sfxhash_anr_count(SFXHASH* t) -{ - return t->anr_count; -} - -/*! - * Get the # finds - * - * @param t SFXHASH table pointer - * - */ +{ return t->anr_count; } + +// Get the # finds static inline unsigned sfxhash_find_total(SFXHASH* t) -{ - return t->find_success + t->find_fail; -} - -/*! - * Get the # unsucessful finds - * - * @param t SFXHASH table pointer - * - */ +{ return t->find_success + t->find_fail; } + +// Get the # unsucessful finds static inline unsigned sfxhash_find_fail(SFXHASH* t) -{ - return t->find_fail; -} - -/*! - * Get the # sucessful finds - * - * @param t SFXHASH table pointer - * - */ +{ return t->find_fail; } + +// Get the # sucessful finds static inline unsigned sfxhash_find_success(SFXHASH* t) -{ - return t->find_success; -} - -/*! - * Get the # of overhead bytes - * - * @param t SFXHASH table pointer - * - */ +{ return t->find_success; } + +// Get the # of overhead bytes static inline unsigned sfxhash_overhead_bytes(SFXHASH* t) -{ - return t->overhead_bytes; -} - -/*! - * Get the # of overhead blocks - * - * @param t SFXHASH table pointer - * - */ +{ return t->overhead_bytes; } + +// Get the # of overhead blocks static inline unsigned sfxhash_overhead_blocks(SFXHASH* t) -{ - return t->overhead_blocks; -} +{ return t->overhead_blocks; } SO_PUBLIC void* sfxhash_mru(SFXHASH* t); SO_PUBLIC void* sfxhash_lru(SFXHASH* t); diff --git a/src/hash/sha2.h b/src/hash/sha2.h index f10a6e7b1..4f202a48c 100644 --- a/src/hash/sha2.h +++ b/src/hash/sha2.h @@ -35,11 +35,16 @@ * the only changes are listed here: * -- removed the source control id line from above since n/a * -- changed sha2.c const static to static const to squelch warnings + * -- added config.h foo */ #ifndef __SHA2_H__ #define __SHA2_H__ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/src/helpers/CMakeLists.txt b/src/helpers/CMakeLists.txt index ae0f1bf56..c201c0533 100644 --- a/src/helpers/CMakeLists.txt +++ b/src/helpers/CMakeLists.txt @@ -4,13 +4,15 @@ add_library (helpers STATIC chunk.h directory.cc directory.h + lua.cc + lua.h markup.cc markup.h process.cc process.h + ring.h + ring_logic.h swapper.h - lua.cc - lua.h ) diff --git a/src/helpers/Makefile.am b/src/helpers/Makefile.am index 622e178e1..3516ec06d 100644 --- a/src/helpers/Makefile.am +++ b/src/helpers/Makefile.am @@ -11,12 +11,14 @@ chunk.cc \ chunk.h \ directory.cc \ directory.h \ +lua.cc \ +lua.h \ markup.cc \ markup.h \ process.cc \ process.h \ -swapper.h \ -lua.cc \ -lua.h +ring.h \ +ring_logic.h \ +swapper.h AM_CXXFLAGS = @AM_CXXFLAGS@ diff --git a/src/helpers/chunk.h b/src/helpers/chunk.h index 8d5d54d7d..16f5aa656 100644 --- a/src/helpers/chunk.h +++ b/src/helpers/chunk.h @@ -20,6 +20,8 @@ #ifndef CHUNK_H #define CHUNK_H +// Lua chunk support + #include void init_chunk(struct lua_State*&, std::string& chunk, const char* name, std::string& args); diff --git a/src/helpers/dev_notes.txt b/src/helpers/dev_notes.txt new file mode 100644 index 000000000..8f1dd3b10 --- /dev/null +++ b/src/helpers/dev_notes.txt @@ -0,0 +1,3 @@ +This directory contains new utility classes and methods for use by the +framework. + diff --git a/src/helpers/directory.h b/src/helpers/directory.h index 5fcede7ff..d1d4f7c8b 100644 --- a/src/helpers/directory.h +++ b/src/helpers/directory.h @@ -20,6 +20,8 @@ #ifndef DIRECTORY_H #define DIRECTORY_H +// simple directory traversal + #include #include diff --git a/src/helpers/lua.h b/src/helpers/lua.h index 390e83ca8..5ea2f13c9 100644 --- a/src/helpers/lua.h +++ b/src/helpers/lua.h @@ -20,6 +20,8 @@ #ifndef LUA_H #define LUA_H +// methods and templates for the C++ / LuaJIT interface + #include namespace Lua diff --git a/src/helpers/markup.h b/src/helpers/markup.h index 40151adfd..706099e69 100644 --- a/src/helpers/markup.h +++ b/src/helpers/markup.h @@ -20,6 +20,8 @@ #ifndef MARKUP_H #define MARKUP_H +// used to format help and list output for inclusion into user manual + #include class Markup diff --git a/src/helpers/process.cc b/src/helpers/process.cc index fd7d879b8..1f6937c3b 100644 --- a/src/helpers/process.cc +++ b/src/helpers/process.cc @@ -44,9 +44,9 @@ using namespace std; #include "main/snort.h" #include "main/snort_config.h" #include "utils/util.h" -#include "utils/ring.h" #include "utils/stats.h" #include "helpers/markup.h" +#include "helpers/ring.h" #include "parser/parser.h" #ifndef SIGNAL_SNORT_RELOAD diff --git a/src/helpers/process.h b/src/helpers/process.h index 0ccc3c410..289901084 100644 --- a/src/helpers/process.h +++ b/src/helpers/process.h @@ -19,11 +19,9 @@ #ifndef PROCESS_H #define PROCESS_H -#include +// process oriented services like signal handling, heap info, etc. -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +#include #include enum PigSignal diff --git a/src/utils/ring.h b/src/helpers/ring.h similarity index 94% rename from src/utils/ring.h rename to src/helpers/ring.h index fca92de60..e31b26176 100644 --- a/src/utils/ring.h +++ b/src/helpers/ring.h @@ -17,13 +17,11 @@ //-------------------------------------------------------------------------- // ring.h author Russ Combs -//------------------------------------------------------------------- -// simple ring -//------------------------------------------------------------------- - #ifndef RING_H #define RING_H +// Simple ring implementation + #include "ring_logic.h" template diff --git a/src/utils/ring_logic.h b/src/helpers/ring_logic.h similarity index 93% rename from src/utils/ring_logic.h rename to src/helpers/ring_logic.h index 887f793e2..05d66c5e6 100644 --- a/src/utils/ring_logic.h +++ b/src/helpers/ring_logic.h @@ -17,13 +17,11 @@ //-------------------------------------------------------------------------- // ring_logic.h author Russ Combs -//------------------------------------------------------------------- -// simple ring logic -//------------------------------------------------------------------- - #ifndef RING_LOGIC_H #define RING_LOGIC_H +// Logic for simple ring implementation + class RingLogic { public: diff --git a/src/helpers/swapper.h b/src/helpers/swapper.h index be218b58b..4378cc051 100644 --- a/src/helpers/swapper.h +++ b/src/helpers/swapper.h @@ -20,6 +20,8 @@ #ifndef SWAPPER_H #define SWAPPER_H +// used to make thread local, pointer-based config swaps by packet threads + struct SnortConfig; struct tTargetBasedConfig; diff --git a/src/ips_options/dev_notes.txt b/src/ips_options/dev_notes.txt new file mode 100644 index 000000000..394d1b111 --- /dev/null +++ b/src/ips_options/dev_notes.txt @@ -0,0 +1,12 @@ +Standard IPS rule option such as "content", "pcre", "flowbits" etc.. +(non-preprocessor specific) implemented as IpsOption subcclasses. + +Most of the IpsOptions can be built statically or dynamically. Several, +however, such as content, are still tightly coupled with the code and can +only be built statically. The code will hopefully evolve and eliminate +these cases. + +Several options use RangeCheck to implement upper and/or lower bound +semantics. The Snort 2X options had various implementations of ranges so +3X differs in some places. + diff --git a/src/ips_options/ips_base64.cc b/src/ips_options/ips_base64.cc index d2ea36c01..3de5f76ef 100644 --- a/src/ips_options/ips_base64.cc +++ b/src/ips_options/ips_base64.cc @@ -36,6 +36,7 @@ #include "util.h" #include "profiler.h" #include "utils/sf_base64decode.h" +#include "utils/util_unfold.h" #include "detection/detection_defines.h" #include "detection/detection_util.h" #include "framework/cursor.h" diff --git a/src/ips_options/ips_byte_extract.h b/src/ips_options/ips_byte_extract.h index 2f3b8bff4..8c6e3e8e5 100644 --- a/src/ips_options/ips_byte_extract.h +++ b/src/ips_options/ips_byte_extract.h @@ -1,7 +1,6 @@ //-------------------------------------------------------------------------- // Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. // Copyright (C) 2010-2013 Sourcefire, Inc. -// Author: Ryan Jordan // // 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 @@ -18,6 +17,8 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// ips_byte_extract.h author Ryan Jordan + #ifndef IPS_BYTE_EXTRACT_H #define IPS_BYTE_EXTRACT_H diff --git a/src/ips_options/ips_flow.h b/src/ips_options/ips_flow.h index 83902e65a..3d845be84 100644 --- a/src/ips_options/ips_flow.h +++ b/src/ips_options/ips_flow.h @@ -21,10 +21,12 @@ #ifndef IPS_FLOW_H #define IPS_FLOW_H -int OtnFlowFromServer(OptTreeNode* otn); -int OtnFlowFromClient(OptTreeNode* otn); -int OtnFlowIgnoreReassembled(OptTreeNode* otn); -int OtnFlowOnlyReassembled(OptTreeNode* otn); +struct OptTreeNode; + +int OtnFlowFromServer(OptTreeNode*); +int OtnFlowFromClient(OptTreeNode*); +int OtnFlowIgnoreReassembled(OptTreeNode*); +int OtnFlowOnlyReassembled(OptTreeNode*); #endif diff --git a/src/ips_options/ips_flowbits.h b/src/ips_options/ips_flowbits.h index 559db104e..5c06b3856 100644 --- a/src/ips_options/ips_flowbits.h +++ b/src/ips_options/ips_flowbits.h @@ -20,12 +20,12 @@ #ifndef IPS_FLOWBITS_H #define IPS_FLOWBITS_H -void FlowbitResetCounts(void); +void FlowbitResetCounts(); int FlowBits_SetOperation(void*); void setFlowbitSize(unsigned); -unsigned int getFlowbitSize(void); -unsigned int getFlowbitSizeInBytes(void); +unsigned int getFlowbitSize(); +unsigned int getFlowbitSizeInBytes(); #endif diff --git a/src/ips_options/ips_pcre.cc b/src/ips_options/ips_pcre.cc index 844ff1878..ad4000707 100644 --- a/src/ips_options/ips_pcre.cc +++ b/src/ips_options/ips_pcre.cc @@ -569,7 +569,7 @@ int PcreOption::eval(Cursor& c, Packet*) PROFILE_VARS; MODULE_PROFILE_START(pcrePerfStats); - //short circuit this for testing pcre performance impact + // short circuit this for testing pcre performance impact if (SnortConfig::no_pcre()) { MODULE_PROFILE_END(pcrePerfStats); diff --git a/src/log/dev_notes.txt b/src/log/dev_notes.txt new file mode 100644 index 000000000..bd7c0122c --- /dev/null +++ b/src/log/dev_notes.txt @@ -0,0 +1,14 @@ +Text output logging facilities are located here: + +* log - provides convenience functions for global packet logging. + +* log_text - provides convenience functions for logging with a TextLog. + +* messages - provides Dumper class and message logging facilities. + +* obfuscation - provides an API for logging packets w/o revealing things + like IP addresses. + +* text_log - provides a class like implementation (TextLog) for multiple + instances of text-based log files. + diff --git a/src/log/log.h b/src/log/log.h index 8234a876c..a5fc2a18c 100644 --- a/src/log/log.h +++ b/src/log/log.h @@ -24,10 +24,7 @@ #include "protocols/packet.h" #include "main/snort_types.h" -namespace tcp -{ -struct TCPHdr; -} // namespace tcp +namespace tcp { struct TCPHdr; } SO_PUBLIC void CreateTCPFlagString(const tcp::TCPHdr* const, char*); diff --git a/src/log/log_text.h b/src/log/log_text.h index ddf7f00eb..8dc5e21ba 100644 --- a/src/log/log_text.h +++ b/src/log/log_text.h @@ -17,22 +17,12 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/** - * @file log_text.h - * @author Russ Combs - * @date Fri Jun 27 10:34:37 2003 - * - * @brief logging to text file - * - * Use these methods to write to a TextLog. - */ +// log_text.h author Russ Combs #ifndef LOG_TEXT_H #define LOG_TEXT_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// Use these methods to write to a TextLog #include #include "log/text_log.h" @@ -41,14 +31,9 @@ struct Packet; struct Event; -namespace ip -{ -struct IP4Hdr; -} -namespace tcp -{ -struct TCPHdr; -} +namespace ip { struct IP4Hdr; } +namespace tcp { struct TCPHdr; } + typedef ip::IP4Hdr IP4Hdr; void LogPriorityData(TextLog*, const Event*, bool doNewLine); diff --git a/src/log/obfuscation.h b/src/log/obfuscation.h index 8fbedc727..d9d99f842 100644 --- a/src/log/obfuscation.h +++ b/src/log/obfuscation.h @@ -108,7 +108,7 @@ typedef struct _ObfuscationApi * None */ - void (* resetObfuscationEntries)(void); + void (* resetObfuscationEntries)(); /* * Adds an obfuscation entry to the queue @@ -258,5 +258,5 @@ typedef struct _ObfuscationApi /* For access when including header */ extern ObfuscationApi* obApi; -#endif /* OBFUSCATION_H */ +#endif diff --git a/src/log/text_log.h b/src/log/text_log.h index 0946fdae0..e2b9773ab 100644 --- a/src/log/text_log.h +++ b/src/log/text_log.h @@ -17,13 +17,12 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/** - * @file text_log.h - * @author Russ Combs - * @date Fri Jun 27 10:34:37 2003 - * - * @brief declares buffered text stream for logging - * +// text_log.h Russ Combs + +#ifndef TEXT_LOG_H +#define TEXT_LOG_H + +/* * Declares a TextLog_*() api for buffered logging. This allows * relatively painless transition from fprintf(), fwrite(), etc. * to a buffer that is formatted in memory and written with one @@ -35,9 +34,6 @@ * name plus a timestamp. */ -#ifndef TEXT_LOG_H -#define TEXT_LOG_H - #include #include #include diff --git a/src/loggers/alert_luajit.cc b/src/loggers/alert_luajit.cc index 9aa78d5d6..9ae6af5d4 100644 --- a/src/loggers/alert_luajit.cc +++ b/src/loggers/alert_luajit.cc @@ -56,7 +56,6 @@ struct SnortEvent const char* msg; const char* svc; - const char* os; }; struct SnortPacket @@ -97,7 +96,6 @@ SO_PUBLIC const SnortEvent* get_event() lua_event.msg = ""; lua_event.svc = event->sig_info->num_services ? event->sig_info->services[1].service : "n/a"; - lua_event.os = event->sig_info->os ? event->sig_info->os : "n/a"; return &lua_event; } diff --git a/src/loggers/dev_notes.txt b/src/loggers/dev_notes.txt new file mode 100644 index 000000000..c2a430ae8 --- /dev/null +++ b/src/loggers/dev_notes.txt @@ -0,0 +1,11 @@ +Logger subclasses that provide logging and event alerting facilities. + +unified2 is currently the best logger for serializing various data like +events and packets and is the only Logger supporting extra data fields. +Currently only the SMTP and HTTP inspectors produce exta data. + +There is separate utility called u2spewfoo provided under tools/ that can +dump the binary u2 log in text format. + +This will likely be replaced with a FlatBuffer implementation. + diff --git a/src/loggers/unified2_common.h b/src/loggers/unified2_common.h index 84768fbd2..0ef56fd5b 100644 --- a/src/loggers/unified2_common.h +++ b/src/loggers/unified2_common.h @@ -31,16 +31,11 @@ #endif #include -/*! \defgroup Unified2 - */ -/** \addtogroup Unified2 - @{*/ - -//SNORT DEFINES -//Long time ago... +// SNORT DEFINES +// Long time ago... #define UNIFIED2_EVENT 1 -//CURRENT +// CURRENT #define UNIFIED2_PACKET 2 #define UNIFIED2_IDS_EVENT 7 #define UNIFIED2_IDS_EVENT_IPV6 72 @@ -57,8 +52,8 @@ typedef struct _Serial_Unified2_Header uint32_t length; } Serial_Unified2_Header; -//UNIFIED2_IDS_EVENT_VLAN = type 104 -//comes from SFDC to EStreamer archive in serialized form with the extended header +// UNIFIED2_IDS_EVENT_VLAN = type 104 +// comes from SFDC to EStreamer archive in serialized form with the extended header struct Unified2IDSEvent { uint32_t sensor_id; @@ -75,15 +70,15 @@ struct Unified2IDSEvent uint16_t sport_itype; uint16_t dport_icode; uint8_t protocol; - uint8_t impact_flag; //overloads packet_action + uint8_t impact_flag; // overloads packet_action uint8_t impact; uint8_t blocked; uint32_t mpls_label; uint16_t vlanId; - uint16_t pad2; //Policy ID + uint16_t pad2; // Policy ID }; -//UNIFIED2_IDS_EVENT_IPV6_VLAN = type 105 +// UNIFIED2_IDS_EVENT_IPV6_VLAN = type 105 typedef struct _Unified2IDSEventIPv6 { uint32_t sensor_id; @@ -108,7 +103,7 @@ typedef struct _Unified2IDSEventIPv6 uint16_t pad2; /*could be IPS Policy local id to support local sensor alerts*/ } Unified2IDSEventIPv6; -//UNIFIED2_PACKET = type 2 +// UNIFIED2_PACKET = type 2 typedef struct _Serial_Unified2Packet { uint32_t sensor_id; @@ -127,7 +122,7 @@ typedef struct _Unified2ExtraDataHdr uint32_t event_length; }Unified2ExtraDataHdr; -//UNIFIED2_EXTRA_DATA - type 110 +// UNIFIED2_EXTRA_DATA - type 110 typedef struct _SerialUnified2ExtraData { uint32_t sensor_id; @@ -144,7 +139,7 @@ typedef struct _Data_Blob const uint8_t* data; } Data_Blob; -//UNIFIED2_EXTRA_DATA - type 110 +// UNIFIED2_EXTRA_DATA - type 110 typedef struct _Serial_Unified2ExtraData { uint32_t sensor_id; @@ -188,7 +183,7 @@ typedef enum _EventDataType #define Serial_Unified2IDSEventIPv6 Unified2IDSEventIPv6 //---------------LEGACY, type '7' -//These structures are not used anymore in the product +// These structures are not used anymore in the product typedef struct _Serial_Unified2IDSEvent_legacy { uint32_t sensor_id; @@ -205,7 +200,7 @@ typedef struct _Serial_Unified2IDSEvent_legacy uint16_t sport_itype; uint16_t dport_icode; uint8_t protocol; - uint8_t impact_flag; //sets packet_action + uint8_t impact_flag; // sets packet_action uint8_t impact; uint8_t blocked; } Serial_Unified2IDSEvent_legacy; @@ -234,6 +229,5 @@ typedef struct _Serial_Unified2IDSEventIPv6_legacy ////////////////////-->LEGACY -/*@}*/ #endif diff --git a/src/main.h b/src/main.h index a29667b74..9a0a0c092 100644 --- a/src/main.h +++ b/src/main.h @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- + // main.cc author Russ Combs #ifndef MAIN_H @@ -28,6 +29,7 @@ struct lua_State; const char* get_prompt(); +// commands provided by the snort module int main_dump_stats(lua_State* = nullptr); int main_rotate_stats(lua_State* = nullptr); int main_reload_config(lua_State* = nullptr); diff --git a/src/main/analyzer.h b/src/main/analyzer.h index 51fc31ffe..dd480859e 100644 --- a/src/main/analyzer.h +++ b/src/main/analyzer.h @@ -20,7 +20,11 @@ #ifndef ANALYZER_H #define ANALYZER_H -#include "snort_types.h" +// Analyzer provides the packet acquisition and processing loop. Since it +// runs in a different thread, it also provides a command facility so that +// to control the thread and swap configuration. + +#include "main/snort_types.h" enum AnalyzerCommand { diff --git a/src/main/build.h b/src/main/build.h index ef36d6b9d..91e68cf27 100644 --- a/src/main/build.h +++ b/src/main/build.h @@ -1,3 +1,6 @@ +#ifndef BUILD_H +#define BUILD_H + //-----------------------------------------------// // ____ _ // // / ___| _ __ ___ _ __| |_ _ _ // @@ -7,5 +10,7 @@ // // //-----------------------------------------------// -#define BUILD "160" +#define BUILD "161" + +#endif diff --git a/src/main/dev_notes.txt b/src/main/dev_notes.txt new file mode 100644 index 000000000..69d8471aa --- /dev/null +++ b/src/main/dev_notes.txt @@ -0,0 +1,5 @@ +This directory provides the top-level application objects and services. +SnortConfig is used heavily throughout the code and should be updated so +that builtin modules can attach state in a generic but readily accessible +fashion. + diff --git a/src/main/help.h b/src/main/help.h index 58510466b..a720aeb22 100644 --- a/src/main/help.h +++ b/src/main/help.h @@ -20,6 +20,9 @@ #ifndef HELP_H #define HELP_H +// utility methods that provide output modes other than the normal packet +// processing. these are called based on command line arguments. + struct SnortConfig; void config_markup(SnortConfig*, const char*); diff --git a/src/main/modules.cc b/src/main/modules.cc index 0a6f10078..040fffefe 100644 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -177,6 +177,11 @@ bool EventQueueModule::set(const char*, Value& v, SnortConfig* sc) // search engine module //------------------------------------------------------------------------- +// FIXIT-L valid search methods should be obtained from available mpse plugins +#define SEARCH_METHODS \ + "ac_banded | ac_bnfa | ac_bnfa_q | ac_full | ac_full_q | " \ + "ac_sparse | ac_sparse_bands | ac_std" + static const Parameter search_engine_params[] = { { "bleedover_port_limit", Parameter::PT_INT, "1:", "1024", @@ -215,7 +220,7 @@ static const Parameter search_engine_params[] = { "inspect_stream_inserts", Parameter::PT_BOOL, nullptr, "false", "inspect reassembled payload - disabling is good for performance, bad for detection" }, - { "search_method", Parameter::PT_STRING, nullptr, "ac_bnfa_q", + { "search_method", Parameter::PT_SELECT, SEARCH_METHODS, "ac_bnfa_q", "set fast pattern algorithm - choose available search engine" }, { "split_any_any", Parameter::PT_BOOL, nullptr, "false", diff --git a/src/main/modules.h b/src/main/modules.h index b0ee75d57..d9366e1d4 100644 --- a/src/main/modules.h +++ b/src/main/modules.h @@ -21,6 +21,9 @@ #ifndef MODULES_H #define MODULES_H +// this is for builtin module initialization. +// ideally, modules.cc would be refactored and several files. + void module_init(); #endif diff --git a/src/main/policy.h b/src/main/policy.h index a4fdd4a73..cab655887 100644 --- a/src/main/policy.h +++ b/src/main/policy.h @@ -20,6 +20,12 @@ #ifndef SNORT_POLICY_H #define SNORT_POLICY_H +// the following policy types are defined: +// +// -- network - for packet handling +// -- inspection - for flow handling +// -- ips - for rule handling + #include #include diff --git a/src/main/shell.h b/src/main/shell.h index 4310acfae..579cef6b5 100644 --- a/src/main/shell.h +++ b/src/main/shell.h @@ -20,6 +20,8 @@ #ifndef SHELL_H #define SHELL_H +// Shell encapsulates a Lua state. There is one for each policy file. + #include struct lua_State; diff --git a/src/main/snort.h b/src/main/snort.h index 404913a0d..49699d80f 100644 --- a/src/main/snort.h +++ b/src/main/snort.h @@ -21,9 +21,7 @@ #ifndef SNORT_H #define SNORT_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// Snort is the top-level application class. #include #include diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index dcdd3e77b..52788415b 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -276,7 +276,7 @@ void SnortConfig::setup() // FIXIT-L see SnortInit() on config printing //detection_filter_print_config(detection_filter_config); - ////RateFilter_PrintConfig(rate_filter_config); + //RateFilter_PrintConfig(rate_filter_config); //print_thresholding(threshold_config, 0); //PrintRuleOrder(rule_lists); diff --git a/src/main/snort_config.h b/src/main/snort_config.h index bd01e19b3..b8d98ce54 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -20,6 +20,9 @@ #ifndef SNORT_CONFIG_H #define SNORT_CONFIG_H +// SnortConfig encapsulates all data loaded from the config files. +// FIXIT-L privatize most of this stuff. + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/main/snort_debug.h b/src/main/snort_debug.h index e014979b8..8fcdb6437 100644 --- a/src/main/snort_debug.h +++ b/src/main/snort_debug.h @@ -21,6 +21,11 @@ #ifndef SNORT_DEBUG_H #define SNORT_DEBUG_H +// this provides a set of flags that can be set by environment variable to +// turn on the output of specific debug messages. +// +// FIXIT-L this needs to be replaced with a module facility. + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -36,7 +41,7 @@ #include #endif -#include "snort_types.h" +#include "main/snort_types.h" // this env var uses the lower 32 bits of the flags: #define DEBUG_VARIABLE "SNORT_DEBUG" diff --git a/src/main/snort_module.h b/src/main/snort_module.h index 61ee6a673..898c6abd5 100644 --- a/src/main/snort_module.h +++ b/src/main/snort_module.h @@ -21,6 +21,9 @@ #ifndef SNORT_MODULE_H #define SNORT_MODULE_H +// the snort module is for handling command line args, +// shell commands, and basic application stats + class Module* get_snort_module(); #endif diff --git a/src/main/snort_types.h b/src/main/snort_types.h index 5d77c7cdb..b6d5b6e0a 100644 --- a/src/main/snort_types.h +++ b/src/main/snort_types.h @@ -20,6 +20,8 @@ #ifndef SNORT_TYPES_H #define SNORT_TYPES_H +// defines common types if not already defined + #include #include #include @@ -137,5 +139,5 @@ typedef uint16_t Port; #define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */ #endif -#endif /* __SF_TYPES_H__ */ +#endif diff --git a/src/main/thread.h b/src/main/thread.h index 5b6fd7a76..246bb82bc 100644 --- a/src/main/thread.h +++ b/src/main/thread.h @@ -20,6 +20,8 @@ #ifndef THREAD_H #define THREAD_H +// basic thread management utilities + #include #include "main/snort_types.h" @@ -45,6 +47,9 @@ void pin_thread_to_cpu(const char* source); SO_PUBLIC unsigned get_instance_id(); SO_PUBLIC unsigned get_instance_max(); +// all modules that use packet thread files should call this function to +// get a packet thread specific path. name should be the module name or +// derived therefrom. SO_PUBLIC const char* get_instance_file(std::string&, const char* name); void take_break(); diff --git a/src/managers/action_manager.h b/src/managers/action_manager.h index 341caa7be..5c7606773 100644 --- a/src/managers/action_manager.h +++ b/src/managers/action_manager.h @@ -20,6 +20,10 @@ #ifndef ACTION_MANAGER_H #define ACTION_MANAGER_H +// Factory for IpsActions. Also manages their associated action queue, +// which is just a single response deferred until end of current packet +// processing. + #ifdef HAVE_CONFIG_H # include "config.h" #endif diff --git a/src/managers/codec_manager.h b/src/managers/codec_manager.h index d9e269c0c..6162e8e5a 100644 --- a/src/managers/codec_manager.h +++ b/src/managers/codec_manager.h @@ -21,6 +21,12 @@ #ifndef MANAGERS_CODEC_MANAGER_H #define MANAGERS_CODEC_MANAGER_H +// Factory for Codecs. Runtime support is provided by PacketManager. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/src/managers/dev_notes.txt b/src/managers/dev_notes.txt new file mode 100644 index 000000000..9aa98d8ab --- /dev/null +++ b/src/managers/dev_notes.txt @@ -0,0 +1,32 @@ +Managers provide the ability to instantiate and utilize the various plugins +in Snort++. There is a separate manager class for each plugin type, plus +one for modules, plugins, scripts, and packets. + +The only plugin that is reloadable is Inspector. It has reference counts +so that it won't be freed while an active flow is using it. + +Only the action, codec, and inspector managers have thread local state: + +* action manager has an action function +* codec manager has the grinder and related stats +* inspector manager has a flag to control calling the clear method + +Some Lua files are here as they are coupled closely with C++ code in this +directory (module_manager.cc): + +* snort_config.lua provides the ability to parse a Lua configuration. It + is much easier to traverse the Lua tables via Lua itself. This file + leverages the LuaJIT FFI to open and close tables and set values. + +* snort_plugin.lua provides FFI for script plugins (ips options and + loggers). This is pretty thin at the moment and should be expanded to + provide more data. + +These Lua files get installed in LUA_PATH. + +Module manager recursively sets default values for all parameters within a +module. While list items have default values, default lists are not +provided by modules; that is strictly done in Lua with snort_defaults.lua. +This not only simplifies the code somewhat, it also makes the most sense +from a user perspective. + diff --git a/src/managers/event_manager.h b/src/managers/event_manager.h index 1a2a959a0..fd5a255e6 100644 --- a/src/managers/event_manager.h +++ b/src/managers/event_manager.h @@ -20,6 +20,10 @@ #ifndef EVENT_MANAGER_H #define EVENT_MANAGER_H +// Factory for Loggers. +// OutputSet is a group of Loggers that can be attached to external data. +// Also provides runtime logging. + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/managers/inspector_manager.h b/src/managers/inspector_manager.h index 4fe8cbd72..cd2a6e817 100644 --- a/src/managers/inspector_manager.h +++ b/src/managers/inspector_manager.h @@ -20,6 +20,9 @@ #ifndef INSPECTOR_MANAGER_H #define INSPECTOR_MANAGER_H +// Factory for Inspectors. +// Also provides packet evaluation. + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/managers/ips_manager.h b/src/managers/ips_manager.h index a1e35b933..264df6f8b 100644 --- a/src/managers/ips_manager.h +++ b/src/managers/ips_manager.h @@ -20,13 +20,16 @@ #ifndef IPS_MANAGER_H #define IPS_MANAGER_H +// Factory for IpsOptions. +// Runtime use of IpsOptions is via detection option tree. + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include -#include "snort_types.h" +#include "main/snort_types.h" #include "detection/detection_options.h" #include "framework/base_api.h" #include "framework/ips_option.h" @@ -88,8 +91,8 @@ public: static void setup_options(); static void clear_options(); static bool verify(SnortConfig*); -#ifdef PIGLET +#ifdef PIGLET static IpsOptionWrapper* instantiate(const char*, Module*, struct OptTreeNode*); #endif }; diff --git a/src/managers/module_manager.cc b/src/managers/module_manager.cc index 465cb9c38..36f56b263 100644 --- a/src/managers/module_manager.cc +++ b/src/managers/module_manager.cc @@ -502,7 +502,7 @@ static bool set_value(const char* fqn, Value& v) // item // -- recursively set all defaults after calling Module::begin(), skipping // lists and list items -// -- on close_table(), call Module::begin() for each module, list, and list +// -- on close_table(), call Module::end() for each module, list, and list // item //------------------------------------------------------------------------- diff --git a/src/managers/module_manager.h b/src/managers/module_manager.h index 3589f6ec4..94a30b28c 100644 --- a/src/managers/module_manager.h +++ b/src/managers/module_manager.h @@ -20,6 +20,9 @@ #ifndef MODULE_MANAGER_H #define MODULE_MANAGER_H +// Factory for Modules, including all builtin and plugin modules. +// Modules are strictly used during parse time. + #include //------------------------------------------------------------------------- @@ -42,6 +45,7 @@ public: static void show_modules(); static void show_module(const char*); + // output for matching module name; prefix is sufficient if not exact static void show_configs(const char* = nullptr, bool exact = false); static void show_commands(const char* = nullptr, bool exact = false); static void show_gids(const char* = nullptr, bool exact = false); diff --git a/src/managers/mpse_manager.h b/src/managers/mpse_manager.h index 230b72377..746e57e94 100644 --- a/src/managers/mpse_manager.h +++ b/src/managers/mpse_manager.h @@ -20,11 +20,15 @@ #ifndef MPSE_MANAGER_H #define MPSE_MANAGER_H +// Factory for Mpse. The same Mpse type is used for rule matching as well +// as searching by inspectors with a SearchTool. Runtime use of the Mpse +// is by the fast pattern detection module. + #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include "snort_types.h" +#include "main/snort_types.h" #include "framework/base_api.h" #ifdef PIGLET diff --git a/src/managers/plugin_manager.h b/src/managers/plugin_manager.h index 81943b439..0ed63b899 100644 --- a/src/managers/plugin_manager.h +++ b/src/managers/plugin_manager.h @@ -20,17 +20,9 @@ #ifndef PLUGIN_MANAGER_H #define PLUGIN_MANAGER_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "snort_types.h" -#include "framework/base_api.h" - //------------------------------------------------------------------------- -// Loading plugins is a 3 step process: +// Manages all plugins. Loading plugins is a 3 step process: +// // 1. ScriptManager loads available scripts and generates an API // for each. // 2. PluginManager loads all API including static, dynamic, generated. @@ -39,6 +31,11 @@ // based on configuration. //------------------------------------------------------------------------- +#include + +#include "main/snort_types.h" +#include "framework/base_api.h" + class Module; struct SnortConfig; diff --git a/src/managers/script_manager.h b/src/managers/script_manager.h index 8d3831fc6..ec0c499dd 100644 --- a/src/managers/script_manager.h +++ b/src/managers/script_manager.h @@ -20,13 +20,12 @@ #ifndef SCRIPT_MANAGER_H #define SCRIPT_MANAGER_H -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +// Factory for Lua script plugins used for IpsOptions and Loggers implemented +// in Lua. Runtime use is via the actual plugin type manager. #include -#include "snort_types.h" +#include "main/snort_types.h" #include "framework/base_api.h" //------------------------------------------------------------------------- diff --git a/src/managers/so_manager.h b/src/managers/so_manager.h index 8d41f7cdd..dc3cb0cf2 100644 --- a/src/managers/so_manager.h +++ b/src/managers/so_manager.h @@ -20,11 +20,10 @@ #ifndef SO_MANAGER_H #define SO_MANAGER_H -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +// Factory for shared object rules. +// Runtime is same as for text rules. -#include "snort_types.h" +#include "main/snort_types.h" #include "framework/base_api.h" #include "framework/so_rule.h" diff --git a/src/network_inspectors/arp_spoof/dev_notes.txt b/src/network_inspectors/arp_spoof/dev_notes.txt new file mode 100644 index 000000000..17f31481d --- /dev/null +++ b/src/network_inspectors/arp_spoof/dev_notes.txt @@ -0,0 +1,9 @@ +Implement a specialized inspection tool which locates and alerts on ARP +protocol violations. This network inspector looks at all ARP ethernet +frames and attempts to locate ARP spoofing attacks. + +It alerts on source or destination address mismatch. It also alerts on an +ARP request ocuring on a uni-cast frame (needs to be multi-cast). + +A network inspector module as it needs to examine all ethernet frames with +packet type of ARP. diff --git a/src/network_inspectors/binder/bind_module.h b/src/network_inspectors/binder/bind_module.h index db455abfc..1aba30da0 100644 --- a/src/network_inspectors/binder/bind_module.h +++ b/src/network_inspectors/binder/bind_module.h @@ -21,6 +21,8 @@ #ifndef BIND_MODULE_H #define BIND_MODULE_H +// binder management interface + #include #include "framework/module.h" @@ -50,6 +52,7 @@ public: bool begin(const char*, int, SnortConfig*) override; bool end(const char*, int, SnortConfig*) override; + // used to create default binder void add(const char* service, const char* type); void add(unsigned proto, const char* type); diff --git a/src/network_inspectors/binder/dev_notes.txt b/src/network_inspectors/binder/dev_notes.txt new file mode 100644 index 000000000..0d4e3b13d --- /dev/null +++ b/src/network_inspectors/binder/dev_notes.txt @@ -0,0 +1,27 @@ +The binder maps configuration to traffic when a flow is started (via the +eval method) and when service is identified (via the exec method). Binder +sets the service on the flow to that of the service inspector when it is +bound to the flow. + +If the binder is not explicitly configured but the wizard is configured, +then the inspector manager will create a default binder with bindings for +each configured service inspector. + +BinderModule creates a vector of Bindings from the Lua binder table which +is moved to the Binder upon its construction. Upon start of flow, the +vector is iterated in search of applicable bindings. These include: + +* stream inspector +* service inspector +* passive inspector + +Note that although Flow contains both clouseau and gadget, only one of +those is bound to the flow at a time. The wizard fills in until service is +identified at which point clouseau is removed and gadget is installed. + +Note that bindings are recursive. It is possible to bind a policy (config +file) that has its own binder, and so on. + +The implementation is not yet optimized for performance. A faster method +of searching for applicable bindings should be developed. + diff --git a/src/network_inspectors/dev_notes.txt b/src/network_inspectors/dev_notes.txt new file mode 100644 index 000000000..9da14ec63 --- /dev/null +++ b/src/network_inspectors/dev_notes.txt @@ -0,0 +1,23 @@ +A set of miscellaneous network inspectors for packet analysis, performance +monitoring, policy binding, etc. They are grouped here as they operate and +the network and/or IP protocol layer. + +The collection includes: + +binder - The flow to config mapping (policy selection) + +arp_spoof - Monitor ARP requests/replies for consistancy. Locate spoofing +attempts and ARP cache inconsistancies + +port_scan - A tool to attempt to locate IP port scanning activity. + +perf_monitor - Although not strictly a network inspector, this module +monitors Snort++ performance criteria. Implemented as a network_inspector +as it processes each valid packet. + +normalize - A collection of IP/ICMP/TCP and potentially UDP frame level +normalizations. + +This entire set of inspectors is instantiated as a group via +network_inspectors.cc + diff --git a/src/network_inspectors/normalize/dev_notes.txt b/src/network_inspectors/normalize/dev_notes.txt new file mode 100644 index 000000000..31184ce57 --- /dev/null +++ b/src/network_inspectors/normalize/dev_notes.txt @@ -0,0 +1,23 @@ +Implement a large group of packet normalizations. See normalize.h for the +entire set. If enabled/configured, examine each packet and make required +modifications. + +The primary utility is to 'repair' protocol issues and provide a cleaner +packet to the downstream network. This ensures that packets that Snort +passes have the best likelihood of reaching their destination since +otherwise attackers could craft packets that facilitate evasions. The +normalizations are done before any related inspection and detection by +Snort. + +Process IP4, IP6, ICMP4, ICMP6, and TCP protocols. No UDP nor Ethernet +level normalizations currently exist. + +Maintain activity counts and print these counts as part of the Snort exit +(or on-demain) counts. + +If inline and able to perform packet replacement, replace the normalized +packet in the output stream. + +Note that TCP stream normalizations are done within the stream_tcp module. +The configuration is done together with the above normalizations, however. + diff --git a/src/network_inspectors/normalize/normalize.h b/src/network_inspectors/normalize/normalize.h index 8e7f7eeda..8d373c157 100644 --- a/src/network_inspectors/normalize/normalize.h +++ b/src/network_inspectors/normalize/normalize.h @@ -22,6 +22,7 @@ #include #include + #include "main/policy.h" #include "framework/counts.h" diff --git a/src/network_inspectors/perf_monitor/dev_notes.txt b/src/network_inspectors/perf_monitor/dev_notes.txt new file mode 100644 index 000000000..b28aa0a18 --- /dev/null +++ b/src/network_inspectors/perf_monitor/dev_notes.txt @@ -0,0 +1,27 @@ +Implement a comprehensive performance collection, processing, and logging +facility. + +There are two broad classes of statistics: Basic packet processing +information and Flow statistics. + +Basic performance statistics include items such as event counts, packet +counts, stream counts, dropped packet counter, processor load, etc. The +Flow statistics count flows between IP addresses. + +The general data flow is: + +1. Process the relevant information from each packet as it's being + inspected. Increment local counters. + +2. At a configured interval, process the counters into the statistics. + +3. At same processing interval, Log these statistics to a file. + +4. Switch to another log file for the next cycle. + +The type of statistics collection/processing/logging is controlled via configuration. + +perf_monitor is implemented as a network_inspector to give it access to the +per-packet processing mechanism. It doesn't perform inspection in the +broad sense, but rather collects and logs information. + diff --git a/src/network_inspectors/perf_monitor/perf.h b/src/network_inspectors/perf_monitor/perf.h index 63158b8f4..8d032ae42 100644 --- a/src/network_inspectors/perf_monitor/perf.h +++ b/src/network_inspectors/perf_monitor/perf.h @@ -76,6 +76,7 @@ typedef struct _SFPERF uint32_t flowip_memcap; } SFPERF; +/* The perf_monitor state information and collected statistics */ SO_PUBLIC extern THREAD_LOCAL SFBASE sfBase; extern THREAD_LOCAL SFFLOW sfFlow; extern THREAD_LOCAL SFEVENT sfEvent; @@ -96,6 +97,7 @@ void sfPerfStatsSummary(SFPERF*); void SetSampleTime(SFPERF*, Packet*); void InitPerfStats(SFPERF* sfPerf); +/* functions to set & get the RotatePerfFileFlag */ static inline void SetRotatePerfFileFlag(void) { perfmon_rotate_perf_file = 1; diff --git a/src/network_inspectors/perf_monitor/perf_base.h b/src/network_inspectors/perf_monitor/perf_base.h index 677edaeb4..d59e801c7 100644 --- a/src/network_inspectors/perf_monitor/perf_base.h +++ b/src/network_inspectors/perf_monitor/perf_base.h @@ -31,21 +31,25 @@ # include "config.h" #endif -#include "network_inspectors/perf_monitor/sfprocpidstats.h" #include "main/snort_types.h" #include "main/snort_debug.h" #include "protocols/packet.h" -#include "network_inspectors/normalize/normalize.h" +#include "normalize/normalize.h" +#include "sfprocpidstats.h" #include #include +/* Structure used for access to the low-level (i.e. DAQ level) + packet receive and drop counters. Dropped packets are those + lost in the input queue due to snort loading/processing. */ typedef struct _PKTSTATS { uint64_t pkts_recv; uint64_t pkts_drop; } PKTSTATS; +/* Define the various counter identifiers */ enum PerfCounts { PERF_COUNT_IP4_TRIM, @@ -81,6 +85,7 @@ enum PerfCounts PERF_COUNT_MAX }; +/* The base set of raw counters */ struct SFBASE { uint64_t total_wire_packets; @@ -171,6 +176,7 @@ struct SFBASE uint64_t total_iAlerts; }; +/* Common structure for time indication */ struct SYSTIMES { double usertime; @@ -179,6 +185,7 @@ struct SYSTIMES double realtime; }; +/* The 'processed' performance statistics */ struct SFBASE_STATS { uint64_t total_packets; diff --git a/src/network_inspectors/perf_monitor/perf_event.h b/src/network_inspectors/perf_monitor/perf_event.h index 5824d7ea5..7404a9d3e 100644 --- a/src/network_inspectors/perf_monitor/perf_event.h +++ b/src/network_inspectors/perf_monitor/perf_event.h @@ -27,8 +27,9 @@ #ifndef PERF_EVENT_H #define PERF_EVENT_H -#include "snort_types.h" +#include "main/snort_types.h" +/* Raw event counters */ typedef struct _SFEVENT { uint64_t NQEvents; @@ -37,6 +38,7 @@ typedef struct _SFEVENT uint64_t TotalEvents; } SFEVENT; +/* Processed event counters */ typedef struct _SFEVENT_STATS { uint64_t NQEvents; diff --git a/src/network_inspectors/perf_monitor/perf_flow.h b/src/network_inspectors/perf_monitor/perf_flow.h index e2a242c2f..9f7f902c4 100644 --- a/src/network_inspectors/perf_monitor/perf_flow.h +++ b/src/network_inspectors/perf_monitor/perf_flow.h @@ -25,8 +25,8 @@ #ifndef PERF_FLOW_H #define PERF_FLOW_H -#include "snort_types.h" -#include "sfxhash.h" +#include "main/snort_types.h" +#include "hash/sfxhash.h" #include "sfip/sfip_t.h" #include "protocols/packet.h" @@ -62,6 +62,7 @@ typedef struct _icmpflow int display[256]; } ICMPFLOW; +/* Raw flow statistics */ typedef struct _sfflow { time_t time; @@ -90,6 +91,7 @@ typedef struct _sfflow SFXHASH* ipMap; } SFFLOW; +/* Processed flow statistics */ typedef struct _sfflow_stats { time_t time; diff --git a/src/network_inspectors/perf_monitor/perf_module.h b/src/network_inspectors/perf_monitor/perf_module.h index 1986f478a..81cf2e928 100644 --- a/src/network_inspectors/perf_monitor/perf_module.h +++ b/src/network_inspectors/perf_monitor/perf_module.h @@ -30,6 +30,7 @@ extern THREAD_LOCAL SimpleStats pmstats; extern THREAD_LOCAL ProfileStats perfmonStats; +/* The Module Class for incorporation into Snort++ */ class PerfMonModule : public Module { public: diff --git a/src/network_inspectors/perf_monitor/sfprocpidstats.h b/src/network_inspectors/perf_monitor/sfprocpidstats.h index 4bca36626..345165e19 100644 --- a/src/network_inspectors/perf_monitor/sfprocpidstats.h +++ b/src/network_inspectors/perf_monitor/sfprocpidstats.h @@ -46,8 +46,13 @@ typedef struct _SFPROCPIDSTATS int iCPUs; } SFPROCPIDSTATS; +/* Init CPU usage processing */ int sfInitProcPidStats(SFPROCPIDSTATS* sfProcPidStats); + +/* Fetch the CPU utilization numbers for process */ int sfProcessProcPidStats(SFPROCPIDSTATS* sfProcPidStats); + +/* Free the statistics structure */ void FreeProcPidStats(SFPROCPIDSTATS* sfProcPidStats); #endif diff --git a/src/network_inspectors/port_scan/dev_notes.txt b/src/network_inspectors/port_scan/dev_notes.txt new file mode 100644 index 000000000..0585d9a33 --- /dev/null +++ b/src/network_inspectors/port_scan/dev_notes.txt @@ -0,0 +1,78 @@ +A tool used to locate and alert port scanning activity. + +The configuration is in two parts. The _global entity is use to provide +parameters for the entire collection of port scanners. Then one can +configure many port scanners with distinct characteristics. + +port_scan is implemented as a network inspector module to give it access to +all packets and be able to inspect the IP level information (addresses, +protocols, ports, etc.) + +port_scan still crafts packets so that its information can be logged. That +is no longer necessary however, and when port_scan is rewritten, it will +only log the relevant information as data. + +The low, medium, and high thresholds and sense levels are hard-coded in +ps_detect.cc. + +Here are notes from the original (Snort) portscan.c: + +The philosophy of portscan detection that we use is based on a generic network +attack methodology: reconnaissance, network service enumeration, and service +exploitation. + +The reconnaissance phase determines what types of network protocols and +services that a host supports. This is the traditional phase where a portscan +occurs. An important requirement of this phase is that an attacker does not +already know what protocols and services are supported by the destination host. +If an attacker does know what services are open on the destination host then +there is no need for this phase. Because of this requirement, we assume that +if an attacker engages in this phase that they do not have prior knowledege to +what services are open. So, the attacker will need to query the ports or +protocols they are interested in. Most or at least some of these queries will +be negative and take the form of either an invalid response (TCP RSTs, ICMP +unreachables) or no response (in which case the host is firewalled or +filtered). We detect portscans from these negative queries. + +The primary goal of this portscan detection engine is to catch nmap and variant +scanners. The engine tracks connection attempts on TCP, UDP, ICMP, and IP +Protocols. If there is a valid response, the connection is marked as valid. +If there is no response or a invalid response (TCP RST), then we track these +attempts separately, so we know the number of invalid responses and the number +of connection attempts that generated no response. These two values +differentiate between a normal scan and a filtered scan. + +We detect four different scan types, and each scan type has its own negative +query characteristics. This is how we determine what type of scan we are +seeing. The different scans are: + +* Portscan +* Decoy Portscan +* Distributed Portscan +* Portsweep + +Portscan: A portscan is a basic one host to one host scan where multiple ports +are scanned on the destination host. We detect these scans by looking for a +low number of hosts that contacted the destination host and a high number of +unique ports and a high number of invalid responses or connections. + +Distributed Portscan: A distributed portscan occurs when many hosts connect to +a single destination host and multiple ports are scanned on the destination +host. We detect these scans by looking for a high number of hosts that +contacted the destination host and a high number of unique ports with a high +number of invalid responses or connections. + +Decoy Portscan: A decoy portscan is a variation on a distributed portscan, the +difference being that a decoy portscan connects to a single port multiple +times. This shows up in the unqiue port count that is tracked. There's still +many hosts connecting to the destination host. + +Portsweep: A portsweep is a basic one host to many host scan where one to a +few ports are scanned on each host. We detect these scans by looking at src +hosts for a high number of contacted hosts and a low number of unique ports +with a high number of invalid responses or connections. + +Each of these scans can also be detected as a filtered portscan, or a portscan +where there wasn't invalid responses and the responses have been firewalled in +some way. + diff --git a/src/network_inspectors/port_scan/ipobj.h b/src/network_inspectors/port_scan/ipobj.h index f577aaf53..b84d08200 100644 --- a/src/network_inspectors/port_scan/ipobj.h +++ b/src/network_inspectors/port_scan/ipobj.h @@ -34,7 +34,7 @@ #include #include -#include "sflsq.h" +#include "utils/sflsq.h" #include "sfip/sfip_t.h" struct PORTRANGE diff --git a/src/network_inspectors/port_scan/ps_detect.cc b/src/network_inspectors/port_scan/ps_detect.cc index 83e34cc7b..41a168b02 100644 --- a/src/network_inspectors/port_scan/ps_detect.cc +++ b/src/network_inspectors/port_scan/ps_detect.cc @@ -30,70 +30,6 @@ ** - Thanks to Judy Novak for her suggestion to log open ports ** on hosts that are portscanned. This idea makes portscan a lot more ** useful for analysts. -** -** The philosophy of portscan detection that we use is based on a generic -** network attack methodology: reconnaissance, network service enumeration, -** and service exploitation. -** -** The reconnaissance phase determines what types of network protocols and -** services that a host supports. This is the traditional phase where a -** portscan occurs. An important requirement of this phase is that an -** attacker does not already know what protocols and services are supported -** by the destination host. If an attacker does know what services are -** open on the destination host then there is no need for this phase. -** Because of this requirement, we assume that if an attacker engages in this -** phase that they do not have prior knowledege to what services are open. -** So, the attacker will need to query the ports or protocols they are -** interested in. Most or at least some of these queries will be negative -** and take the form of either an invalid response (TCP RSTs, ICMP -** unreachables) or no response (in which case the host is firewalled or -** filtered). We detect portscans from these negative queries. -** -** The primary goal of this portscan detection engine is to catch nmap and -** variant scanners. The engine tracks connection attempts on TCP, UDP, -** ICMP, and IP Protocols. If there is a valid response, the connection -** is marked as valid. If there is no response or a invalid response -** (TCP RST), then we track these attempts separately, so we know the -** number of invalid responses and the number of connection attempts that -** generated no response. These two values differentiate between a -** normal scan and a filtered scan. -** -** We detect four different scan types, and each scan type has its own -** negative query characteristics. This is how we determine what type -** of scan we are seeing. The different scans are: -** -** - Portscan -** - Decoy Portscan -** - Distributed Portscan -** - Portsweep -** -** Portscan: A portscan is a basic one host to one host scan where -** multiple ports are scanned on the destination host. We detect these -** scans by looking for a low number of hosts that contacted the -** destination host and a high number of unique ports and a high number -** of invalid responses or connections. -** -** Distributed Portscan: A distributed portscan occurs when many hosts -** connect to a single destination host and multiple ports are scanned -** on the destination host. We detect these scans by looking for a high -** number of hosts that contacted the destination host and a high number -** of unique ports with a high number of invalid responses or connections. -** -** Decoy Portscan: A decoy portscan is a variation on a distributed -** portscan, the difference being that a decoy portscan connects to a -** single port multiple times. This shows up in the unqiue port count that -** is tracked. There's still many hosts connecting to the destination host. -** -** Portsweep: A portsweep is a basic one host to many host scan where -** one to a few ports are scanned on each host. We detect these scans by -** looking at src hosts for a high number of contacted hosts and a low -** number of unique ports with a high number of invalid responses or -** connections. -** -** Each of these scans can also be detected as a filtered portscan, or a -** portscan where there wasn't invalid responses and the responses have -** been firewalled in some way. -** */ #include "ps_detect.h" #include "ps_inspect.h" diff --git a/src/packet_io/active.h b/src/packet_io/active.h index 7d552bded..b71710b56 100644 --- a/src/packet_io/active.h +++ b/src/packet_io/active.h @@ -17,19 +17,21 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// @file active.h -// @author Russ Combs +// active.h author Russ Combs #ifndef ACTIVE_H #define ACTIVE_H +// manages packet processing verdicts returned to the DAQ. action (what to +// do) is separate from status (whether we can actually do it or not). + #include "main/snort_types.h" #include "main/snort_config.h" +#include "main/snort.h" #include "protocols/packet.h" #include "protocols/packet_manager.h" -#include "main/snort.h" -#include "utils/stats.h" #include "packet_io/sfdaq.h" +#include "utils/stats.h" struct Packet; diff --git a/src/packet_io/dev_notes.txt b/src/packet_io/dev_notes.txt new file mode 100644 index 000000000..eacb66426 --- /dev/null +++ b/src/packet_io/dev_notes.txt @@ -0,0 +1,7 @@ +This unit is the interface for incoming and outgoing packets and manages the +DAQ. + +There is one DAQ instance per active source (interface, pcap, etc.). The +DAQ determines the required root decoder, instantiated upon thread +initialization, and which remains the same for all packets. + diff --git a/src/packet_io/intf.h b/src/packet_io/intf.h index 2fb2773a2..a57795e62 100644 --- a/src/packet_io/intf.h +++ b/src/packet_io/intf.h @@ -20,10 +20,6 @@ #ifndef INTF_H #define INTF_H -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - /* This macro helps to simplify the differences between Win32 and non-Win32 code when printing out the name of the interface */ #define PRINT_INTERFACE(i) (i ? i : "NULL") diff --git a/src/packet_io/sfdaq.cc b/src/packet_io/sfdaq.cc index 86ceeb1d5..92a68f396 100644 --- a/src/packet_io/sfdaq.cc +++ b/src/packet_io/sfdaq.cc @@ -68,8 +68,6 @@ static THREAD_LOCAL int daq_dlt = -1; static THREAD_LOCAL int s_error = DAQ_SUCCESS; static THREAD_LOCAL DAQ_Stats_t daq_stats, tot_stats; -namespace snort -{ static void DAQ_Accumulate(void); //-------------------------------------------------------------------- @@ -613,5 +611,4 @@ int DAQ_ModifyFlow(const void* h, uint32_t id) return -1; #endif } -} diff --git a/src/packet_io/sfdaq.h b/src/packet_io/sfdaq.h index 6386a0b89..603b50785 100644 --- a/src/packet_io/sfdaq.h +++ b/src/packet_io/sfdaq.h @@ -17,8 +17,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// @file sfdaq.h -// @author Russ Combs +// sfdaq.h author Russ Combs #ifndef SFDAQ_H #define SFDAQ_H @@ -37,8 +36,7 @@ extern "C" { #define PKT_TIMEOUT 1000 // ms, worst daq resolution is 1 sec struct SnortConfig; -namespace snort -{ + void DAQ_Load(const SnortConfig*); void DAQ_Unload(void); @@ -69,7 +67,7 @@ int DAQ_Start(void); int DAQ_WasStarted(void); int DAQ_Stop(void); -// TBD some stuff may be inlined once encapsulations are straight +// FIXIT-L some stuff may be inlined once encapsulations are straight // (but only where performance justifies exposing implementation!) int DAQ_Acquire(int max, DAQ_Analysis_Func_t, uint8_t* user); int DAQ_Inject(const DAQ_PktHdr_t*, int rev, const uint8_t* buf, uint32_t len); @@ -89,14 +87,11 @@ static inline uint16_t DAQ_GetAddressSpaceID(const DAQ_PktHdr_t* h) { return h->address_space_id; } - #endif // returns total stats if no daq else current stats // returns statically allocated stats - don't free const DAQ_Stats_t* DAQ_GetStats(void); -} -using namespace snort; -#endif // SFDAQ_H +#endif diff --git a/src/packet_io/trough.h b/src/packet_io/trough.h index 025d5dde2..963537561 100644 --- a/src/packet_io/trough.h +++ b/src/packet_io/trough.h @@ -20,11 +20,13 @@ #ifndef TROUGH_H #define TROUGH_H +// Trough provides access to sources (interface, file, etc.). + enum SourceType { - SOURCE_FILE_LIST, - SOURCE_LIST, - SOURCE_DIR + SOURCE_FILE_LIST, // a file containing a list of sources + SOURCE_LIST, // a list of sources (eg from cmd line) + SOURCE_DIR // a directory of sources; often used wiht filter }; void Trough_SetLoopCount(long int); diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt index ee73113f1..b278c4ed2 100644 --- a/src/parser/CMakeLists.txt +++ b/src/parser/CMakeLists.txt @@ -20,7 +20,6 @@ add_library (parser STATIC cmd_line.h config_file.cc config_file.h - keywords.h mstring.cc mstring.h vars.cc diff --git a/src/parser/Makefile.am b/src/parser/Makefile.am index 931e41334..3a10a1fa3 100644 --- a/src/parser/Makefile.am +++ b/src/parser/Makefile.am @@ -13,7 +13,6 @@ parse_stream.cc parse_stream.h \ parse_utils.cc parse_utils.h \ cmd_line.cc cmd_line.h \ config_file.cc config_file.h \ -keywords.h \ mstring.cc mstring.h \ vars.cc vars.h diff --git a/src/parser/config_file.cc b/src/parser/config_file.cc index 1b6321708..eed5d2a13 100644 --- a/src/parser/config_file.cc +++ b/src/parser/config_file.cc @@ -36,16 +36,15 @@ #include #include #include -#include "utils/dnet_header.h" #include "parser.h" #include "cmd_line.h" #include "mstring.h" -#include "keywords.h" #include "main/snort_types.h" #include "main/snort_debug.h" #include "main/snort.h" +#include "utils/dnet_header.h" #include "utils/util.h" #include "utils/strvec.h" #include "utils/snort_bounds.h" @@ -70,6 +69,17 @@ #define OUTPUT_U2 "unified2" #define OUTPUT_FAST "alert_fast" +#define CHECKSUM_MODE_OPT__ALL "all" +#define CHECKSUM_MODE_OPT__NONE "none" +#define CHECKSUM_MODE_OPT__IP "ip" +#define CHECKSUM_MODE_OPT__NO_IP "noip" +#define CHECKSUM_MODE_OPT__TCP "tcp" +#define CHECKSUM_MODE_OPT__NO_TCP "notcp" +#define CHECKSUM_MODE_OPT__UDP "udp" +#define CHECKSUM_MODE_OPT__NO_UDP "noudp" +#define CHECKSUM_MODE_OPT__ICMP "icmp" +#define CHECKSUM_MODE_OPT__NO_ICMP "noicmp" + static std::string lua_conf; static std::string snort_conf_dir; diff --git a/src/parser/dev_notes.txt b/src/parser/dev_notes.txt new file mode 100644 index 000000000..6e6cfa075 --- /dev/null +++ b/src/parser/dev_notes.txt @@ -0,0 +1,8 @@ +This unit support parsing of command line args, detection rules, IP addresses, +and config files. New Lua-based feratures are elsewhere. + +* parse_stream.cc uses state machines to parse IPS rules. + +* mstring is a set of parsing utilities that should not be used in new + code. + diff --git a/src/parser/keywords.h b/src/parser/keywords.h deleted file mode 100644 index 3bc085711..000000000 --- a/src/parser/keywords.h +++ /dev/null @@ -1,49 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2013-2013 Sourcefire, Inc. -// -// 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. -//-------------------------------------------------------------------------- - -#ifndef KEYWORDS_H -#define KEYWORDS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define MAX_RULE_COUNT (65535 * 2) - -#define RULE_PROTO_OPT__IP "ip" -#define RULE_PROTO_OPT__TCP "tcp" -#define RULE_PROTO_OPT__UDP "udp" -#define RULE_PROTO_OPT__ICMP "icmp" - -#define RULE_DIR_OPT__DIRECTIONAL "->" -#define RULE_DIR_OPT__BIDIRECTIONAL "<>" - -#define CHECKSUM_MODE_OPT__ALL "all" -#define CHECKSUM_MODE_OPT__NONE "none" -#define CHECKSUM_MODE_OPT__IP "ip" -#define CHECKSUM_MODE_OPT__NO_IP "noip" -#define CHECKSUM_MODE_OPT__TCP "tcp" -#define CHECKSUM_MODE_OPT__NO_TCP "notcp" -#define CHECKSUM_MODE_OPT__UDP "udp" -#define CHECKSUM_MODE_OPT__NO_UDP "noudp" -#define CHECKSUM_MODE_OPT__ICMP "icmp" -#define CHECKSUM_MODE_OPT__NO_ICMP "noicmp" - -#endif - diff --git a/src/parser/mstring.cc b/src/parser/mstring.cc index 87e2af4f2..315441eaa 100644 --- a/src/parser/mstring.cc +++ b/src/parser/mstring.cc @@ -18,27 +18,6 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/*************************************************************************** - * - * File: MSTRING.C - * - * Purpose: Provide a variety of string functions not included in libc. Makes - * up for the fact that the libstdc++ is hard to get reference - * material on and I don't want to write any more non-portable c++ - * code until I have solid references and libraries to use. - * - * History: - * - * Date: Author: Notes: - * ---------- ------- ---------------------------------------------- - * 08/19/98 MFR Initial coding begun - * 03/06/99 MFR Added Boyer-Moore pattern match routine, don't use - * mContainsSubstr() any more if you don't have to - * 12/31/99 JGW Added a full Boyer-Moore implementation to increase - * performance. Added a case insensitive version of mSearch - * 07/24/01 MFR Fixed Regex pattern matcher introduced by Fyodor - * - **************************************************************************/ #include "mstring.h" #ifdef HAVE_CONFIG_H diff --git a/src/parser/mstring.h b/src/parser/mstring.h index 59a93fc5a..3e1aff1be 100644 --- a/src/parser/mstring.h +++ b/src/parser/mstring.h @@ -21,15 +21,16 @@ #ifndef MSTRING_H #define MSTRING_H +// Provide a variety of string functions not included in libc. +// Deprecated - Do not use this in new code. + #include "main/snort_types.h" -/* D E F I N E S *******************************************************/ #define TOKS_BUF_SIZE 100 -/* P R O T O T Y P E S *************************************************/ SO_PUBLIC char** mSplit(const char*, const char*, const int, int*, const char); SO_PUBLIC void mSplitFree(char*** toks, int numtoks); SO_PUBLIC int mContainsSubstr(const char*, int, const char*, int); -#endif /* MSTRING_H */ +#endif diff --git a/src/parser/parse_conf.cc b/src/parser/parse_conf.cc index de6af1b67..42cf5dc33 100644 --- a/src/parser/parse_conf.cc +++ b/src/parser/parse_conf.cc @@ -65,7 +65,6 @@ #include "managers/action_manager.h" #include "actions/actions.h" #include "config_file.h" -#include "keywords.h" #include "vars.h" #include "target_based/snort_protocols.h" @@ -266,7 +265,7 @@ ListHead* get_rule_list(SnortConfig* sc, const char* s) return p ? p->RuleList : nullptr; } -// FIXIT-L find this a better home +// FIXIT-L move to snort config void AddRuleState(SnortConfig* sc, const RuleState& rs) { if (sc == NULL) diff --git a/src/parser/parse_conf.h b/src/parser/parse_conf.h index 0598c688a..c27a567bd 100644 --- a/src/parser/parse_conf.h +++ b/src/parser/parse_conf.h @@ -20,7 +20,6 @@ #ifndef PARSE_CONF_H #define PARSE_CONF_H -#include #include "detection/rules.h" void parse_conf_init(); diff --git a/src/parser/parse_ip.h b/src/parser/parse_ip.h index 9536714a8..c88b2bf08 100644 --- a/src/parser/parse_ip.h +++ b/src/parser/parse_ip.h @@ -21,7 +21,7 @@ #define PARSE_IP_H #include -#include "snort_types.h" +#include "main/snort_types.h" struct sfip_var_t; diff --git a/src/parser/parse_rule.cc b/src/parser/parse_rule.cc index afbd46a08..24de6b546 100644 --- a/src/parser/parse_rule.cc +++ b/src/parser/parse_rule.cc @@ -73,30 +73,14 @@ #include "managers/ips_manager.h" #include "managers/so_manager.h" #include "config_file.h" -#include "keywords.h" #include "target_based/snort_protocols.h" +#define RULE_DIR_OPT__DIRECTIONAL "->" +#define RULE_DIR_OPT__BIDIRECTIONAL "<>" + #define SRC 0 #define DST 1 -/* Tracking the port_list_t structure for printing and debugging at - * this point...temporarily... */ -struct port_entry_t -{ - int rule_type; - int proto; - unsigned int gid; - unsigned int sid; - bool has_fast_pattern; -}; - -struct port_list_t -{ - int pl_max; - int pl_cnt; - port_entry_t pl_array[MAX_RULE_COUNT]; -}; - /* rule counts for port lists */ struct rule_count_t { @@ -121,50 +105,8 @@ static rule_count_t icmpCnt; static rule_count_t ipCnt; static rule_count_t svcCnt; // dummy for now -static port_list_t port_list; - static bool s_ignore = false; // for skipping drop rules when not inline, etc. -static int port_list_add_entry(port_list_t* plist, port_entry_t* pentry) -{ - if ( !plist ) - { - return -1; - } - - if ( plist->pl_cnt >= plist->pl_max ) - { - return -1; - } - - SafeMemcpy(&plist->pl_array[plist->pl_cnt], pentry, sizeof(port_entry_t), - &plist->pl_array[plist->pl_cnt], - (char*)(&plist->pl_array[plist->pl_cnt]) + sizeof(port_entry_t)); - plist->pl_cnt++; - - return 0; -} - -#if 0 -static void port_list_print(port_list_t* plist) -{ - int i; - for (i=0; ipl_cnt; i++) - { - LogMessage("rule %d { ", i); - LogMessage(" gid %u sid %u",plist->pl_array[i].gid,plist->pl_array[i].sid); - LogMessage(" fp %d", plist->pl_array[i].has_fast_pattern); - LogMessage(" }\n"); - } -} - -#endif - -static void port_list_free(port_list_t* plist) -{ - plist->pl_cnt = 0; -} - /* * Finish adding the rule to the port tables * @@ -177,11 +119,10 @@ static void port_list_free(port_list_t* plist) * a)do this for src and dst port * b)add the rule index/id to the portobject(s) * c)if the rule is bidir add the rule and port-object to both src and dst tables - * */ static int FinishPortListRule( RulePortTables* port_tables, RuleTreeNode* rtn, OptTreeNode* otn, - int proto, port_entry_t* pe, FastPatternConfig* fp) + int proto, bool has_fp, FastPatternConfig* fp) { int large_port_group = 0; int src_cnt = 0; @@ -250,7 +191,7 @@ static int FinishPortListRule( rim_index = otn->ruleIndex; /* Add up the nfp rules */ - if ( !pe->has_fast_pattern ) + if ( has_fp ) prc->nfp++; /* If not an any-any rule test for port bleedover, if we are using a @@ -1064,8 +1005,7 @@ static void SetupRTNFuncList(RuleTreeNode* rtn) * ***************************************************************************/ static RuleTreeNode* ProcessHeadNode( - SnortConfig* sc, RuleTreeNode* test_node, - ListHead* list) + SnortConfig* sc, RuleTreeNode* test_node, ListHead* list) { RuleTreeNode* rtn = findHeadNode( sc, test_node, get_ips_policy()->policy_id); @@ -1255,10 +1195,6 @@ void parse_rule_init() otn_count = 0; rule_proto = 0; - port_list_free(&port_list); - memset(&port_list, 0, sizeof(port_list)); - port_list.pl_max = MAX_RULE_COUNT; - memset(&ipCnt, 0, sizeof(ipCnt)); memset(&icmpCnt, 0, sizeof(icmpCnt)); memset(&tcpCnt, 0, sizeof(tcpCnt)); @@ -1267,9 +1203,7 @@ void parse_rule_init() } void parse_rule_term() -{ - port_list_free(&port_list); -} +{ } void parse_rule_print() { @@ -1318,7 +1252,6 @@ void parse_rule_print() LogMessage("%8s%8u%8u%8u%8u\n", "total", tcp, udp, icmp, ip); //print_rule_index_map( ruleIndexMap ); - //port_list_print( &port_list ); } void parse_rule_type(SnortConfig* sc, const char* s, RuleTreeNode& rtn) @@ -1560,19 +1493,6 @@ const char* parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* ot ValidateFastPattern(otn); OtnLookupAdd(sc->otn_map, otn); - port_entry_t pe; - memset(&pe, 0, sizeof(pe)); - - /* Get rule option info */ - pe.gid = otn->sigInfo.generator; - pe.sid = otn->sigInfo.id; - - pe.has_fast_pattern = has_fp; - pe.proto = rtn.proto; - pe.rule_type = rtn.type; - - port_list_add_entry(&port_list, &pe); - if ( is_service_protocol(otn->proto) ) add_service_to_otn(sc, otn, get_protocol_name(otn->proto)); @@ -1582,7 +1502,8 @@ const char* parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* ot * * After otn processing we can finalize port object processing for this rule */ - if (FinishPortListRule(sc->port_tables, new_rtn, otn, rtn.proto, &pe, sc->fast_pattern_config)) + if ( FinishPortListRule( + sc->port_tables, new_rtn, otn, rtn.proto, has_fp, sc->fast_pattern_config) ) ParseError("Failed to finish a port list rule."); return nullptr; diff --git a/src/parser/parse_rule.h b/src/parser/parse_rule.h index 48c479cc9..5ee7de661 100644 --- a/src/parser/parse_rule.h +++ b/src/parser/parse_rule.h @@ -30,14 +30,10 @@ void parse_rule_init(); void parse_rule_term(); void parse_rule_print(); -void parse_rule(struct SnortConfig*, const char* args, RuleType, ListHead*); - void parse_rule_type(SnortConfig*, const char*, RuleTreeNode&); void parse_rule_proto(SnortConfig*, const char*, RuleTreeNode&); -void parse_rule_nets( - SnortConfig*, const char*, bool src, RuleTreeNode&); -void parse_rule_ports( - SnortConfig*, const char*, bool src, RuleTreeNode&); +void parse_rule_nets(SnortConfig*, const char*, bool src, RuleTreeNode&); +void parse_rule_ports(SnortConfig*, const char*, bool src, RuleTreeNode&); void parse_rule_dir(SnortConfig*, const char*, RuleTreeNode&); void parse_rule_opt_begin(SnortConfig*, const char* key); void parse_rule_opt_set( diff --git a/src/parser/parser.cc b/src/parser/parser.cc index 60c55daeb..176a8bc00 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -43,7 +43,6 @@ #include "cmd_line.h" #include "mstring.h" #include "config_file.h" -#include "keywords.h" #include "parse_conf.h" #include "parse_rule.h" #include "parse_stream.h" @@ -86,7 +85,7 @@ static unsigned parse_errors = 0; static unsigned parse_warnings = 0; -rule_index_map_t* ruleIndexMap = NULL; /* rule index -> sid:gid map */ +struct rule_index_map_t* ruleIndexMap = nullptr; /* rule index -> sid:gid map */ static std::string s_aux_rules; @@ -118,12 +117,15 @@ static void InitParser(void) { parse_rule_init(); - if (ruleIndexMap != NULL) - RuleIndexMapFree(&ruleIndexMap); + if (ruleIndexMap ) + { + RuleIndexMapFree(ruleIndexMap); + ruleIndexMap = nullptr; + } - ruleIndexMap = RuleIndexMapCreate(MAX_RULE_COUNT); + ruleIndexMap = RuleIndexMapCreate(); - if (ruleIndexMap == NULL) + if ( !ruleIndexMap ) { ParseAbort("failed to create rule index map."); } @@ -647,10 +649,10 @@ void ParserCleanup(void) { parse_rule_term(); - if (ruleIndexMap != NULL) + if (ruleIndexMap ) { - RuleIndexMapFree(&ruleIndexMap); - ruleIndexMap = NULL; + RuleIndexMapFree(ruleIndexMap); + ruleIndexMap = nullptr; } } @@ -1035,11 +1037,6 @@ int addRtnToOtn(OptTreeNode* otn, RuleTreeNode* rtn) void rule_index_map_print_index(int index, char* buf, int bufsize) { - if ( index < ruleIndexMap->num_rules ) - { - SnortSnprintfAppend(buf, bufsize, "%u:%u ", - ruleIndexMap->map[index].gid, - ruleIndexMap->map[index].sid); - } + rule_index_map_print_index(ruleIndexMap, index, buf, bufsize); } diff --git a/src/parser/parser.h b/src/parser/parser.h index 69dad6f09..7942e0a57 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -26,10 +26,10 @@ #include -#include "rules.h" -#include "treenodes.h" -#include "main/policy.h" +#include "detection/rules.h" #include "detection/sfrim.h" +#include "detection/treenodes.h" +#include "main/policy.h" unsigned get_parse_errors(); unsigned get_parse_warnings(); @@ -86,10 +86,6 @@ RuleTreeNode* deleteRtnFromOtn(struct OptTreeNode*); RuleTreeNode* deleteRtnFromOtn(struct OptTreeNode*, PolicyId); /*Get RTN for a given OTN and policyId. - * - * @param otn pointer to structure OptTreeNode. - * @param policyId policy id - * * @return pointer to deleted RTN, NULL otherwise. */ static inline RuleTreeNode* getRtnFromOtn( diff --git a/src/parser/vars.cc b/src/parser/vars.cc index 19741e754..710e4ada6 100644 --- a/src/parser/vars.cc +++ b/src/parser/vars.cc @@ -66,7 +66,6 @@ #include "file_api/libs/file_config.h" #include "framework/ips_option.h" #include "config_file.h" -#include "keywords.h" //------------------------------------------------------------------------- // var node stuff diff --git a/src/piglet/dev_notes.txt b/src/piglet/dev_notes.txt new file mode 100644 index 000000000..6136b8204 --- /dev/null +++ b/src/piglet/dev_notes.txt @@ -0,0 +1,28 @@ +This directory contains the framework used to instantiate, run and collect +the results from test harness scripts. + +The piglet test harness provides a Lua scripted interface to the Snort +plugins. The tests written by the harness occupy a place somewhere between +unit tests and integration tests in scope. + +When Snort is started in piglet mode, any Lua scripts located in +"--script-path" are loaded and checked for table named "plugin". If the +plugin table's "type" field is set to "piglet", the script is considered to +be a piglet plugin and the Lua chunk is added to Piglet::Manager. + +When the Piglet::Main::piglet() entry point is called, Piglet::Runner +iterates through the test harness chunks and uses Piglet::Manager to +instantiate the appropriate Piglet for each plugin type. + +Each test harness chunk contains a table named "piglet". This table +contains fields "target" and "type" which indicate the plugin type and name +of the plugin to be instantiated and tested. The table should also contain +an entry point function called "test". + +The Piglets all derive from Piget::BasePlugin and contain code to expose +the target plugin methods to the Lua chunk. There is a Piglet subclass for +each plugin type. (The enum of plugin types is located in +framework/base_api.h) + +Piglet::Runner than calls the entry point method referenced by piglet.test +in the Lua script, and then returns the results. diff --git a/src/piglet/piglet.h b/src/piglet/piglet.h index 74456b6a6..302d7dc0a 100644 --- a/src/piglet/piglet.h +++ b/src/piglet/piglet.h @@ -20,6 +20,8 @@ #ifndef PIGLET_H #define PIGLET_H +// Front end for the piglet test harness. + namespace Piglet { // FIXIT-L: May not need to wrap these functions in a class diff --git a/src/piglet/piglet_api.h b/src/piglet/piglet_api.h index d15268f9b..00ee74c33 100644 --- a/src/piglet/piglet_api.h +++ b/src/piglet/piglet_api.h @@ -20,6 +20,8 @@ #ifndef PIGLET_API_H #define PIGLET_API_H +// Piglet plugin API + #include #include "framework/base_api.h" diff --git a/src/piglet/piglet_manager.h b/src/piglet/piglet_manager.h index de0715fc4..0f7fc2420 100644 --- a/src/piglet/piglet_manager.h +++ b/src/piglet/piglet_manager.h @@ -20,11 +20,12 @@ #ifndef PIGLET_MANAGER_H #define PIGLET_MANAGER_H +// Factory for instantiating piglet plugins + #include #include #include "helpers/lua.h" - #include "piglet_api.h" #include "piglet_utils.h" diff --git a/src/piglet/piglet_runner.h b/src/piglet/piglet_runner.h index 0a0ebfe5a..6923874dc 100644 --- a/src/piglet/piglet_runner.h +++ b/src/piglet/piglet_runner.h @@ -20,6 +20,8 @@ #ifndef PIGLET_RUNNER_H #define PIGLET_RUNNER_H +// Test runner + #include "piglet_utils.h" namespace Piglet diff --git a/src/piglet/piglet_utils.h b/src/piglet/piglet_utils.h index d20d9021c..f962fc348 100644 --- a/src/piglet/piglet_utils.h +++ b/src/piglet/piglet_utils.h @@ -20,6 +20,8 @@ #ifndef PIGLET_UTILS_H #define PIGLET_UTILS_H +// Miscellaneous data objects used for the piglet test harness + #include #include #include diff --git a/src/piglet_plugins/dev_notes.txt b/src/piglet_plugins/dev_notes.txt new file mode 100644 index 000000000..0aa1e79a8 --- /dev/null +++ b/src/piglet_plugins/dev_notes.txt @@ -0,0 +1,7 @@ +This directory contains subclasses of Piglet::BasePlugin that correspond to +each Snort plugin type. Each pp_\*.cc source file is a Snort plugin proper. + +piglet_plugins_common contains utilities for working with the Lua C API and +Lua interfaces for some useful Snort data structures (Packet, DecodeData). +There is also an interface called RawData. This is essentially a wrapper +around a vector. diff --git a/src/piglet_plugins/piglet_plugin_common.h b/src/piglet_plugins/piglet_plugin_common.h index df94100ec..618403970 100644 --- a/src/piglet_plugins/piglet_plugin_common.h +++ b/src/piglet_plugins/piglet_plugin_common.h @@ -20,12 +20,15 @@ #ifndef PIGLET_PLUGIN_COMMON_H #define PIGLET_PLUGIN_COMMON_H -#include -#include +// Utils for working with the Lua C API and +// interfaces for exposing some common structs to Lua. #include #include +#include +#include + #include "events/event.h" #include "detection/signature.h" #include "framework/codec.h" diff --git a/src/ports/readme.txt b/src/ports/dev_notes.txt similarity index 82% rename from src/ports/readme.txt rename to src/ports/dev_notes.txt index 49de3b9bb..0e68fd05f 100644 --- a/src/ports/readme.txt +++ b/src/ports/dev_notes.txt @@ -1,5 +1,21 @@ -These comments are from the original sfportobject.c from which ports/ is -derived. +Port groups actually refer to a groups of rules based on ports (and +protocol and direction) only. The idea is that when we get a packet, say +going to tcp port 80, we can select an MPSE instance for fast pattern +matching. We then need to fully evaluate only rules with matching fast +patterns. (Of course, any tcp destination port 80 rules w/o fast patterns +must be evaluated as well, but the hope is there are very few if any of +those rules.) Because there are many possible ports with related traffic, +port groups are typically based on a collection of related ports, eg 80 and +8080 for HTTP. + +When services came along, port groups were used for rules grouped by +service as well as by ports. (Note that ports and service considerations +are not intermixed.) Thus we could combine the fast patterns of all HTTP +traffic to the server into one "port group" and select that instead of +selecting an MPSE by port. + +The following comments are from the original sfportobject.c from which +ports/ is derived. author: marc norton date: 11/05/2005 @@ -23,14 +39,14 @@ cause all rules in all port-rule groups to be merged into one set unless we apply a more complex logic than simply merging rule-port groups with common ports. This is the problem addressed by the sfportobject module. -== Port list examples of acceptable usage: +*Port list examples of acceptable usage* * var has been overloaded, if it includes _port we add as a port-object also. -var http_ports 80 -var http_range_ports 80:81 -var http_list_ports [80,8080,8138] + var http_ports 80 + var http_range_ports 80:81 + var http_list_ports [80,8080,8138] * portvar has been added to indicate portvariables, this form does not require _port @@ -63,18 +79,18 @@ for these as that would then generate multiple large state machines for the multi-pattern matching phase of the detection engine which in turn could use a lot of memory. -Turns out that one scheme, the one used herein, provides some blending -of rule groups to minimize memory, and tries to minimize large group sizes -to keep performance more optimal - although this is at the expense of memory. +Turns out that one scheme, the one used herein, provides some blending of +rule groups to minimize memory, and tries to minimize large group sizes to +keep performance more optimal - although this is at the expense of memory. -== Port variables +*Port Variables* * Var has been overloaded. If it's name includes _port as part of the var name it is added to the PortVarTable. * PortVar has been added. These are always added to the PortVarTable. -== Loading Port lists and rules +*Loading Port Lists and Rules* * PortTables - we support src and dst tables for tcp/udp/icmp/ip rules. @@ -92,7 +108,7 @@ the rules are done loading we should have a set of port-objects with port-lists that differ by at least one port. The next step handles the cases where we have multiple port-objects with at least one common port. -== Merging Ports and Rules +*Merging Ports and Rules* We maintain for each port a list of port objects and their rules that apply to it. This allows us to view combining the rules associated with each port @@ -109,7 +125,7 @@ port presents rules in one of four catagories: 4. multiple port objects with large rule sets, and zero or more port objects each with a small set of rules associated with it. -== We process these four categories as follows: +We process these four categories as follows 1. a single port object (large or small) do nothing, each port referencing this port object is complete. @@ -140,7 +156,7 @@ port presents rules in one of four catagories: added to port groups. Therefore generous statistics are printed after the rules and port objects are compiled into their final groupings. -== Procedure for using PortLists +*Procedure for using PortLists* 1. Process Var's as PortVar's and standard Var's (for now). This allows existing snort features to work, with the Var's. Add in the PortVar @@ -158,7 +174,7 @@ c. Test if this Port object exists already, * If so, add the sid to it. * If not add it .... -== Notes +*Notes* All any-any port rules are managed separately, and added in to the final rules lists of each port group after this analysis. Rules defined with @@ -167,7 +183,7 @@ port-rule groupings. This should help prevent some cross fertilization of rule groups with rules that are unneccessary, this causes rule group sizes to bloat and performance to slow. -== Hierarchy: +*Hierarchy* PortTable -> PortObject's diff --git a/src/ports/port_group.h b/src/ports/port_group.h index 856a40052..936cf94b6 100644 --- a/src/ports/port_group.h +++ b/src/ports/port_group.h @@ -18,13 +18,19 @@ //-------------------------------------------------------------------------- // port_group.h derived from pcrm.h by -/* -** Marc Norton -** Dan Roelker -*/ +// +// Marc Norton +// Dan Roelker + #ifndef PortGroup_H #define PortGroup_H +// PortGroup contains a set of fast patterns in the form of an MPSE and a +// set of non-fast-pattern (nfp) rules. when a PortGroup is selected, the +// MPSE will run fp rules if there is a match on the associated fast +// patterns. it will always run nfp rules since there is no way to filter +// them out. + enum PmType { PM_TYPE_PKT, diff --git a/src/ports/port_item.h b/src/ports/port_item.h index d60b0c8e4..5c3ed914b 100644 --- a/src/ports/port_item.h +++ b/src/ports/port_item.h @@ -30,7 +30,10 @@ //------------------------------------------------------------------------- // Port Object Item supports -// port, lowport:highport (inclusive), portlist +// port, lowport:highport (inclusive) +// +// so it indicates a single port, a consecutive range of ports, or the any +// port. can also be negated. //------------------------------------------------------------------------- struct PortObjectItem diff --git a/src/ports/port_object.h b/src/ports/port_object.h index c352f8f42..d634ea10b 100644 --- a/src/ports/port_object.h +++ b/src/ports/port_object.h @@ -22,27 +22,27 @@ #ifndef PORT_OBJECT_H #define PORT_OBJECT_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "framework/bits.h" #include "utils/sflsq.h" //------------------------------------------------------------------------- // PortObject supports a set of PortObjectItems +// associates rules with a PortGroup. //------------------------------------------------------------------------- struct PortObjectItem; struct PortObject { + // FIXIT convert char* to C++ string char* name; /* user name - always use strdup or malloc for this*/ int id; /* internal tracking - compiling sets this value */ SF_LIST* item_list; /* list of port and port-range items */ SF_LIST* rule_list; /* list of rules */ + // FIXIT-L convert from void* to PortGroup* and + // call dtor instead of needing free func void* data; /* user data, PortGroup based on rule_list - only used by any-any ports */ void (* data_free)(void*); diff --git a/src/ports/port_object2.h b/src/ports/port_object2.h index 8137cf7a5..bf6b4e95f 100644 --- a/src/ports/port_object2.h +++ b/src/ports/port_object2.h @@ -22,10 +22,6 @@ #ifndef PORT_OBJECT2_H #define PORT_OBJECT2_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "framework/bits.h" #include "hash/sfghash.h" #include "utils/sflsq.h" @@ -38,6 +34,7 @@ struct PortObject; struct PortObject2 { + // FIXIT convert char* to C++ string char* name; /* user name - always use strdup or malloc for this*/ int id; /* internal tracking - compiling sets this value */ @@ -47,6 +44,8 @@ struct PortObject2 int port_cnt; /* count of ports using this object */ PortBitSet* port_list; /* for collecting ports that use this object */ + // FIXIT-L convert from void* to PortGroup* and + // call dtor instead of needing free func void* data; /* user data, PortGroup based on rule_hash */ void (* data_free)(void*); }; diff --git a/src/ports/port_table.cc b/src/ports/port_table.cc index f1884dedb..e4716d3dd 100644 --- a/src/ports/port_table.cc +++ b/src/ports/port_table.cc @@ -51,14 +51,12 @@ // PortTable - private - plx //------------------------------------------------------------------------- -/* - * plx_t is a variable sized array of pointers - */ -typedef struct +// plx_t is a variable sized array of pointers +struct plx_t { int n; void** p; -}plx_t; +}; static plx_t* plx_new(void* pv_array[], int n) { diff --git a/src/ports/port_table.h b/src/ports/port_table.h index d7a8dcb3d..87ff901d6 100644 --- a/src/ports/port_table.h +++ b/src/ports/port_table.h @@ -22,10 +22,6 @@ #ifndef PORT_TABLE_H #define PORT_TABLE_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "hash/sfghash.h" #include "utils/sflsq.h" #include "ports/port_item.h" diff --git a/src/ports/port_var_table.h b/src/ports/port_var_table.h index e1692b630..170a06ef5 100644 --- a/src/ports/port_var_table.h +++ b/src/ports/port_var_table.h @@ -22,10 +22,6 @@ #ifndef PORT_VAR_TABLE_H #define PORT_VAR_TABLE_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "hash/sfghash.h" #include "ports/port_object.h" #include "ports/port_table.h" diff --git a/src/protocols/dev_notes.txt b/src/protocols/dev_notes.txt new file mode 100644 index 000000000..c59a25eb9 --- /dev/null +++ b/src/protocols/dev_notes.txt @@ -0,0 +1,18 @@ +Headers for the various protocols processed by Snort. Use these headers +instead of directly accessing system headers. Advantages: + +* the vagaries of required system includes are minimized and localized here + +* these headers are OO in nature and much more user friendly than the often + awkard system defined structs + +Packet, used throughout Snort, is defined here as well. Packet represents +a unit of work, essentially a buffer associated with a flow. It does not +necessarily represent a wire packet. + +* PktType indicates the general nature of the packet. This may be the + transport protocol for wire packets, FILE for file data, or PDU for a + reassembled buffer. + +* proto_bits indicates the protocols present in the packet. + diff --git a/src/protocols/eth.h b/src/protocols/eth.h index 707e3c38b..c97b99f95 100644 --- a/src/protocols/eth.h +++ b/src/protocols/eth.h @@ -23,7 +23,7 @@ #include #define ETHERNET_HEADER_LEN 14 -#define ETHERNET_MTU 1500 +#define ETHERNET_MTU 1500 namespace eth { diff --git a/src/protocols/ip.h b/src/protocols/ip.h index 9b202ab3b..4f1f43fc1 100644 --- a/src/protocols/ip.h +++ b/src/protocols/ip.h @@ -20,16 +20,24 @@ #ifndef PROTOCOLS_IP_H #define PROTOCOLS_IP_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef WIN32 + #include #include #include -#else /* !WIN32 */ + +#else + #include #ifndef IFNAMSIZ #define IFNAMESIZ MAX_ADAPTER_NAME -#endif /* !IFNAMSIZ */ -#endif /* !WIN32 */ +#endif + +#endif #include diff --git a/src/protocols/ipv4.h b/src/protocols/ipv4.h index 5d28dd84e..e68e5fa46 100644 --- a/src/protocols/ipv4.h +++ b/src/protocols/ipv4.h @@ -20,19 +20,27 @@ #ifndef PROTOCOLS_IPV4_H #define PROTOCOLS_IPV4_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #ifndef WIN32 + #include #include #include -#else /* !WIN32 */ + +#else + #include #ifndef IFNAMSIZ #define IFNAMESIZ MAX_ADAPTER_NAME -#endif /* !IFNAMSIZ */ -#endif /* !WIN32 */ +#endif + +#endif #include "protocols/protocol_ids.h" // include ipv4 protocol numbers diff --git a/src/protocols/ipv6.h b/src/protocols/ipv6.h index 0b02f84dc..0c75bdb29 100644 --- a/src/protocols/ipv6.h +++ b/src/protocols/ipv6.h @@ -20,21 +20,29 @@ #ifndef PROTOCOLS_IPV6_H #define PROTOCOLS_IPV6_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include "sfip/sfip_t.h" #include "protocols/protocol_ids.h" #ifndef WIN32 + #include #include #include -#else /* !WIN32 */ + +#else + #include #ifndef IFNAMSIZ #define IFNAMESIZ MAX_ADAPTER_NAME -#endif /* !IFNAMSIZ */ -#endif /* !WIN32 */ +#endif + +#endif namespace ip { diff --git a/src/protocols/linux_sll.h b/src/protocols/linux_sll.h index 0663d616e..cfe4c4447 100644 --- a/src/protocols/linux_sll.h +++ b/src/protocols/linux_sll.h @@ -29,14 +29,14 @@ namespace linux_sll const uint8_t SLL_HDR_LEN = 16; const uint8_t SLL_ADDRLEN = 8; -typedef struct _SLLHdr +struct SLLHdr { uint16_t sll_pkttype; /* packet type */ uint16_t sll_hatype; /* link-layer address type */ uint16_t sll_halen; /* link-layer address length */ uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ uint16_t sll_protocol; /* protocol */ -} SLLHdr; +}; /* * ssl_pkttype values. diff --git a/src/protocols/packet.h b/src/protocols/packet.h index a019acea3..87c21d813 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -20,8 +20,6 @@ #ifndef PROTOCOLS_PACKET_H #define PROTOCOLS_PACKET_H -/* I N C L U D E S **********************************************************/ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -30,14 +28,18 @@ #include #ifndef WIN32 + #include #include #include + #else + #include #ifndef IFNAMSIZ #define IFNAMESIZ MAX_ADAPTER_NAME #endif + #endif extern "C" { @@ -49,8 +51,6 @@ extern "C" { #include "framework/decode_data.h" #include "protocols/layer.h" -/* D E F I N E S ************************************************************/ - /* packet status flags */ #define PKT_REBUILT_FRAG 0x00000001 /* is a rebuilt fragment */ #define PKT_REBUILT_STREAM 0x00000002 /* is a rebuilt stream */ @@ -296,15 +296,15 @@ static inline uint32_t EXTRACT_32BITS(const uint8_t* p) memmove(&tmp, p, sizeof(uint32_t)); return ntohl(tmp); } - -#endif /* __GNUC__ */ +#endif #else /* allows unaligned ntohl parameter - dies w/SIGBUS on SPARCs */ static inline uint32_t EXTRACT_32BITS(const uint8_t* p) { return ntohl(*(uint32_t*)p); } -#endif /* WORDS_MUSTALIGN */ + +#endif #endif diff --git a/src/protocols/packet_manager.cc b/src/protocols/packet_manager.cc index 0c75980c7..68c6e01bf 100644 --- a/src/protocols/packet_manager.cc +++ b/src/protocols/packet_manager.cc @@ -17,6 +17,8 @@ //-------------------------------------------------------------------------- // packet_manager.cc author Josh Rosenbaum +#include "protocols/packet_manager.h" + #include #include #include @@ -26,7 +28,6 @@ #include "framework/codec.h" #include "managers/codec_manager.h" -#include "protocols/packet_manager.h" #include "main/snort_config.h" #include "main/thread.h" #include "log/messages.h" diff --git a/src/protocols/packet_manager.h b/src/protocols/packet_manager.h index f5f0505f4..81210ef2f 100644 --- a/src/protocols/packet_manager.h +++ b/src/protocols/packet_manager.h @@ -20,16 +20,16 @@ #ifndef PROTOCOLS_PACKET_MANAGER_H #define PROTOCOLS_PACKET_MANAGER_H +// PacketManager provides decode and encode services by leveraging Codecs. + #include #include -// FIXIT-L update this includes #include "main/snort_types.h" -#include "framework/codec.h" #include "protocols/packet.h" // FIXIT-L remove #include "framework/counts.h" +#include "framework/codec.h" #include "managers/codec_manager.h" -#include "main/thread.h" struct _daq_pkthdr; struct TextLog; @@ -168,5 +168,6 @@ private: static std::array g_stats; static const std::array stat_names; }; + #endif diff --git a/src/protocols/protocol_ids.h b/src/protocols/protocol_ids.h index acff433b5..b9791ef52 100644 --- a/src/protocols/protocol_ids.h +++ b/src/protocols/protocol_ids.h @@ -22,9 +22,9 @@ /***************************************************************** ***** NOTE: Protocols are only included in this file when **** - ***** their IDs are needed throughout multipled **** - ***** files. If a protocol ID is only need in one **** - ***** file, define that number as a **** + ***** their IDs are needed throughout multiple **** + ***** files. If a protocol ID is only needed in **** + ***** one file, define that number as a **** ***** static const uint16_t ID_NAME = ZZZZ **** ***** in the specific file. **** ****************************************************************/ diff --git a/src/protocols/ssl.h b/src/protocols/ssl.h index 643a41adf..9007237b0 100644 --- a/src/protocols/ssl.h +++ b/src/protocols/ssl.h @@ -27,6 +27,10 @@ #ifndef SSL_H #define SSL_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include @@ -138,52 +142,52 @@ #pragma pack(1) #endif -typedef struct _SSL_record +struct SSL_record_t { uint8_t type; uint8_t major; uint8_t minor; uint16_t length; -} SSL_record_t; +}; #define SSL_REC_PAYLOAD_OFFSET (sizeof(uint8_t) * 5) -typedef struct _SSL_heartbeat +struct SSL_heartbeat { uint8_t type; uint16_t length; -} SSL_heartbeat; +}; -typedef struct _SSL_handshake +struct SSL_handshake_t { uint8_t type; uint8_t length[3]; -} SSL_handshake_t; +}; -typedef struct _SSL_handshake_hello +struct SSL_handshake_hello_t { uint8_t type; uint8_t length[3]; uint8_t major; uint8_t minor; -} SSL_handshake_hello_t; +}; // http://www.mozilla.org/projects/security/pki/nss/ssl/draft02.html -typedef struct _SSLv2_record +struct SSLv2_record_t { uint16_t length; uint8_t type; -} SSLv2_record_t; +}; -typedef struct _SSLv2_chello +struct SSLv2_chello_t { uint16_t length; uint8_t type; uint8_t major; uint8_t minor; -} SSLv2_chello_t; +}; -typedef struct _SSLv2_shello +struct SSLv2_shello_t { uint16_t length; uint8_t type; @@ -191,7 +195,7 @@ typedef struct _SSLv2_shello uint8_t certtype; uint8_t major; uint8_t minor; -} SSLv2_shello_t; +}; #define SSL_V2_MIN_LEN 5 diff --git a/src/protocols/tcp.h b/src/protocols/tcp.h index 750d1d082..ef38ae7fc 100644 --- a/src/protocols/tcp.h +++ b/src/protocols/tcp.h @@ -62,7 +62,7 @@ namespace tcp { -constexpr uint8_t TCP_MIN_HEADER_LEN = 20; // this is actually the minimal TCP header lenght +constexpr uint8_t TCP_MIN_HEADER_LEN = 20; // this is actually the minimal TCP header length constexpr int OPT_TRUNC = -1; constexpr int OPT_BADLEN = -2; @@ -167,5 +167,5 @@ struct TCPHdr }; } // namespace tcp -#endif /* TCP_H */ +#endif diff --git a/src/protocols/tcp_options.h b/src/protocols/tcp_options.h index 18688cbf1..96cdf371c 100644 --- a/src/protocols/tcp_options.h +++ b/src/protocols/tcp_options.h @@ -178,5 +178,5 @@ private: }; } // namespace tcp -#endif /* PROTOCOLS_TCP_OPTIONS_H */ +#endif diff --git a/src/search_engines/ac_banded.cc b/src/search_engines/ac_banded.cc index 04045e187..912efab0c 100644 --- a/src/search_engines/ac_banded.cc +++ b/src/search_engines/ac_banded.cc @@ -63,17 +63,17 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return acsmCompile2(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { return acsmSearchSparseDFA_Banded( - obj, (unsigned char*)T, n, action, data, current_state); + obj, (unsigned char*)T, n, match, data, current_state); } int print_info() override diff --git a/src/search_engines/ac_bnfa.cc b/src/search_engines/ac_bnfa.cc index e229f5307..20401bcf7 100644 --- a/src/search_engines/ac_bnfa.cc +++ b/src/search_engines/ac_bnfa.cc @@ -77,19 +77,18 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return bnfaCompile(sc, obj, build_tree, neg_list); } int _search( - const uint8_t* T, int n, mpse_action_f action, + const uint8_t* T, int n, MpseMatch match, void* data, int* current_state) override { /* return is actually the state */ return _bnfa_search_csparse_nfa( - obj, T, n, (bnfa_match_f)action, - data, 0 /* start-state */, current_state); + obj, T, n, match, data, 0 /* start-state */, current_state); } int print_info() override diff --git a/src/search_engines/ac_bnfa_q.cc b/src/search_engines/ac_bnfa_q.cc index a4f9f908b..823266da1 100644 --- a/src/search_engines/ac_bnfa_q.cc +++ b/src/search_engines/ac_bnfa_q.cc @@ -79,18 +79,18 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return bnfaCompile(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { /* return is actually the state */ return _bnfa_search_csparse_nfa_q( - obj, (unsigned char*)T, n, (bnfa_match_f)action, + obj, (unsigned char*)T, n, match, data, 0 /* start-state */, current_state); } diff --git a/src/search_engines/ac_full.cc b/src/search_engines/ac_full.cc index 4dc67150e..858a9e28f 100644 --- a/src/search_engines/ac_full.cc +++ b/src/search_engines/ac_full.cc @@ -69,25 +69,25 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return acsmCompile2(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { return acsmSearchSparseDFA_Full( - obj, (unsigned char*)T, n, action, data, current_state); + obj, (unsigned char*)T, n, match, data, current_state); } int search_all( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { return acsmSearchSparseDFA_Full_All( - obj, (unsigned char*)T, n, action, data, current_state); + obj, (unsigned char*)T, n, match, data, current_state); } int print_info() override diff --git a/src/search_engines/ac_full_q.cc b/src/search_engines/ac_full_q.cc index 3054107cd..fbbe8a185 100644 --- a/src/search_engines/ac_full_q.cc +++ b/src/search_engines/ac_full_q.cc @@ -69,25 +69,25 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return acsmCompile2(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { return acsmSearchSparseDFA_Full_q( - obj, (unsigned char*)T, n, action, data, current_state); + obj, (unsigned char*)T, n, match, data, current_state); } int search_all( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { return acsmSearchSparseDFA_Full_q_all( - obj, (unsigned char*)T, n, action, data, current_state); + obj, (unsigned char*)T, n, match, data, current_state); } int print_info() override diff --git a/src/search_engines/ac_sparse.cc b/src/search_engines/ac_sparse.cc index 279bd9990..83c963904 100644 --- a/src/search_engines/ac_sparse.cc +++ b/src/search_engines/ac_sparse.cc @@ -60,17 +60,17 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return acsmCompile2(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { return acsmSearchSparseDFA( - obj, (unsigned char*)T, n, action, data, current_state); + obj, (unsigned char*)T, n, match, data, current_state); } int print_info() override diff --git a/src/search_engines/ac_sparse_bands.cc b/src/search_engines/ac_sparse_bands.cc index 2a9e09e41..75121d7f1 100644 --- a/src/search_engines/ac_sparse_bands.cc +++ b/src/search_engines/ac_sparse_bands.cc @@ -63,17 +63,17 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return acsmCompile2(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { return acsmSearchSparseNFA( - obj, (unsigned char*)T, n, action, data, current_state); + obj, (unsigned char*)T, n, match, data, current_state); } int print_info() override diff --git a/src/search_engines/ac_std.cc b/src/search_engines/ac_std.cc index 2a7f35d7a..f18656f92 100644 --- a/src/search_engines/ac_std.cc +++ b/src/search_engines/ac_std.cc @@ -64,17 +64,17 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return acsmCompile(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { return acsmSearch( - obj, (unsigned char*)T, n, action, data, current_state); + obj, (unsigned char*)T, n, match, data, current_state); } int print_info() override @@ -111,14 +111,11 @@ static void ac_dtor(Mpse* p) static void ac_init() { acsmx_init_xlatcase(); - // TBD this was never implemented for acsmx (only acsmx2) - //acsm_init_summary(); } static void ac_print() { - // TBD this was apparently partly cloned from acsmx2 and never finished - //acsmPrintSummaryInfo(); + acsmPrintSummaryInfo(); } static const MpseApi ac_api = diff --git a/src/search_engines/acsmx.cc b/src/search_engines/acsmx.cc index 883f7fdae..dbf363d05 100644 --- a/src/search_engines/acsmx.cc +++ b/src/search_engines/acsmx.cc @@ -66,29 +66,18 @@ #define MEMASSERT(p,s) if (!p) { fprintf(stderr,"ACSM-No Memory: %s\n",s); exit(0); } -#ifdef DEBUG_AC static int max_memory = 0; -#endif - -/*static void Print_DFA( ACSM_STRUCT * acsm );*/ -/* -* -*/ static void* AC_MALLOC(int n) { - void* p; - p = calloc (1,n); -#ifdef DEBUG_AC + void* p = calloc (1,n); + if (p) max_memory += n; -#endif + return p; } -/* -* -*/ static void AC_FREE(void* p) { if (p) @@ -461,10 +450,7 @@ int acsmAddPattern( } static int acsmBuildMatchStateTrees( - SnortConfig* sc, - ACSM_STRUCT* acsm, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list) ) + SnortConfig* sc, ACSM_STRUCT* acsm, MpseBuild build_tree, MpseNegate neg_list_func) { int i, cnt = 0; ACSM_PATTERN* mlist; @@ -556,21 +542,11 @@ static inline int _acsmCompile(ACSM_STRUCT* acsm) /* Convert the NFA to a DFA */ Convert_NFA_To_DFA (acsm); - /* - printf ("ACSMX-Max Memory: %d bytes, %d states\n", max_memory, - acsm->acsmMaxStates); - */ - - //Print_DFA( acsm ); - return 0; } int acsmCompile( - SnortConfig* sc, - ACSM_STRUCT* acsm, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)) + SnortConfig* sc, ACSM_STRUCT* acsm, MpseBuild build_tree, MpseNegate neg_list_func) { int rval; @@ -591,7 +567,7 @@ static THREAD_LOCAL unsigned char Tc[64*1024]; * Search Text or Binary Data for Pattern matches */ int acsmSearch( - ACSM_STRUCT* acsm, unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT* acsm, unsigned char* Tx, int n, MpseMatch match, void* data, int* current_state) { int state = 0; @@ -623,7 +599,7 @@ int acsmSearch( mlist = StateTable[state].MatchList; index = T - mlist->n + 1 - Tc; nfound++; - if (Match (mlist->udata->id, mlist->rule_option_tree, index, data, mlist->neg_list) > + if (match (mlist->udata->id, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; @@ -690,10 +666,6 @@ int acsmPatternCount(ACSM_STRUCT* acsm) return acsm->numPatterns; } -/* - * - */ -/* static void Print_DFA( ACSM_STRUCT * acsm ) { int k; @@ -718,44 +690,20 @@ static void Print_DFA( ACSM_STRUCT * acsm ) } } -*/ -int acsmPrintDetailInfo(ACSM_STRUCT*) +int acsmPrintDetailInfo(ACSM_STRUCT* acsm) { + Print_DFA( acsm ); return 0; } int acsmPrintSummaryInfo(void) { -#ifdef XXXXX - char* fsa[]= - { - "TRIE", - "NFA", - "DFA", - }; - - ACSM_STRUCT2* p = &summary.acsm; - - if ( !summary.num_states ) - return; - - LogMessage("+--[Pattern Matcher:Aho-Corasick Summary]----------------------\n"); - LogMessage("| Alphabet Size : %d Chars\n",p->acsmAlphabetSize); - LogMessage("| Sizeof State : %d bytes\n",sizeof(acstate_t)); - LogMessage("| Storage Format : %s \n",sf[ p->acsmFormat ]); - LogMessage("| Num States : %d\n",summary.num_states); - LogMessage("| Num Transitions : %d\n",summary.num_transitions); - LogMessage("| State Density : %.1f%%\n",100.0*(double)summary.num_transitions/ - (summary.num_states*p->acsmAlphabetSize)); - LogMessage("| Finite Automatum : %s\n", fsa[p->acsmFSA]); - if ( max_memory < 1024*1024 ) - LogMessage("| Memory : %.2fKbytes\n", (float)max_memory/1024); - else - LogMessage("| Memory : %.2fMbytes\n", (float)max_memory/(1024*1024) ); - LogMessage("+-------------------------------------------------------------\n"); - +#if 0 + printf ("ACSMX-Max Memory: %d bytes, %d states\n", max_memory, + acsm->acsmMaxStates); #endif + return 0; } diff --git a/src/search_engines/acsmx.h b/src/search_engines/acsmx.h index 75f7be9ba..fe0f5f847 100644 --- a/src/search_engines/acsmx.h +++ b/src/search_engines/acsmx.h @@ -18,31 +18,25 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** ACSMX.H -** -** -*/ +// acsmx.h author Marc Norton + +#ifndef ACSMX_H +#define ACSMX_H + +// version 1 #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "snort_types.h" #include #include #include -#include "search_common.h" -#ifndef ACSMX_H -#define ACSMX_H - -/* -* Prototypes -*/ +#include "main/snort_types.h" +#include "search_common.h" #define ALPHABET_SIZE 256 - #define ACSM_FAIL_STATE -1 typedef struct _acsm_userdata @@ -109,21 +103,11 @@ ACSM_STRUCT* acsmNew(void (* userfree)(void* p), int acsmAddPattern(ACSM_STRUCT* p, const uint8_t* pat, unsigned n, bool nocase, bool negative, void* id, int iid); -int acsmCompile(ACSM_STRUCT* acsm, - int (* build_tree)(void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)); - -struct SnortConfig; - -int acsmCompile( - SnortConfig*, - ACSM_STRUCT* acsm, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)); +int acsmCompile(struct SnortConfig*, ACSM_STRUCT* acsm, MpseBuild, MpseNegate); int acsmSearch ( -ACSM_STRUCT * acsm,unsigned char* T, int n, MpseCallback, -void* data, int* current_state); + ACSM_STRUCT * acsm,unsigned char* T, int n, MpseMatch, + void* data, int* current_state); void acsmFree(ACSM_STRUCT* acsm); int acsmPatternCount(ACSM_STRUCT* acsm); diff --git a/src/search_engines/acsmx2.cc b/src/search_engines/acsmx2.cc index 2dfea3459..f44d0de33 100644 --- a/src/search_engines/acsmx2.cc +++ b/src/search_engines/acsmx2.cc @@ -1568,7 +1568,6 @@ int acsmSelectFSA2(ACSM_STRUCT2* acsm, int m) { switch ( m ) { - case FSA_TRIE: case FSA_NFA: case FSA_DFA: acsm->acsmFSA = m; @@ -1729,10 +1728,7 @@ static void acsmUpdateMatchStates(ACSM_STRUCT2* acsm) } static int acsmBuildMatchStateTrees2( - SnortConfig* sc, - ACSM_STRUCT2* acsm, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list) ) + SnortConfig* sc, ACSM_STRUCT2* acsm, MpseBuild build_tree, MpseNegate neg_list_func) { int i, cnt = 0; ACSM_PATTERN2** MatchList = acsm->acsmMatchList; @@ -1913,6 +1909,11 @@ static inline int _acsmCompile2(ACSM_STRUCT2* acsm) acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); List_PrintTransTable(acsm); } + + /* Don't need the FailState table anymore */ + AC_FREE(acsm->acsmFailState, sizeof(acstate_t) * acsm->acsmNumStates, + ACSM2_MEMORY_TYPE__FAILSTATE); + acsm->acsmFailState = NULL; } /* Select Final Transition Table Storage Mode */ @@ -1977,11 +1978,6 @@ static inline int _acsmCompile2(ACSM_STRUCT2* acsm) acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); Print_DFA(acsm); } - - /* Don't need the FailState table anymore */ - AC_FREE(acsm->acsmFailState, sizeof(acstate_t) * acsm->acsmNumStates, - ACSM2_MEMORY_TYPE__FAILSTATE); - acsm->acsmFailState = NULL; } /* load boolean match flags into state table */ @@ -2011,11 +2007,7 @@ static inline int _acsmCompile2(ACSM_STRUCT2* acsm) } int acsmCompile2( - SnortConfig* sc, - ACSM_STRUCT2* acsm, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list) - ) + SnortConfig* sc, ACSM_STRUCT2* acsm, MpseBuild build_tree, MpseNegate neg_list_func) { int rval; @@ -2254,7 +2246,7 @@ static inline acstate_t SparseGetNextStateDFA( * Sparse & Sparse-Banded Matrix search */ int acsmSearchSparseDFA( - ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseMatch match, void* data, int* current_state) { acstate_t state; @@ -2289,7 +2281,7 @@ int acsmSearchSparseDFA( { index = T - mlist->n - Tc + 1; nfound++; - if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > + if (match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; @@ -2350,7 +2342,7 @@ static inline int _add_queue(PMQ* b, void* p) } static inline unsigned _process_queue( - PMQ* q, MpseCallback Match, void* data) + PMQ* q, MpseMatch match, void* data) { ACSM_PATTERN2* mlist; unsigned int i; @@ -2366,7 +2358,7 @@ static inline unsigned _process_queue( mlist = (ACSM_PATTERN2*)q->q[i]; if (mlist) { - if (Match (mlist->udata, mlist->rule_option_tree, 0, data, mlist->neg_list) > 0) + if (match (mlist->udata, mlist->rule_option_tree, 0, data, mlist->neg_list) > 0) { q->inq = 0; return 1; @@ -2397,7 +2389,7 @@ static inline unsigned _process_queue( { \ if (_add_queue(&acsm->q,MatchList[state])) \ { \ - if (_process_queue(&acsm->q, Match,data)) \ + if (_process_queue(&acsm->q, match, data)) \ { \ *current_state = state; \ return 1; \ @@ -2409,7 +2401,7 @@ static inline unsigned _process_queue( } int acsmSearchSparseDFA_Full_q( - ACSM_STRUCT2* acsm, unsigned char* T, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, unsigned char* T, int n, MpseMatch match, void* data, int* current_state) { unsigned char* Tend; @@ -2456,7 +2448,7 @@ int acsmSearchSparseDFA_Full_q( if (MatchList[state]) _add_queue(&acsm->q,MatchList[state]); - _process_queue(&acsm->q,Match,data); + _process_queue(&acsm->q, match, data); return 0; } @@ -2485,7 +2477,7 @@ int acsmSearchSparseDFA_Full_q( { \ if (_add_queue(&acsm->q,mlist)) \ { \ - if (_process_queue(&acsm->q, Match,data)) \ + if (_process_queue(&acsm->q, match, data)) \ { \ *current_state = state; \ return 1; \ @@ -2498,7 +2490,7 @@ int acsmSearchSparseDFA_Full_q( } int acsmSearchSparseDFA_Full_q_all( - ACSM_STRUCT2* acsm, const unsigned char* T, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) { const unsigned char* Tend; @@ -2551,7 +2543,7 @@ int acsmSearchSparseDFA_Full_q_all( { if (_add_queue(&acsm->q,mlist)) { - if (_process_queue(&acsm->q, Match,data)) + if (_process_queue(&acsm->q, match, data)) { *current_state = state; return 1; @@ -2560,7 +2552,7 @@ int acsmSearchSparseDFA_Full_q_all( } } - _process_queue(&acsm->q,Match,data); + _process_queue(&acsm->q, match, data); return 0; } @@ -2587,7 +2579,7 @@ int acsmSearchSparseDFA_Full_q_all( { \ index = T - mlist->n - Tx; \ nfound++; \ - if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > \ + if (match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > \ 0) \ { \ *current_state = state; \ @@ -2599,7 +2591,7 @@ int acsmSearchSparseDFA_Full_q_all( } int acsmSearchSparseDFA_Full( - ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseMatch match, void* data, int* current_state ) { @@ -2651,7 +2643,7 @@ int acsmSearchSparseDFA_Full( { index = T - mlist->n - Tx; nfound++; - if (Match(mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) + if (match(mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; @@ -2687,7 +2679,7 @@ int acsmSearchSparseDFA_Full( if ( mlist->nocase || (memcmp (mlist->casepatrn, Tx + index, mlist->n) == 0)) \ { \ nfound++; \ - if (Match (mlist->udata, mlist->rule_option_tree, index, data, \ + if (match (mlist->udata, mlist->rule_option_tree, index, data, \ mlist->neg_list) > 0) \ { \ *current_state = state; \ @@ -2700,7 +2692,7 @@ int acsmSearchSparseDFA_Full( } int acsmSearchSparseDFA_Full_All( - ACSM_STRUCT2* acsm, const unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, const unsigned char* Tx, int n, MpseMatch match, void* data, int* current_state) { ACSM_PATTERN2* mlist; @@ -2755,7 +2747,7 @@ int acsmSearchSparseDFA_Full_All( if ( mlist->nocase || (memcmp (mlist->casepatrn, Tx + index, mlist->n) == 0)) { nfound++; - if (Match(mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) + if (match(mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; @@ -2778,7 +2770,7 @@ int acsmSearchSparseDFA_Full_All( * ps[3] = index of 1st element */ int acsmSearchSparseDFA_Banded( - ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseMatch match, void* data, int* current_state) { acstate_t state; @@ -2816,7 +2808,7 @@ int acsmSearchSparseDFA_Banded( { index = T - mlist->n - Tx; nfound++; - if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > + if (match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; @@ -2839,7 +2831,7 @@ int acsmSearchSparseDFA_Banded( { index = T - mlist->n - Tx; nfound++; - if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) + if (match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; @@ -2855,7 +2847,7 @@ int acsmSearchSparseDFA_Banded( * Sparse Storage Version */ int acsmSearchSparseNFA( - ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseMatch match, void* data, int* current_state) { acstate_t state; @@ -2895,7 +2887,7 @@ int acsmSearchSparseNFA( { index = T - mlist->n - Tx; nfound++; - if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) + if (match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; @@ -3025,11 +3017,11 @@ int acsmPrintSummaryInfo2(void) { const char* sf[]= { - "Full", - "Sparse", - "Banded", - "Sparse-Bands", - "Full-Q" + "full", + "sparse", + "banded", + "sparse-bands", + "full-queue" }; const char* fsa[]= @@ -3044,59 +3036,56 @@ int acsmPrintSummaryInfo2(void) if ( !summary.num_states ) return 0; - LogMessage("%s\n", LOG_DIV); - LogMessage("aho-corasick summary\n"); + LogValue("storage format", sf[p->acsmFormat]); + LogValue("finite automaton", fsa[p->acsmFSA]); + LogCount("alphabet size", p->acsmAlphabetSize); - LogMessage("%25.25s: %s\n", "storage format", sf[p->acsmFormat]); - LogMessage("%25.25s: %s\n", "finite automaton", fsa[p->acsmFSA]); - LogMessage("%25.25s: %-12u\n", "alphabet size", p->acsmAlphabetSize); + LogCount("instances", summary.num_instances); + LogCount("patterns", summary.num_patterns); + LogCount("pattern chars", summary.num_characters); - if (summary.acsm.compress_states) - LogMessage("%25.25s: %s\n", "sizeof state", "1, 2, or 4"); + LogCount("states", summary.num_states); + LogCount("transitions", summary.num_transitions); + LogCount("match states", summary.num_match_states); + + if ( !summary.acsm.compress_states ) + LogCount("sizeof state", (int)(sizeof(acstate_t))); else - LogMessage("%25.25s: %-12u\n", "sizeof state", (int)(sizeof(acstate_t))); + { + LogValue("sizeof state", "1, 2, or 4"); - LogMessage("%25.25s: %-12u\n", "instances", summary.num_instances); + if ( summary.num_1byte_instances ) + LogCount("1 byte states", summary.num_1byte_instances); - if ( summary.acsm.compress_states && summary.num_1byte_instances ) - LogMessage("%25.25s: %-12u\n", "1 byte states", summary.num_1byte_instances); + if ( summary.num_2byte_instances ) + LogCount("2 byte states", summary.num_2byte_instances); - if ( summary.acsm.compress_states && summary.num_2byte_instances ) - LogMessage("%25.25s: %-12u\n", "2 byte states", summary.num_2byte_instances); + if ( summary.num_4byte_instances ) + LogCount("4 byte states", summary.num_4byte_instances); + } - if ( summary.acsm.compress_states && summary.num_4byte_instances ) - LogMessage("%25.25s: %-12u\n", "4 byte states", summary.num_4byte_instances); + double scale; - LogMessage("%25.25s: %-12u\n", "characters", summary.num_characters); - LogMessage("%25.25s: %-12u\n", "states", summary.num_states); - LogMessage("%25.25s: %-12u\n", "transitions", summary.num_transitions); + if ( acsm2_total_memory < 1024*1024 ) + { + scale = 1024; + LogValue("memory scale", "KB"); + } + else + { + scale = 1024 * 1024; + LogValue("memory scale", "MB"); + } + LogStat("total memory", acsm2_total_memory/scale); + LogStat("pattern memory", acsm2_pattern_memory/scale); + LogStat("match list memory", acsm2_matchlist_memory/scale); + LogStat("transition memory", acsm2_transtable_memory/scale); + LogStat("fail state memory", acsm2_failstate_memory/scale); - //LogMessage("%25.25s: %-12u\n", "", ); #if 0 // FIXIT-L clean up format; not all this should be printed all the time //#ifndef VALGRIND_TESTING // valgrind on macos claims leakage here ... - LogMessage("| State Density : %.1f%%\n", - pct(summary.num_transitions, summary.num_states*p->acsmAlphabetSize)); - LogMessage("| Patterns : %u\n",summary.num_patterns); - LogMessage("| Match States : %d\n",summary.num_match_states); - - double scale = 1024 * 1024.0; - const char* units = "MB"; - if ( acsm2_total_memory < 1024*1024 ) - { - scale = 1024.0; - units = "KB"; - } - LogMessage("| Memory (%s) : %.2f\n", units, acsm2_total_memory/scale); - if (acsm2_pattern_memory > 0) - LogMessage("| Pattern : %.2f\n", acsm2_pattern_memory/scale); - if (acsm2_matchlist_memory > 0) - LogMessage("| Match Lists : %.2f\n", acsm2_matchlist_memory/scale); - if (acsm2_transtable_memory > 0) - LogMessage("| Transitions : %.2f\n", acsm2_transtable_memory/scale); - if (acsm2_failstate_memory > 0) - LogMessage("| Fail States : %.2f\n", acsm2_failstate_memory/scale); if (acsm2_dfa_memory > 0) { if (summary.acsm.compress_states) @@ -3118,7 +3107,7 @@ int acsmPrintSummaryInfo2(void) #ifdef ACSMX2S_MAIN static int acsmSearch2( - ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseMatch match, void* data, int* current_state) { switch ( acsm->acsmFSA ) @@ -3127,39 +3116,35 @@ static int acsmSearch2( if ( acsm->acsmFormat == ACF_FULL ) { - return acsmSearchSparseDFA_Full(acsm, Tx, n, Match, data, + return acsmSearchSparseDFA_Full(acsm, Tx, n, match, data, current_state); } else if ( acsm->acsmFormat == ACF_FULLQ ) { - return acsmSearchSparseDFA_Full_q(acsm, Tx, n, Match, data, + return acsmSearchSparseDFA_Full_q(acsm, Tx, n, match, data, current_state); } else if ( acsm->acsmFormat == ACF_BANDED ) { - return acsmSearchSparseDFA_Banded(acsm, Tx, n, Match, data, + return acsmSearchSparseDFA_Banded(acsm, Tx, n, match, data, current_state); } else { - return acsmSearchSparseDFA(acsm, Tx, n, Match, data, + return acsmSearchSparseDFA(acsm, Tx, n, match, data, current_state); } case FSA_NFA: - return acsmSearchSparseNFA(acsm, Tx, n, Match, data, + return acsmSearchSparseNFA(acsm, Tx, n, match, data, current_state); - - case FSA_TRIE: - - return 0; } return 0; } static int acsmSearchAll2( - ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT2* acsm, unsigned char* Tx, int n, MpseMatch match, void* data, int* current_state) { switch ( acsm->acsmFSA ) @@ -3168,33 +3153,29 @@ static int acsmSearchAll2( if ( acsm->acsmFormat == ACF_FULL ) { - return acsmSearchSparseDFA_Full_All(acsm, Tx, n, Match, data, + return acsmSearchSparseDFA_Full_All(acsm, Tx, n, match, data, current_state); } else if ( acsm->acsmFormat == ACF_FULLQ ) { - return acsmSearchSparseDFA_Full_q_all(acsm, Tx, n, Match, data, + return acsmSearchSparseDFA_Full_q_all(acsm, Tx, n, match, data, current_state); } else if ( acsm->acsmFormat == ACF_BANDED ) { - return acsmSearchSparseDFA_Banded(acsm, Tx, n, Match, data, + return acsmSearchSparseDFA_Banded(acsm, Tx, n, match, data, current_state); } else { - return acsmSearchSparseDFA(acsm, Tx, n, Match, data, + return acsmSearchSparseDFA(acsm, Tx, n, match, data, current_state); } case FSA_NFA: - return acsmSearchSparseNFA(acsm, Tx, n, Match, data, + return acsmSearchSparseNFA(acsm, Tx, n, match, data, current_state); - - case FSA_TRIE: - - return 0; } return 0; } @@ -3289,10 +3270,6 @@ int main(int argc, char** argv) { acsm->acsmFSA = FSA_DFA; } - if (strcmp (argv[i], "-trie") == 0) - { - acsm->acsmFSA = FSA_TRIE; - } } for (i = 2; i < argc; i++) diff --git a/src/search_engines/acsmx2.h b/src/search_engines/acsmx2.h index adc52f7a4..94af5ea3a 100644 --- a/src/search_engines/acsmx2.h +++ b/src/search_engines/acsmx2.h @@ -17,35 +17,24 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** ACSMX2.H -** -** Version 2.0 -** -** Author: Marc Norton -*/ +// acsmx2.h author Marc Norton -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +#ifndef ACSMX2_H +#define ACSMX2_H + +// Version 2.0 #include #include #include #include -#include "search_common.h" -#ifndef ACSMX2_H -#define ACSMX2_H +#include "search_common.h" -/* -* DEFINES and Typedef's -*/ #define MAX_ALPHABET_SIZE 256 /* FAIL STATE for 1,2,or 4 bytes for state transitions - Uncomment this define to use 32 bit state values #define AC32 */ @@ -64,11 +53,7 @@ typedef unsigned short acstate_t; #endif -/* -* -*/ -typedef - struct _acsm_pattern2 +typedef struct _acsm_pattern2 { struct _acsm_pattern2* next; @@ -86,16 +71,14 @@ typedef /* * transition nodes - either 8 or 12 bytes */ -typedef - struct trans_node_s +typedef struct trans_node_s { - acstate_t key; /* The character that got us here - sized to keep structure aligned - on 4 bytes - to better the caching opportunities. A value that crosses the - cache line - forces an expensive reconstruction, typing this as acstate_t stops - that. */ - acstate_t next_state; /* */ + /* The character that got us here - sized to keep structure aligned on 4 bytes + * to better the caching opportunities. A value that crosses the cache line + * forces an expensive reconstruction, typing this as acstate_t stops that. + */ + acstate_t key; + acstate_t next_state; struct trans_node_s* next; /* next transition for this state */ } trans_node_t; @@ -114,13 +97,11 @@ enum /* * User specified machine types * -* TRIE : Keyword trie * NFA : * DFA : */ enum { - FSA_TRIE, FSA_NFA, FSA_DFA }; @@ -181,57 +162,46 @@ int acsmAddPattern2( ACSM_STRUCT2* p, const uint8_t* pat, unsigned n, bool nocase, bool negative, void* id, int iid); -int acsmCompile2( - ACSM_STRUCT2* acsm, - int (* build_tree)(void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)); - -struct SnortConfig; - -int acsmCompile2( - SnortConfig*, - ACSM_STRUCT2* acsm, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)); +int acsmCompile2(struct SnortConfig*, ACSM_STRUCT2*, MpseBuild, MpseNegate); int acsmSearchSparseDFA_Full( - ACSM_STRUCT2* acsm,unsigned char* T, int n, MpseCallback Match, + ACSM_STRUCT2*, unsigned char* T, int n, MpseMatch, void* data, int* current_state); int acsmSearchSparseDFA_Full_q( - ACSM_STRUCT2* acsm,unsigned char* T, int n, MpseCallback Match, + ACSM_STRUCT2*, unsigned char* T, int n, MpseMatch, void* data, int* current_state); int acsmSearchSparseDFA_Banded( - ACSM_STRUCT2* acsm,unsigned char* T, int n, MpseCallback Match, + ACSM_STRUCT2*, unsigned char* T, int n, MpseMatch, void* data, int* current_state); int acsmSearchSparseDFA( - ACSM_STRUCT2* acsm,unsigned char* T, int n, MpseCallback Match, + ACSM_STRUCT2*, unsigned char* T, int n, MpseMatch, void* data, int* current_state); int acsmSearchSparseNFA( - ACSM_STRUCT2* acsm,unsigned char* T, int n, MpseCallback Match, + ACSM_STRUCT2*, unsigned char* T, int n, MpseMatch, void* data, int* current_state); int acsmSearchSparseDFA_Full_All( - ACSM_STRUCT2* acsm, const unsigned char* Tx, int n, MpseCallback Match, + ACSM_STRUCT2*, const unsigned char* Tx, int n, MpseMatch, void* data, int* current_state); int acsmSearchSparseDFA_Full_q_all( - ACSM_STRUCT2* acsm, const unsigned char* T, int n, MpseCallback Match, + ACSM_STRUCT2*, const unsigned char* T, int n, MpseMatch, void* data, int* current_state); void acsmFree2(ACSM_STRUCT2* acsm); int acsmPatternCount2(ACSM_STRUCT2* acsm); void acsmCompressStates(ACSM_STRUCT2*, int); -int acsmSelectFormat2(ACSM_STRUCT2* acsm, int format); -int acsmSelectFSA2(ACSM_STRUCT2* acsm, int fsa); +int acsmSelectFormat2(ACSM_STRUCT2*, int format); +int acsmSelectFSA2(ACSM_STRUCT2*, int fsa); -void acsmSetMaxSparseBandZeros2(ACSM_STRUCT2* acsm, int n); -void acsmSetMaxSparseElements2(ACSM_STRUCT2* acsm, int n); -int acsmSetAlphabetSize2(ACSM_STRUCT2* acsm, int n); +void acsmSetMaxSparseBandZeros2(ACSM_STRUCT2*, int n); +void acsmSetMaxSparseElements2(ACSM_STRUCT2*, int n); +int acsmSetAlphabetSize2(ACSM_STRUCT2*, int n); void acsmSetVerbose2(void); void acsmPrintInfo2(ACSM_STRUCT2* p); diff --git a/src/search_engines/bnfa_search.cc b/src/search_engines/bnfa_search.cc index ce53cdf44..5eec21dbd 100644 --- a/src/search_engines/bnfa_search.cc +++ b/src/search_engines/bnfa_search.cc @@ -474,10 +474,7 @@ static int _bnfa_list_free_table(bnfa_struct_t* bnfa) } static int bnfaBuildMatchStateTrees( - SnortConfig* sc, - bnfa_struct_t* bnfa, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)) + SnortConfig* sc, bnfa_struct_t* bnfa, MpseBuild build_tree, MpseNegate neg_list_func) { int i,cnt = 0; bnfa_match_node_t* mn; @@ -1616,10 +1613,7 @@ static inline int _bnfaCompile(bnfa_struct_t* bnfa) } int bnfaCompile( - SnortConfig* sc, - bnfa_struct_t* bnfa, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func )(void* id, void** list)) + SnortConfig* sc, bnfa_struct_t* bnfa, MpseBuild build_tree, MpseNegate neg_list_func) { int rval; @@ -1639,7 +1633,7 @@ int bnfaCompile( * Full Matrix Format Search */ static inline unsigned _bnfa_search_full_nfa( - bnfa_struct_t* bnfa, unsigned char* Tx, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, unsigned char* Tx, int n, MpseMatch match, void* data, bnfa_state_t state, int* current_state) { unsigned char* Tend; @@ -1702,7 +1696,7 @@ static inline unsigned _bnfa_search_full_nfa( * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ - res = Match (patrn->userdata, mlist->rule_option_tree, index, data, + res = match(patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { @@ -1724,7 +1718,7 @@ static inline unsigned _bnfa_search_full_nfa( * Full Matrix Format Search - Exact matching patterns only */ static inline unsigned _bnfa_search_full_nfa_case( - bnfa_struct_t* bnfa, unsigned char* Tx, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, unsigned char* Tx, int n, MpseMatch match, void* data, bnfa_state_t state, int* current_state) { unsigned char* Tend; @@ -1787,7 +1781,7 @@ static inline unsigned _bnfa_search_full_nfa_case( * since that will be covered by the rule tree itself. Each * tree might have both case sensitive & case insensitive patterns. */ - res = Match (patrn->userdata, mlist->rule_option_tree, index, data, + res = match(patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { @@ -1809,7 +1803,7 @@ static inline unsigned _bnfa_search_full_nfa_case( * Full Matrix Format Search - no case */ static inline unsigned _bnfa_search_full_nfa_nocase( - bnfa_struct_t* bnfa, unsigned char* Tx, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, unsigned char* Tx, int n, MpseMatch match, void* data, bnfa_state_t state, int* current_state) { unsigned char* Tend; @@ -1871,7 +1865,7 @@ static inline unsigned _bnfa_search_full_nfa_nocase( * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ - res = Match (patrn->userdata, mlist->rule_option_tree, index, data, + res = match(patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { @@ -2125,7 +2119,7 @@ static inline int _add_queue(bnfa_struct_t* b, bnfa_match_node_t* p) } static inline unsigned _process_queue( - bnfa_struct_t* bnfa, bnfa_match_f Match, void* data) + bnfa_struct_t* bnfa, MpseMatch match, void* data) { bnfa_match_node_t* mlist; bnfa_pattern_t* patrn; @@ -2145,7 +2139,7 @@ static inline unsigned _process_queue( { patrn = (bnfa_pattern_t*)mlist->data; /*process a pattern - case is handled by otn processing */ - res = Match ((bnfa_pattern_t*)patrn->userdata, mlist->rule_option_tree, 0, data, + res = match(patrn->userdata, mlist->rule_option_tree, 0, data, mlist->neg_list); if ( res > 0 ) { @@ -2161,7 +2155,7 @@ static inline unsigned _process_queue( #ifdef BNFA_MAIN static inline unsigned _bnfa_search_csparse_nfa_qx( - bnfa_struct_t* bnfa, unsigned char* T, int n, bnfa_match_f Match, void* data) + bnfa_struct_t* bnfa, unsigned char* T, int n, MpseMatch match, void* data) { bnfa_match_node_t* mlist; unsigned char* Tend; @@ -2186,7 +2180,7 @@ static inline unsigned _bnfa_search_csparse_nfa_qx( { if ( _add_queue(bnfa,mlist) ) { - if ( _process_queue(bnfa, Match, data) ) + if ( _process_queue(bnfa, match, data) ) { return 1; } @@ -2204,7 +2198,7 @@ static inline unsigned _bnfa_search_csparse_nfa_qx( #endif unsigned _bnfa_search_csparse_nfa_q( - bnfa_struct_t* bnfa, unsigned char* T, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, unsigned char* T, int n, MpseMatch match, void* data, unsigned sindex, int* current_state) { bnfa_match_node_t* mlist; @@ -2236,7 +2230,7 @@ unsigned _bnfa_search_csparse_nfa_q( { if ( _add_queue(bnfa,mlist) ) { - if ( _process_queue(bnfa, Match, data) ) + if ( _process_queue(bnfa, match, data) ) { *current_state = sindex; return 1; @@ -2247,7 +2241,7 @@ unsigned _bnfa_search_csparse_nfa_q( } *current_state = sindex; - return _process_queue(bnfa, Match, data); + return _process_queue(bnfa, match, data); } /* @@ -2257,7 +2251,7 @@ unsigned _bnfa_search_csparse_nfa_q( * note: index is not used by snort, so it's commented */ unsigned _bnfa_search_csparse_nfa( - bnfa_struct_t* bnfa, const uint8_t* Tx, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, const uint8_t* Tx, int n, MpseMatch match, void* data, unsigned sindex, int* current_state) { bnfa_match_node_t* mlist; @@ -2314,7 +2308,7 @@ unsigned _bnfa_search_csparse_nfa( * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ - res = Match ((bnfa_pattern_t*)patrn->userdata, mlist->rule_option_tree, index, + res = match(patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { @@ -2339,7 +2333,7 @@ unsigned _bnfa_search_csparse_nfa( * note: index is not used by snort, so it's commented */ static inline unsigned _bnfa_search_csparse_nfa_case( - bnfa_struct_t* bnfa, unsigned char* Tx, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, unsigned char* Tx, int n, MpseMatch match, void* data, unsigned sindex, int* current_state) { bnfa_match_node_t* mlist; @@ -2383,7 +2377,7 @@ static inline unsigned _bnfa_search_csparse_nfa_case( * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ - res = Match ((bnfa_pattern_t*)patrn->userdata, mlist->rule_option_tree, index, + res = match(patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { @@ -2407,7 +2401,7 @@ static inline unsigned _bnfa_search_csparse_nfa_case( * note: index is not used by snort, so it's commented */ static inline unsigned _bnfa_search_csparse_nfa_nocase( - bnfa_struct_t* bnfa, unsigned char* Tx, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, unsigned char* Tx, int n, MpseMatch match, void* data, unsigned sindex, int* current_state) { bnfa_match_node_t* mlist; @@ -2454,7 +2448,7 @@ static inline unsigned _bnfa_search_csparse_nfa_nocase( * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ - res = Match ((bnfa_pattern_t*)patrn->userdata, mlist->rule_option_tree, index, + res = match(patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { @@ -2506,16 +2500,17 @@ static void bnfaPrintInfoEx(bnfa_struct_t* p) if ( max_memory < 1024*1024 ) { scale = 1024; - LogStat("memory (KB)", max_memory/scale); + LogValue("memory scale", "KB"); } else { scale = 1024 * 1024; - LogStat("memory (MB)", max_memory/scale); + LogValue("memory scale", "MB"); } - LogStat("patterns", p->pat_memory/scale); - LogStat("match lists", p->matchlist_memory/scale); - LogStat("transitions", p->nextstate_memory/scale); + LogStat("total memory", max_memory/scale); + LogStat("pattern memory", p->pat_memory/scale); + LogStat("match list memory", p->matchlist_memory/scale); + LogStat("transition memory", p->nextstate_memory/scale); } void bnfaPrintInfo(bnfa_struct_t* p) @@ -2605,7 +2600,7 @@ void bnfaPrintMatchListCnt(bnfa_struct_t* p) * in on the next search, if desired. */ unsigned bnfaSearchX( - bnfa_struct_t* bnfa, unsigned char* T, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, unsigned char* T, int n, MpseMatch match, void* data, unsigned, int*) { int ret; @@ -2613,17 +2608,17 @@ unsigned bnfaSearchX( _init_queue(bnfa); while ( n > 0) { - ret = _bnfa_search_csparse_nfa_qx(bnfa, T++, n--, Match, data); + ret = _bnfa_search_csparse_nfa_qx(bnfa, T++, n--, match, data); if ( ret ) return 0; } - return _process_queue(bnfa, Match, data); + return _process_queue(bnfa, match, data); } // FIXIT-L eliminate the if-else- unsigned bnfaSearch( - bnfa_struct_t* bnfa, unsigned char* Tx, int n, bnfa_match_f Match, + bnfa_struct_t* bnfa, unsigned char* Tx, int n, MpseMatch match, void* data, unsigned sindex, int* current_state) { assert(current_state); @@ -2642,23 +2637,23 @@ unsigned bnfaSearch( if (bnfa->bnfaMethod) { ret = _bnfa_search_csparse_nfa( - bnfa, Tx, n, Match, data, sindex, current_state); + bnfa, Tx, n, match, data, sindex, current_state); } else { ret = _bnfa_search_csparse_nfa_q( - bnfa, Tx, n, Match, data, sindex, current_state); + bnfa, Tx, n, match, data, sindex, current_state); } } else if ( bnfa->bnfaCaseMode == BNFA_CASE ) { ret = _bnfa_search_csparse_nfa_case( - bnfa, Tx, n, Match, data, sindex, current_state); + bnfa, Tx, n, match, data, sindex, current_state); } else /* NOCASE */ { ret = _bnfa_search_csparse_nfa_nocase( - bnfa, Tx, n, Match, data, sindex, current_state); + bnfa, Tx, n, match, data, sindex, current_state); } } else if ( bnfa->bnfaFormat == BNFA_FULL ) @@ -2666,17 +2661,17 @@ unsigned bnfaSearch( if ( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) { ret = _bnfa_search_full_nfa( - bnfa, Tx, n, Match, data, (bnfa_state_t)sindex, current_state); + bnfa, Tx, n, match, data, (bnfa_state_t)sindex, current_state); } else if ( bnfa->bnfaCaseMode == BNFA_CASE ) { ret = _bnfa_search_full_nfa_case( - bnfa, Tx, n, Match, data, (bnfa_state_t)sindex, current_state); + bnfa, Tx, n, match, data, (bnfa_state_t)sindex, current_state); } else { ret = _bnfa_search_full_nfa_nocase( - bnfa, Tx, n, Match, data, (bnfa_state_t)sindex, current_state); + bnfa, Tx, n, match, data, (bnfa_state_t)sindex, current_state); } } #else @@ -2685,23 +2680,23 @@ unsigned bnfaSearch( if (bnfa->bnfaMethod) { ret = _bnfa_search_csparse_nfa( - bnfa, Tx, n, Match, data, sindex, current_state); + bnfa, Tx, n, match, data, sindex, current_state); } else { ret = _bnfa_search_csparse_nfa_q( - bnfa, Tx, n, Match, data, sindex, current_state); + bnfa, Tx, n, match, data, sindex, current_state); } } else if ( bnfa->bnfaCaseMode == BNFA_CASE ) { ret = _bnfa_search_csparse_nfa_case( - bnfa, Tx, n, Match, data, sindex, current_state); + bnfa, Tx, n, match, data, sindex, current_state); } else /* NOCASE */ { ret = _bnfa_search_csparse_nfa_nocase( - bnfa, Tx, n, Match, data, sindex, current_state); + bnfa, Tx, n, match, data, sindex, current_state); } #endif return ret; diff --git a/src/search_engines/bnfa_search.h b/src/search_engines/bnfa_search.h index 512975cfe..bd481e221 100644 --- a/src/search_engines/bnfa_search.h +++ b/src/search_engines/bnfa_search.h @@ -16,15 +16,17 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- + +// bnfa_search.h author Marc Norton + +#ifndef BNFA_SEARCH_H +#define BNFA_SEARCH_H + /* -** bnfa_search.h -** ** Basic NFA based multi-pattern search using Aho_corasick construction, ** and compacted sparse storage. ** ** Version 3.0 -** -** author: marc norton ** date: 12/21/05 */ @@ -33,8 +35,7 @@ #include #include -#ifndef BNFA_SEARCH_H -#define BNFA_SEARCH_H +#include "search_common.h" /* debugging - allow printing the trie and nfa in list format #define ALLOW_LIST_PRINT */ @@ -166,6 +167,7 @@ void bnfa_init_xlatcase(); bnfa_struct_t* bnfaNew(void (* userfree)(void* p), void (* optiontreefree)(void** p), void (* neg_list_free)(void** p)); + void bnfaSetOpt(bnfa_struct_t* p, int flag); void bnfaSetCase(bnfa_struct_t* p, int flag); void bnfaFree(bnfa_struct_t* pstruct); @@ -174,26 +176,15 @@ int bnfaAddPattern( bnfa_struct_t* pstruct, const uint8_t* pat, unsigned patlen, bool nocase, bool negative, void* userdata); -int bnfaCompile(bnfa_struct_t* pstruct, - int (* build_tree)(void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)); -struct SnortConfig; -int bnfaCompile( - SnortConfig*, - bnfa_struct_t* pstruct, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)); - -typedef int (* bnfa_match_f)( - bnfa_pattern_t*, void* tree, int index, void* data, void* neg_list); +int bnfaCompile(struct SnortConfig*, bnfa_struct_t*, MpseBuild, MpseNegate); unsigned _bnfa_search_csparse_nfa( -bnfa_struct_t * pstruct, const uint8_t* t, int tlen, bnfa_match_f, -void* sdata, unsigned sindex, int* current_state); + bnfa_struct_t * pstruct, const uint8_t* t, int tlen, MpseMatch, + void* sdata, unsigned sindex, int* current_state); unsigned _bnfa_search_csparse_nfa_q( -bnfa_struct_t * pstruct, unsigned char* t, int tlen, bnfa_match_f, -void* sdata, unsigned sindex, int* current_state); + bnfa_struct_t * pstruct, unsigned char* t, int tlen, MpseMatch, + void* sdata, unsigned sindex, int* current_state); int bnfaPatternCount(bnfa_struct_t* p); @@ -207,8 +198,7 @@ void bnfaPrintInfo(bnfa_struct_t* pstruct); /* print info on this search engi * */ void bnfaPrintInfoEx(bnfa_struct_t* p, const char* text); -void bnfaAccumInfo(bnfa_struct_t* pstruct); /* add info to summary over multiple search engines - */ +void bnfaAccumInfo(bnfa_struct_t* pstruct); // add info to summary over multiple search engines void bnfaPrintSummary(void); /* print current summary */ void bnfaInitSummary(void); /* reset accumulator foir global summary over multiple engines */ void bnfa_print_qinfo(void); diff --git a/src/search_engines/dev_notes.txt b/src/search_engines/dev_notes.txt new file mode 100644 index 000000000..836a35be3 --- /dev/null +++ b/src/search_engines/dev_notes.txt @@ -0,0 +1,39 @@ +Builtin fast pattern matching algorithms are implemented here. + +MPSE = multi-pattern search engine +DFA = deterministic finite automaton +NFA = non-DFA + +This code has has evolved through 3 major versions: + +1. acsmx.cc: ac_std +2. acsmx2.cc: ac_full, ac_full_q, ac_sparse, ac_banded, ac_sparse_bands +3. bnfa_search.cc: ac_bnfa, ac_bnfa_q + +Check the comments at the start of the above files for details on the +implementation. + +Version 1 and 2 flavors are all DFAs. Version 3 flavors are NFAs. The +TRIE based implementations were moved to extras. + +NFAs require much less memory than DFAs, but DFAs are faster. The multiple +DFA flavors try to reduce memory for transition storage by various schemes: + +* full - an array of 256 transitions for each state indexed by event (byte) +* sparse - a list of valid transitions (which must be searched) +* banded - like full except that the leading and trailing invalid + transitions are not stored +* sparse bands - a list of bands + +The *_q flavors use a match queue to defer rule tree evaluation until after +the full buffer is searched in order to keep the cache warm. This aspect +should be orthogonal such that any method can be used with or w/o a match +queue. + +SearchTool makes it easy to use ac_bnfa. This is used by http, pop, imap, +and smtp. + +Reference - Efficient String matching: An Aid to Bibliographic Search +Alfred V Aho and Margaret J Corasick, Bell Laboratories +Copyright (C) 1975 Association for Computing Machinery,Inc + diff --git a/src/search_engines/intel_cpm.cc b/src/search_engines/intel_cpm.cc index ff536faf2..87579ebe4 100644 --- a/src/search_engines/intel_cpm.cc +++ b/src/search_engines/intel_cpm.cc @@ -75,17 +75,17 @@ public: } int prep_patterns( - SnortConfig* sc, mpse_build_f build_tree, mpse_negate_f neg_list) override + SnortConfig* sc, MpseBuild build_tree, MpseNegate neg_list) override { return IntelPmFinishGroup(sc, obj, build_tree, neg_list); } int _search( - const unsigned char* T, int n, mpse_action_f action, + const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) override { *current_state = 0; - return IntelPmSearch((IntelPm*)p->obj, (unsigned char*)T, n, action, data); + return IntelPmSearch((IntelPm*)p->obj, (unsigned char*)T, n, match, data); } int get_pattern_count() override diff --git a/src/search_engines/intel_soft_cpm.cc b/src/search_engines/intel_soft_cpm.cc index db8956463..2a5ce7c9a 100644 --- a/src/search_engines/intel_soft_cpm.cc +++ b/src/search_engines/intel_soft_cpm.cc @@ -367,10 +367,7 @@ int IntelPmAddPattern( } int IntelPmFinishGroup( - SnortConfig* sc, - IntelPm* ipm, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)) + SnortConfig* sc, IntelPm* ipm, MpseBuild build_tree, MpseNegate net_list_func) { Cpa32U sessionCtxSize; CpaPmSessionProperty sessionProperty; diff --git a/src/search_engines/intel_soft_cpm.h b/src/search_engines/intel_soft_cpm.h index 0fbe5da3f..ad8a92e8d 100644 --- a/src/search_engines/intel_soft_cpm.h +++ b/src/search_engines/intel_soft_cpm.h @@ -20,12 +20,13 @@ #ifndef INTEL_SOFT_CPM_H #define INTEL_SOFT_CPM_H -#include "cpa.h" -#include "pm/cpa_pm.h" -#include "cpa_types.h" -#include "snort_debug.h" +#include +#include +#include + +#include "main/snort_debug.h" +#include "search_common.h" -/* DATA TYPES *****************************************************************/ typedef struct _IntelPmPattern { void* user_data; @@ -41,7 +42,7 @@ typedef struct _IntelPmPattern } IntelPmPattern; struct SnortConfig; -struct _IntelPmHandles; + typedef struct _IntelPm { Cpa16U patternGroupId; @@ -49,14 +50,14 @@ typedef struct _IntelPm CpaPmSessionCtx sessionCtx; /* Temporary data for building trees */ - int (* build_tree)(SnortConfig*, void* id, void** existing_tree); - int (* neg_list_func)(void* id, void** list); + MpseBuild build_tree; + MpseNegate neg_list_func; void* match_queue; /* Temporary data for match callback */ void* data; - MpseCallback match; + MpseMatch match; void (* user_free)(void*); void (* option_tree_free)(void**); @@ -69,7 +70,6 @@ typedef struct _IntelPm struct _IntelPmHandles* handles; } IntelPm; -/* PROTOTYPES *****************************************************************/ void IntelPmStartInstance(void); void IntelPmStopInstance(void); @@ -79,7 +79,7 @@ void* IntelPmNew( void (* option_tree_free)(void** p), void (* neg_list_free)(void** p)); -void IntelPmDelete(IntelPm* ipm); +void IntelPmDelete(IntelPm*); int IntelPmAddPattern( SnortConfig* sc, @@ -92,23 +92,20 @@ int IntelPmAddPattern( int pat_id); int IntelPmFinishGroup( - SnortConfig*, - IntelPm* ipm, - int (* build_tree)(SnortConfig*, void* id, void** existing_tree), - int (* neg_list_func)(void* id, void** list)); + SnortConfig*, IntelPm*, MpseBuild, MpseNegate); void IntelPmCompile(SnortConfig*); void IntelPmActivate(SnortConfig*); void IntelPmDeactivate(void); int IntelPmSearch( -IntelPm *ipm, unsigned char* buffer, int buffer_len, MpseCallback, void* data); + IntelPm*, unsigned char* buffer, int buffer_len, MpseMatch, void* data); -int IntelGetPatternCount(IntelPm* ipm); -int IntelPmPrintInfo(IntelPm* ipm); +int IntelGetPatternCount(IntelPm*); +int IntelPmPrintInfo(IntelPm*); void IntelPmPrintSummary(SnortConfig*); void IntelPmPrintBufferStats(void); int IntelPmRelease(struct _IntelPmHandles*); -#endif /* INTEL_SOFT_CPM_H */ +#endif diff --git a/src/search_engines/search_common.h b/src/search_engines/search_common.h index e2f00fa5c..7c0d4533c 100644 --- a/src/search_engines/search_common.h +++ b/src/search_engines/search_common.h @@ -19,7 +19,9 @@ #ifndef SEARCH_COMMON_H #define SEARCH_COMMON_H -typedef int (* MpseCallback)(void* id, void* tree, int index, void* data, void* neg_list); +typedef int (* MpseBuild)(struct SnortConfig*, void* id, void** existing_tree); +typedef int (* MpseNegate)(void* id, void** list); +typedef int (* MpseMatch)(void* id, void* tree, int index, void* data, void* neg_list); #endif diff --git a/src/search_engines/search_engines.cc b/src/search_engines/search_engines.cc index 329f11065..966beb53c 100644 --- a/src/search_engines/search_engines.cc +++ b/src/search_engines/search_engines.cc @@ -21,7 +21,21 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "framework/mpse.h" + +struct BaseApi; + +extern const BaseApi* se_ac_banded; +extern const BaseApi* se_ac_bnfa; +extern const BaseApi* se_ac_bnfa_q; +extern const BaseApi* se_ac_full; +extern const BaseApi* se_ac_full_q; +extern const BaseApi* se_ac_sparse; +extern const BaseApi* se_ac_sparse_bands; +extern const BaseApi* se_ac_std; + +#ifdef INTEL_SOFT_CPM +extern const BaseApi* se_intel_cpm; +#endif const BaseApi* search_engines[] = { diff --git a/src/search_engines/search_engines.h b/src/search_engines/search_engines.h index 3264ba676..f2c65363c 100644 --- a/src/search_engines/search_engines.h +++ b/src/search_engines/search_engines.h @@ -19,26 +19,7 @@ #ifndef SEARCH_ENGINES_H #define SEARCH_ENGINES_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -struct BaseApi; - -extern const BaseApi* se_ac_banded; -extern const BaseApi* se_ac_bnfa; -extern const BaseApi* se_ac_bnfa_q; -extern const BaseApi* se_ac_full; -extern const BaseApi* se_ac_full_q; -extern const BaseApi* se_ac_sparse; -extern const BaseApi* se_ac_sparse_bands; -extern const BaseApi* se_ac_std; - -#ifdef INTEL_SOFT_CPM -extern const BaseApi* se_intel_cpm; -#endif - -extern const BaseApi* search_engines[]; +extern const struct BaseApi* search_engines[]; #endif diff --git a/src/search_engines/search_tool.cc b/src/search_engines/search_tool.cc index 9c0d17aa1..7e485221d 100644 --- a/src/search_engines/search_tool.cc +++ b/src/search_engines/search_tool.cc @@ -62,7 +62,7 @@ void SearchTool::prep() int SearchTool::find( const char* str, unsigned len, - mpse_action_f mf, + MpseMatch mf, int& state, bool confine, void* user_data) @@ -84,7 +84,7 @@ int SearchTool::find( int SearchTool::find( const char* str, unsigned len, - mpse_action_f mf, + MpseMatch mf, bool confine, void* user_data) { @@ -95,7 +95,7 @@ int SearchTool::find( int SearchTool::find_all( const char* str, unsigned len, - mpse_action_f mf, + MpseMatch mf, bool confine, void* user_data) { diff --git a/src/search_engines/search_tool.h b/src/search_engines/search_tool.h index 529b5ac87..e7f851e78 100644 --- a/src/search_engines/search_tool.h +++ b/src/search_engines/search_tool.h @@ -34,13 +34,13 @@ public: void prep(); // set state to zero on first call - int find(const char* s, unsigned s_len, mpse_action_f, int& state, + int find(const char* s, unsigned s_len, MpseMatch, int& state, bool confine = false, void* user_data = nullptr); - int find(const char* s, unsigned s_len, mpse_action_f, + int find(const char* s, unsigned s_len, MpseMatch, bool confine = false, void* user_data = nullptr); - int find_all(const char* s, unsigned s_len, mpse_action_f, + int find_all(const char* s, unsigned s_len, MpseMatch, bool confine = false, void* user_data = nullptr); private: diff --git a/src/service_inspectors/back_orifice/dev_notes.txt b/src/service_inspectors/back_orifice/dev_notes.txt new file mode 100644 index 000000000..dd50b2f11 --- /dev/null +++ b/src/service_inspectors/back_orifice/dev_notes.txt @@ -0,0 +1,7 @@ +Detects Back Orifice traffic by brute forcing the weak encryption +of the program's network protocol and detects the magic cookie +that it's servers and clients require to communicate with each +other. + +See also: https://en.wikipedia.org/wiki/Back_Orifice + diff --git a/src/service_inspectors/dev_notes.txt b/src/service_inspectors/dev_notes.txt new file mode 100644 index 000000000..07ff45bf3 --- /dev/null +++ b/src/service_inspectors/dev_notes.txt @@ -0,0 +1,15 @@ +Service inspectors are the modules that process individual upper-level +protocols such as FTP, Telnet, SMTP, and HTTP. + +Service inspectors are often subdivided into two classes. The stream +splitter accepts a stream of protocol data from the transport layer and +segments it at the PDU boundaries. The inspector processes the resulting +PDUs. + +The wizard is a special service inspector that examines the beginning of a +data stream and decides what application protocol is present. + +http_inspect is the legacy Snort HTTP preprocessor ported to Snort\++ . +nhttp_inspect is the complete rewrite being developed specifically for +Snort++. + diff --git a/src/service_inspectors/dns/dev_notes.txt b/src/service_inspectors/dns/dev_notes.txt new file mode 100644 index 000000000..d7d83f11e --- /dev/null +++ b/src/service_inspectors/dns/dev_notes.txt @@ -0,0 +1,6 @@ +The DNS inspector decodes DNS Responses in DNS PDUs and can detect the +following exploits: DNS Client RData Overflow, Obsolete Record Types, and +Experimental Record Types. + +DNS looks are DNS Response traffic over UDP and TCP and it requires Stream +inspector to be enabled for TCP decoding. diff --git a/src/service_inspectors/dns/dns.cc b/src/service_inspectors/dns/dns.cc index 6f9f3301b..e8b3e1714 100644 --- a/src/service_inspectors/dns/dns.cc +++ b/src/service_inspectors/dns/dns.cc @@ -16,20 +16,11 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * DNS preprocessor - * Author: Chris Sherwin - * Contributors: Adam Keeton, Ryan Jordan - * - * - * Alert for Gobbles, CRC32, protocol mismatch (Cisco catalyst vulnerability), - * and a SecureCRT vulnerability. Will also alert if the client or server - * traffic appears to flow the wrong direction, or if packets appear - * malformed/spoofed. - * - */ +// dns.cc author Steven Sturges +// Alert for DNS client rdata buffer overflow. +// Alert for Obsolete or Experimental RData types (per RFC 1035) + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/service_inspectors/dns/dns.h b/src/service_inspectors/dns/dns.h index 11a6dc2d8..a8c0df9f6 100644 --- a/src/service_inspectors/dns/dns.h +++ b/src/service_inspectors/dns/dns.h @@ -16,29 +16,24 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * dns.h: Definitions, structs, function prototype(s) for - * the DNS service inspectors. - * Author: Chris Sherwin - */ +// dns.h author Steven Sturges #ifndef DNS_H #define DNS_H #include "protocols/packet.h" #include "stream/stream_api.h" -#include "profiler.h" +#include "time/profiler.h" + +// Implementation header with definitions, datatypes and flowdata class for +// DNS service inspector. -/* - * Directional defines - */ +// Directional defines #define DNS_DIR_FROM_SERVER 1 #define DNS_DIR_FROM_CLIENT 2 -/****** A few data structures ******/ -typedef struct _DNSHdr +struct DNSHdr { uint16_t id; uint16_t flags; @@ -46,7 +41,7 @@ typedef struct _DNSHdr uint16_t answers; uint16_t authorities; uint16_t additionals; -} DNSHdr; +}; #define DNS_HDR_FLAG_REPLY_CODE_MASK 0x000F #define DNS_HDR_FLAG_NON_AUTHENTICATED_OK 0x0010 @@ -59,21 +54,22 @@ typedef struct _DNSHdr #define DNS_HDR_FLAG_OPCODE_MASK 0x7800 #define DNS_HDR_FLAG_RESPONSE 0x8000 -typedef struct _DNSQuestion +struct DNSQuestion { uint16_t type; uint16_t dns_class; -} DNSQuestion; +}; -typedef struct _DNSRR +struct DNSRR { uint16_t type; uint16_t dns_class; uint32_t ttl; uint16_t length; -} DNSRR; +}; -typedef struct _DNSNameState +// FIXIT-L replace alerted/relative to bool? +struct DNSNameState { uint32_t txt_count; uint32_t total_txt_len; @@ -83,98 +79,89 @@ typedef struct _DNSNameState uint8_t alerted; uint16_t offset; uint8_t relative; -} DNSNameState; +}; +// FIXIT-L remove obsolete flags? #define DNS_RR_TYPE_A 0x0001 #define DNS_RR_TYPE_NS 0x0002 -#define DNS_RR_TYPE_MD 0x0003 /* obsolete */ -#define DNS_RR_TYPE_MF 0x0004 /* obsolete */ +#define DNS_RR_TYPE_MD 0x0003 // obsolete +#define DNS_RR_TYPE_MF 0x0004 // obsolete #define DNS_RR_TYPE_CNAME 0x0005 #define DNS_RR_TYPE_SOA 0x0006 -#define DNS_RR_TYPE_MB 0x0007 /* experimental */ -#define DNS_RR_TYPE_MG 0x0008 /* experimental */ -#define DNS_RR_TYPE_MR 0x0009 /* experimental */ -#define DNS_RR_TYPE_NULL 0x000a /* experimental */ +#define DNS_RR_TYPE_MB 0x0007 // experimental +#define DNS_RR_TYPE_MG 0x0008 // experimental +#define DNS_RR_TYPE_MR 0x0009 // experimental +#define DNS_RR_TYPE_NULL 0x000a // experimental #define DNS_RR_TYPE_WKS 0x000b #define DNS_RR_TYPE_PTR 0x000c #define DNS_RR_TYPE_HINFO 0x000d -#define DNS_RR_TYPE_MINFO 0x000e /* experimental */ +#define DNS_RR_TYPE_MINFO 0x000e // experimental #define DNS_RR_TYPE_MX 0x000f #define DNS_RR_TYPE_TXT 0x0010 #define DNS_FLAG_NOT_DNS 0x01 -/* DNSSessionData States */ -#define DNS_RESP_STATE_LENGTH 0x00 /* 2 bytes - TCP only*/ -#define DNS_RESP_STATE_LENGTH_PART 0x01 /* Partial length */ - -#define DNS_RESP_STATE_HDR 0x10 /* 12 bytes */ -#define DNS_RESP_STATE_HDR_ID 0x11 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_ID_PART 0x12 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_FLAGS 0x13 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_FLAGS_PART 0x14 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_QS 0x15 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_QS_PART 0x16 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_ANSS 0x17 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_ANSS_PART 0x18 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_AUTHS 0x19 /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_AUTHS_PART 0x1a /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_ADDS 0x1b /* (2 bytes) */ -#define DNS_RESP_STATE_HDR_ADDS_PART 0x1c /* (2 bytes) */ - -#define DNS_RESP_STATE_QUESTION 0x20 /* 4 bytes */ -#define DNS_RESP_STATE_Q_NAME 0x21 /* (size depends on data) */ -#define DNS_RESP_STATE_Q_NAME_COMPLETE 0x22 /* (size depends on data) */ -#define DNS_RESP_STATE_Q_TYPE 0x23 /* (2 bytes) */ -#define DNS_RESP_STATE_Q_TYPE_PART 0x24 /* (2 bytes) */ -#define DNS_RESP_STATE_Q_CLASS 0x25 /* (2 bytes) */ -#define DNS_RESP_STATE_Q_CLASS_PART 0x26 /* (2 bytes) */ +// DNSSessionData States +#define DNS_RESP_STATE_LENGTH 0x00 // 2 bytes - TCP only +#define DNS_RESP_STATE_LENGTH_PART 0x01 // Partial length + +#define DNS_RESP_STATE_HDR 0x10 // 12 bytes +#define DNS_RESP_STATE_HDR_ID 0x11 // (2 bytes) +#define DNS_RESP_STATE_HDR_ID_PART 0x12 // (2 bytes) +#define DNS_RESP_STATE_HDR_FLAGS 0x13 // (2 bytes) +#define DNS_RESP_STATE_HDR_FLAGS_PART 0x14 // (2 bytes) +#define DNS_RESP_STATE_HDR_QS 0x15 // (2 bytes) +#define DNS_RESP_STATE_HDR_QS_PART 0x16 // (2 bytes) +#define DNS_RESP_STATE_HDR_ANSS 0x17 // (2 bytes) +#define DNS_RESP_STATE_HDR_ANSS_PART 0x18 // (2 bytes) +#define DNS_RESP_STATE_HDR_AUTHS 0x19 // (2 bytes) +#define DNS_RESP_STATE_HDR_AUTHS_PART 0x1a // (2 bytes) +#define DNS_RESP_STATE_HDR_ADDS 0x1b // (2 bytes) +#define DNS_RESP_STATE_HDR_ADDS_PART 0x1c // (2 bytes) + +#define DNS_RESP_STATE_QUESTION 0x20 // 4 bytes +#define DNS_RESP_STATE_Q_NAME 0x21 // (size depends on data) +#define DNS_RESP_STATE_Q_NAME_COMPLETE 0x22 // (size depends on data) +#define DNS_RESP_STATE_Q_TYPE 0x23 // (2 bytes) +#define DNS_RESP_STATE_Q_TYPE_PART 0x24 // (2 bytes) +#define DNS_RESP_STATE_Q_CLASS 0x25 // (2 bytes) +#define DNS_RESP_STATE_Q_CLASS_PART 0x26 // (2 bytes) #define DNS_RESP_STATE_Q_COMPLETE 0x27 -#define DNS_RESP_STATE_NAME_SIZE 0x31 /* (1 byte) */ -#define DNS_RESP_STATE_NAME 0x32 /* (size depends on field) */ +#define DNS_RESP_STATE_NAME_SIZE 0x31 // (1 byte) +#define DNS_RESP_STATE_NAME 0x32 // (size depends on field) #define DNS_RESP_STATE_NAME_COMPLETE 0x33 -#define DNS_RESP_STATE_ANS_RR 0x40 /* (size depends on field) */ -#define DNS_RESP_STATE_RR_NAME_SIZE 0x41 /* (1 byte) */ -#define DNS_RESP_STATE_RR_NAME 0x42 /* (size depends on field) */ +#define DNS_RESP_STATE_ANS_RR 0x40 // (size depends on field) +#define DNS_RESP_STATE_RR_NAME_SIZE 0x41 // (1 byte) +#define DNS_RESP_STATE_RR_NAME 0x42 // (size depends on field) #define DNS_RESP_STATE_RR_NAME_COMPLETE 0x43 -#define DNS_RESP_STATE_RR_TYPE 0x44 /* (2 bytes) */ -#define DNS_RESP_STATE_RR_TYPE_PART 0x45 /* (2 bytes) */ -#define DNS_RESP_STATE_RR_CLASS 0x46 /* (2 bytes) */ -#define DNS_RESP_STATE_RR_CLASS_PART 0x47 /* (2 bytes) */ -#define DNS_RESP_STATE_RR_TTL 0x48 /* (4 bytes) */ -#define DNS_RESP_STATE_RR_TTL_PART 0x49 /* (4 bytes) */ -#define DNS_RESP_STATE_RR_RDLENGTH 0x4a /* (2 bytes) */ -#define DNS_RESP_STATE_RR_RDLENGTH_PART 0x4b /* (2 bytes) */ -#define DNS_RESP_STATE_RR_RDATA_START 0x4c /* (size depends on RDLENGTH) */ -#define DNS_RESP_STATE_RR_RDATA_MID 0x4d /* (size depends on RDLENGTH) */ +#define DNS_RESP_STATE_RR_TYPE 0x44 // (2 bytes) +#define DNS_RESP_STATE_RR_TYPE_PART 0x45 // (2 bytes) +#define DNS_RESP_STATE_RR_CLASS 0x46 // (2 bytes) +#define DNS_RESP_STATE_RR_CLASS_PART 0x47 // (2 bytes) +#define DNS_RESP_STATE_RR_TTL 0x48 // (4 bytes) +#define DNS_RESP_STATE_RR_TTL_PART 0x49 // (4 bytes) +#define DNS_RESP_STATE_RR_RDLENGTH 0x4a // (2 bytes) +#define DNS_RESP_STATE_RR_RDLENGTH_PART 0x4b // (2 bytes) +#define DNS_RESP_STATE_RR_RDATA_START 0x4c // (size depends on RDLENGTH) +#define DNS_RESP_STATE_RR_RDATA_MID 0x4d // (size depends on RDLENGTH) #define DNS_RESP_STATE_RR_COMPLETE 0x4e #define DNS_RESP_STATE_AUTH_RR 0x50 #define DNS_RESP_STATE_ADD_RR 0x60 -/* - * Per-session data block containing current state - * of the DNS preprocessor for the session. - * - * state: The current state of the session. - * num_records: Number of records in the session. - * curr_record: Record number for the current record - * curr_record_length: Current record length. - * total_record_length: Total data length of records. - * length: Total length of DNS response (TCP only) - * hdr: Copy of the data from the DNS Header - */ +// Per-session data block containing current state +// of the DNS preprocessor for the session. struct DNSData { - uint32_t state; - uint16_t curr_rec; + uint32_t state; // The current state of the session. + uint16_t curr_rec; // Record number for the current record uint16_t curr_rec_length; uint16_t bytes_seen_curr_rec; uint16_t length; uint8_t curr_rec_state; - DNSHdr hdr; + DNSHdr hdr; // Copy of the data from the DNS Header DNSQuestion curr_q; DNSRR curr_rr; DNSNameState curr_txt; @@ -197,5 +184,5 @@ public: DNSData session; }; -#endif /* DNS_H */ +#endif diff --git a/src/service_inspectors/dns/dns_module.h b/src/service_inspectors/dns/dns_module.h index 7edba8d2a..387c9ebe4 100644 --- a/src/service_inspectors/dns/dns_module.h +++ b/src/service_inspectors/dns/dns_module.h @@ -20,6 +20,7 @@ #ifndef DNS_MODULE_H #define DNS_MODULE_H +//Interface to the DNS service inspector #include "framework/module.h" #include "framework/bits.h" @@ -57,4 +58,3 @@ public: }; #endif - diff --git a/src/service_inspectors/ftp_telnet/dev_notes.txt b/src/service_inspectors/ftp_telnet/dev_notes.txt new file mode 100644 index 000000000..8686057fa --- /dev/null +++ b/src/service_inspectors/ftp_telnet/dev_notes.txt @@ -0,0 +1,7 @@ +Telnet, FTP, and FTP-Data service inspectors. Telnet and FTP are normal +inspectors, FTP-Data detected from the FTP control channel and used primarily +for file processing. + +FTP and Telnet inspectors share implementation because FTP uses a +Telnet-based control channel. + diff --git a/src/service_inspectors/ftp_telnet/ft_main.h b/src/service_inspectors/ftp_telnet/ft_main.h index db8fd99ff..3ac9e8c2d 100644 --- a/src/service_inspectors/ftp_telnet/ft_main.h +++ b/src/service_inspectors/ftp_telnet/ft_main.h @@ -32,6 +32,10 @@ #ifndef FT_MAIN_H #define FT_MAIN_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ftpp_ui_config.h" #include "protocols/packet.h" #include "framework/bits.h" diff --git a/src/service_inspectors/ftp_telnet/ftp_client.h b/src/service_inspectors/ftp_telnet/ftp_client.h index bee1117d6..d1ad5b2db 100644 --- a/src/service_inspectors/ftp_telnet/ftp_client.h +++ b/src/service_inspectors/ftp_telnet/ftp_client.h @@ -16,30 +16,24 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- + +// ftp_client.h author Steven A. Sturges + +// contributors: +// Daniel J. Roelker +// Marc A. Norton + +#ifndef FTP_CLIENT_H +#define FTP_CLIENT_H + /* - * Description: - * - * Header file for FTPTelnet FTP Client Module + * FTP Client Module * * This file defines the client reqest structure and functions * to access client inspection. - * - * NOTES: - * - 16.09.04: Initial Development. SAS - * - * Steven A. Sturges - * Daniel J. Roelker - * Marc A. Norton */ -#ifndef FTP_CLIENT_H -#define FTP_CLIENT_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include - #include "ftpp_include.h" struct FTP_CLIENT_REQ diff --git a/src/service_inspectors/ftp_telnet/ftp_server.h b/src/service_inspectors/ftp_telnet/ftp_server.h index 0d6e9a905..e421ed824 100644 --- a/src/service_inspectors/ftp_telnet/ftp_server.h +++ b/src/service_inspectors/ftp_telnet/ftp_server.h @@ -16,23 +16,22 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- + +// ftp_server.h author Steven A. Sturges + +// contributors: +// Daniel J. Roelker +// Marc A. Norton + +#ifndef FTP_SERVER_H +#define FTP_SERVER_H + /* - * Description: - * - * Header file for FTPTelnet FTP Server Module + * FTP Server Module * * This file defines the server structure and functions to access server * inspection. - * - * NOTES: - * - 16.09.04: Initial Development. SAS - * - * Steven A. Sturges - * Daniel J. Roelker - * Marc A. Norton */ -#ifndef FTP_SERVER_H -#define FTP_SERVER_H #include "ftpp_include.h" diff --git a/src/service_inspectors/ftp_telnet/ftpp_include.h b/src/service_inspectors/ftp_telnet/ftpp_include.h index a32b1d888..d81e3465e 100644 --- a/src/service_inspectors/ftp_telnet/ftpp_include.h +++ b/src/service_inspectors/ftp_telnet/ftpp_include.h @@ -31,9 +31,9 @@ #ifndef FTPP_INCLUDE_H #define FTPP_INCLUDE_H -#include "snort_types.h" -#include "sf_ip.h" -#include "snort_debug.h" +#include "main/snort_types.h" +#include "main/snort_debug.h" +#include "sfip/sf_ip.h" #include "protocols/packet.h" #define GENERATOR_SPP_FTPP_FTP 125 diff --git a/src/service_inspectors/ftp_telnet/ftpp_ui_config.h b/src/service_inspectors/ftp_telnet/ftpp_ui_config.h index 277d81d3c..5b4dcd47b 100644 --- a/src/service_inspectors/ftp_telnet/ftpp_ui_config.h +++ b/src/service_inspectors/ftp_telnet/ftpp_ui_config.h @@ -40,10 +40,10 @@ #include "ftpp_include.h" #include "hi_util_kmap.h" -#include "sfrt/sfrt.h" -#include "snort_bounds.h" #include "framework/bits.h" #include "sfip/sfip_t.h" +#include "sfrt/sfrt.h" +#include "utils/snort_bounds.h" /* * Defines diff --git a/src/service_inspectors/ftp_telnet/ftpp_util_kmap.h b/src/service_inspectors/ftp_telnet/ftpp_util_kmap.h index 46e464e70..3bd690a9d 100644 --- a/src/service_inspectors/ftp_telnet/ftpp_util_kmap.h +++ b/src/service_inspectors/ftp_telnet/ftpp_util_kmap.h @@ -16,9 +16,8 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * Author: Marc A Norton - */ + +// ftpp_util_kmap.h author Marc A Norton #ifndef FTPP_UTIL_KMAP_H #define FTPP_UTIL_KMAP_H diff --git a/src/service_inspectors/ftp_telnet/hi_util_kmap.cc b/src/service_inspectors/ftp_telnet/hi_util_kmap.cc index 28a59c552..5cef622ec 100644 --- a/src/service_inspectors/ftp_telnet/hi_util_kmap.cc +++ b/src/service_inspectors/ftp_telnet/hi_util_kmap.cc @@ -17,27 +17,9 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -* -* kmap.c - a generic map library - maps key + data pairs -* -* Uses Lexical Keyword Trie -* The tree uses linked lists to build the finite automata -* -* MapKeyFind(): Performs a setwise strcmp() equivalant. -* -* Notes: -* -* Keys may be ascii or binary, both may be of random sizes. -* Each key may be a different size, or all one size. -* Fast dictionary lookup, proportional to the length of the key, -* and independent of the number of keys in the table. -* May use more memory than a hash table, depends. -* Memory is allocated as needed, so none is wasted. -* -* Author: Marc Norton -* -*/ +// hi_util_kmap.cc author Marc Norton +// a generic map library - maps key + data pairs + #include "hi_util_kmap.h" #ifdef HAVE_CONFIG_H diff --git a/src/service_inspectors/ftp_telnet/hi_util_kmap.h b/src/service_inspectors/ftp_telnet/hi_util_kmap.h index 2986d42df..fbd25edf7 100644 --- a/src/service_inspectors/ftp_telnet/hi_util_kmap.h +++ b/src/service_inspectors/ftp_telnet/hi_util_kmap.h @@ -17,18 +17,23 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -* kmap.h -* -* Keyword Trie based Map Table -* -* Author: Marc Norton -* -*/ +// hi_util_kmap.h author Marc Norton #ifndef HI_UTIL_KMAP_H #define HI_UTIL_KMAP_H + // FIXIT-L this is a dup of the file in http_inspect +// +// Keyword Trie based Map Table +// The tree uses linked lists to build the finite automata +// +// MapKeyFind(): Performs a setwise strcmp() equivalant. +// +// Keys may be ascii or binary, both may be of random sizes. Each key may +// be a different size, or all one size. Fast dictionary lookup, +// proportional to the length of the key, and independent of the number of +// keys in the table. May use more memory than a hash table, depends. +// Memory is allocated as needed, so none is wasted. #define ALPHABET_SIZE 256 diff --git a/src/service_inspectors/ftp_telnet/hi_util_xmalloc.h b/src/service_inspectors/ftp_telnet/hi_util_xmalloc.h index 63d27fae7..a3b7f3d7b 100644 --- a/src/service_inspectors/ftp_telnet/hi_util_xmalloc.h +++ b/src/service_inspectors/ftp_telnet/hi_util_xmalloc.h @@ -19,6 +19,7 @@ #ifndef HI_UTIL_XMALLOC_H #define HI_UTIL_XMALLOC_H + // FIXIT-L this is a dup of the file in http_inspect #include diff --git a/src/service_inspectors/ftp_telnet/pp_ftp.h b/src/service_inspectors/ftp_telnet/pp_ftp.h index 36f399a9c..d71d7537e 100644 --- a/src/service_inspectors/ftp_telnet/pp_ftp.h +++ b/src/service_inspectors/ftp_telnet/pp_ftp.h @@ -16,28 +16,16 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * Description: - * - * Header file for FTPTelnet FTP Module - * - * This file defines the ftp checking functions - * - * NOTES: - * - 20.09.04: Initial Development. SAS - * - * Steven A. Sturges - */ + +// pp_ftp.h author Steven A. Sturges + #ifndef PP_FTP_H #define PP_FTP_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// declares the ftp checking functions #include -//#include "protocols/packet.h" #include "ftpp_ui_config.h" #include "ftpp_si.h" diff --git a/src/service_inspectors/ftp_telnet/pp_telnet.h b/src/service_inspectors/ftp_telnet/pp_telnet.h index 8e3001d97..c9486b2db 100644 --- a/src/service_inspectors/ftp_telnet/pp_telnet.h +++ b/src/service_inspectors/ftp_telnet/pp_telnet.h @@ -16,21 +16,14 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * Description: - * - * Header file for FTPTelnet telnet Module - * - * This file defines the telnet checking functions - * - * NOTES: - * - 20.09.04: Initial Development. SAS - * - * Steven A. Sturges - */ + +// pp_telnet.h author Steven A. Sturges + #ifndef PP_TELNET_H #define PP_TELNET_H +// declares the telnet checking functions + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -42,7 +35,6 @@ /* RFC 1184 defines Abort, Suspend, and End of File telnet optinos */ #define RFC1184 -//#include "protocols/packet.h" #include "ftpp_ui_config.h" #include "ftpp_si.h" diff --git a/src/service_inspectors/http_inspect/CMakeLists.txt b/src/service_inspectors/http_inspect/CMakeLists.txt index fa691b82d..d787f27e0 100644 --- a/src/service_inspectors/http_inspect/CMakeLists.txt +++ b/src/service_inspectors/http_inspect/CMakeLists.txt @@ -3,41 +3,42 @@ set (FILE_LIST http_inspect.cc hi_main.cc hi_main.h - hi_ad.cc + hi_ad.cc hi_ad.h - hi_client.cc + hi_client.cc hi_client.h - hi_client_norm.cc + hi_client_norm.cc hi_client_norm.h - hi_cmd_lookup.cc + hi_cmd_lookup.cc hi_cmd_lookup.h + hi_events.cc + hi_events.h hi_include.h - hi_mi.cc + hi_mi.cc hi_mi.h - hi_norm.cc + hi_norm.cc hi_norm.h - hi_paf.cc - hi_paf.h - hi_events.cc - hi_events.h hi_module.cc hi_module.h hi_reqmethod_check.h hi_return_codes.h - hi_server.cc + hi_server.cc hi_server.h - hi_server_norm.cc + hi_server_norm.cc hi_server_norm.h - hi_si.cc hi_si.h + hi_si.cc + hi_si.h hi_stateful_inspect.h - hi_ui_config.cc + hi_stream_splitter.cc + hi_stream_splitter.h + hi_ui_config.cc hi_ui_config.h - hi_ui_iis_unicode_map.cc + hi_ui_iis_unicode_map.cc hi_ui_iis_unicode_map.h hi_util.h - hi_util_kmap.cc + hi_util_kmap.cc hi_util_kmap.h - hi_util_xmalloc.cc + hi_util_xmalloc.cc hi_util_xmalloc.h ) diff --git a/src/service_inspectors/http_inspect/Makefile.am b/src/service_inspectors/http_inspect/Makefile.am index 96800f4ea..7367b6dc2 100644 --- a/src/service_inspectors/http_inspect/Makefile.am +++ b/src/service_inspectors/http_inspect/Makefile.am @@ -12,13 +12,13 @@ hi_include.h \ hi_mi.cc hi_mi.h \ hi_module.cc hi_module.h \ hi_norm.cc hi_norm.h \ -hi_paf.cc hi_paf.h \ hi_reqmethod_check.h \ hi_return_codes.h \ hi_server.cc hi_server.h \ hi_server_norm.cc hi_server_norm.h \ hi_si.cc hi_si.h \ hi_stateful_inspect.h \ +hi_stream_splitter.cc hi_stream_splitter.h \ hi_ui_config.cc hi_ui_config.h \ hi_ui_iis_unicode_map.cc hi_ui_iis_unicode_map.h \ hi_util.h \ diff --git a/src/service_inspectors/http_inspect/dev_notes.txt b/src/service_inspectors/http_inspect/dev_notes.txt new file mode 100644 index 000000000..844c8d06b --- /dev/null +++ b/src/service_inspectors/http_inspect/dev_notes.txt @@ -0,0 +1,24 @@ +This is the old Snort HTTP preprocessor ported to Snort++ and made into an +inspector. A new HTTP inspector currently known as NHttpInspect is under +development in a neighboring directory. Eventually NHttpInspect will be +renamed HttpInspect and this module will be retired. Meanwhile the +abbreviations HI and NHI are sometimes used when it is important to +distinguish the two modules. + +HI and NHI are not intended to be used together. Only configure one of them +at a time. + +The starting point is http_inspect.cc which defines the HttpInspect +subclass of Inspector. Within that look to member eval() which accepts a +packet from the framework and processes it. + +HI evolved from a stateless packet processor and to a very substantial +extent it still is one despite having a fully-developed stream splitter. +That means it often does not know for sure what part of the HTTP message it +is looking at and it makes great effort to try and overcome that. Always +keep this in mind when trying to understand what HI is doing. + +The other useful thing to remember is HI processes request ("client") and +response ("server") messages through largely separate code paths and far +more differently than you would expect from reading the RFC. + diff --git a/src/service_inspectors/http_inspect/hi_client.cc b/src/service_inspectors/http_inspect/hi_client.cc index 90a627165..25b4a66f9 100644 --- a/src/service_inspectors/http_inspect/hi_client.cc +++ b/src/service_inspectors/http_inspect/hi_client.cc @@ -1331,7 +1331,7 @@ int SetProxy(HI_SESSION* session, const u_char* start, { if (session->global_conf->proxy_alert && !ServerConf->allow_proxy) uri_ptr->proxy = *ptr; - //If we found :// check to see if it is preceeded by http. If so, this is a proxy + // If we found :// check to see if it is preceeded by http. If so, this is a proxy proxy_start = (u_char*)SnortStrcasestr((const char*)uri_ptr->uri, (*ptr - uri_ptr->uri), "http"); proxy_end = end; @@ -2306,7 +2306,7 @@ static inline const u_char* extractHeaderFieldValues(HI_SESSION* session, } else if (((p - offset) == 0) && ((*p == 'x') || (*p == 'X') || (*p == 't') || (*p == 'T'))) { - //* The default/legacy behavior with two builtin XFF field names */ + // The default/legacy behavior with two builtin XFF field names if ( (ServerConf->enable_xff) && hsd && ((hdrs_args->true_clnt_xff & XFF_HEADERS) == 0) ) { if (IsHeaderFieldName(p, end, HEADER_NAME__XFF, HEADER_LENGTH__XFF)) @@ -2868,9 +2868,9 @@ int StatelessInspection(Packet* p, HI_SESSION* session, HttpSessionData* hsd, in { Client->request.method_raw = method_ptr.uri; Client->request.method_size = method_ptr.uri_end - method_ptr.uri; - ///XXX - ///Copy out the header into its own buffer..., - /// set ptr to end of header. + // XXX + // Copy out the header into its own buffer..., + // set ptr to end of header. // // uri_ptr.end points to end of URI & HTTP version identifier. if (hi_util_in_bounds(start, end, uri_ptr.uri_end + 1)) diff --git a/src/service_inspectors/http_inspect/hi_client.h b/src/service_inspectors/http_inspect/hi_client.h index bfa427f19..da5b1fe55 100644 --- a/src/service_inspectors/http_inspect/hi_client.h +++ b/src/service_inspectors/http_inspect/hi_client.h @@ -20,10 +20,6 @@ #ifndef HI_CLIENT_H #define HI_CLIENT_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include #include "hi_main.h" @@ -34,6 +30,7 @@ #define POST_END 100 #define NO_URI 101 +// Special processing for the HTTP X-Forwarded-For request header #define XFF_MODE_MASK (0x000f) #define XFF_EXFF_MASK (0x000c) @@ -59,14 +56,14 @@ typedef struct s_CONTLEN_PTR const u_char* cont_len_start; const u_char* cont_len_end; uint32_t len; -}CONTLEN_PTR; +} CONTLEN_PTR; typedef struct s_CONT_ENCODING_PTR { const u_char* cont_encoding_start; const u_char* cont_encoding_end; uint16_t compress_fmt; -}CONT_ENCODING_PTR; +} CONT_ENCODING_PTR; typedef struct s_HEADER_FIELD_PTR { diff --git a/src/service_inspectors/http_inspect/hi_events.h b/src/service_inspectors/http_inspect/hi_events.h index 825c61a3e..fb33fa553 100644 --- a/src/service_inspectors/http_inspect/hi_events.h +++ b/src/service_inspectors/http_inspect/hi_events.h @@ -25,9 +25,7 @@ #define GID_HTTP_CLIENT 119 #define GID_HTTP_SERVER 120 -/* -** Client Events -*/ +// Client Events typedef enum _HI_CLI_EVENTS { HI_CLIENT_ASCII = 1, @@ -68,6 +66,7 @@ typedef enum _HI_CLI_EVENTS HI_CLIENT_EVENT_NUM } HI_CLI_EVENTS; +// Server Events typedef enum _HI_EVENTS { HI_ANOM_SERVER = 1, @@ -90,9 +89,7 @@ typedef enum _HI_EVENTS HI_SERVER_EVENT_NUM } HI_EVENTS; -/* -** These defines are the alert names for each event -*/ +// Client alert text for each event #define HI_CLIENT_ASCII_STR \ "ascii encoding" #define HI_CLIENT_DOUBLE_DECODE_STR \ @@ -163,10 +160,7 @@ typedef enum _HI_EVENTS #define HI_CLIENT_PIPELINE_MAX_STR \ "too many pipelined requests" -/* -** Server Events -*/ - +// Server alert text for each event #define HI_ANOM_SERVER_STR \ "anomalous http server on undefined HTTP port" #define HI_SERVER_INVALID_STATCODE_STR \ diff --git a/src/service_inspectors/http_inspect/hi_include.h b/src/service_inspectors/http_inspect/hi_include.h index 16705d889..7c9a075d7 100644 --- a/src/service_inspectors/http_inspect/hi_include.h +++ b/src/service_inspectors/http_inspect/hi_include.h @@ -20,8 +20,8 @@ #ifndef HI_INCLUDE_H #define HI_INCLUDE_H -#include "snort_types.h" -#include "snort_debug.h" +#include "main/snort_types.h" +#include "main/snort_debug.h" #include "main/thread.h" #include "utils/stats.h" @@ -37,8 +37,8 @@ struct HIStats PegCount req_headers; /* Number of successfully extracted request headers */ PegCount resp_headers; /* Number of successfully extracted response headers */ - PegCount req_cookies; /* Number of successfully extracted request cookies */ - PegCount resp_cookies; /* Number of successfully extracted response cookies */ + PegCount req_cookies; /* Number of successfully extracted request cookies */ + PegCount resp_cookies; /* Number of successfully extracted response cookies */ PegCount post_params; /* Number of successfully extract post parameters */ PegCount unicode; diff --git a/src/service_inspectors/http_inspect/hi_main.h b/src/service_inspectors/http_inspect/hi_main.h index 106f36d57..27f4b112e 100644 --- a/src/service_inspectors/http_inspect/hi_main.h +++ b/src/service_inspectors/http_inspect/hi_main.h @@ -26,25 +26,22 @@ #include +#include "hi_ui_config.h" #include "protocols/packet.h" #include "stream/stream_api.h" -#include "hi_ui_config.h" -#include "util_utf.h" -#include "detection_util.h" +#include "detection/detection_util.h" #include "search_engines/search_tool.h" -#include "util_jsnorm.h" -#include "profiler.h" +#include "time/profiler.h" +#include "utils/util_jsnorm.h" +#include "utils/util_utf.h" #define MAX_METHOD_LEN 256 #define DEFAULT_HTTP_MEMCAP 150994944 /* 144 MB */ -#define MIN_HTTP_MEMCAP 2304 -#define MAX_HTTP_MEMCAP 603979776 /* 576 MB */ #define MAX_URI_EXTRACTED 2048 #define MAX_HOSTNAME 256 #define DEFAULT_MAX_GZIP_MEM 838860 -#define GZIP_MEM_MIN 3276 #define MAX_GZIP_DEPTH 65535 #define DEFAULT_COMP_DEPTH 1460 #define DEFAULT_DECOMP_DEPTH 2920 @@ -92,7 +89,7 @@ typedef struct s_HTTP_RESP_STATE int data_extracted; uint32_t max_seq; bool flow_depth_excd; -}HTTP_RESP_STATE; +} HTTP_RESP_STATE; typedef struct s_HTTP_LOG_STATE { @@ -100,7 +97,7 @@ typedef struct s_HTTP_LOG_STATE uint32_t hostname_bytes; uint8_t uri_extracted[MAX_URI_EXTRACTED]; uint8_t hostname_extracted[MAX_HOSTNAME]; -}HTTP_LOG_STATE; +} HTTP_LOG_STATE; typedef struct _HttpSessionData { diff --git a/src/service_inspectors/http_inspect/hi_mi.h b/src/service_inspectors/http_inspect/hi_mi.h index 531bee85c..317ed35c5 100644 --- a/src/service_inspectors/http_inspect/hi_mi.h +++ b/src/service_inspectors/http_inspect/hi_mi.h @@ -33,7 +33,6 @@ #include #include "hi_si.h" -#include "hi_include.h" #include "hi_main.h" int hi_mi_mode_inspection(HI_SESSION* session, int iInspectMode, Packet* p, HttpSessionData*); diff --git a/src/service_inspectors/http_inspect/hi_reqmethod_check.h b/src/service_inspectors/http_inspect/hi_reqmethod_check.h index 3f9559a86..4163f2d9e 100644 --- a/src/service_inspectors/http_inspect/hi_reqmethod_check.h +++ b/src/service_inspectors/http_inspect/hi_reqmethod_check.h @@ -18,12 +18,9 @@ //-------------------------------------------------------------------------- /* - * hi_reqmethod_check.h: Structure definitions/function prototype(s) - * for the request method type check + * Structure definitions/function prototype(s) for the request method type check */ -/* $Id */ - #ifndef HI_REQMETHOD_CHECK_H #define HI_REQMETHOD_CHECK_H @@ -37,9 +34,8 @@ #define HI_RMFLG_CONNECT (0x40) #define HI_RMFLG_ALL (0xFFFFFFFF) -/* Structure stored as callback data for use by request method - * detection plugin code. - */ +// Structure stored as callback data for use by request method detection plugin code. + typedef struct _ReqMethodCheckData { int type_vector; @@ -49,5 +45,5 @@ typedef struct _ReqMethodCheckData extern int ReqMethodCheckInit(char*, char*, void**); extern int ReqMethodCheckEval(void*, uint8_t**, void*); -#endif /* HI_REQMETHOD_CHECK */ +#endif diff --git a/src/service_inspectors/http_inspect/hi_server.cc b/src/service_inspectors/http_inspect/hi_server.cc index e61c96841..1525b963f 100644 --- a/src/service_inspectors/http_inspect/hi_server.cc +++ b/src/service_inspectors/http_inspect/hi_server.cc @@ -38,7 +38,7 @@ #include #include -#include "hi_paf.h" +#include "hi_stream_splitter.h" #include "main/thread.h" static THREAD_LOCAL bool headers = false; diff --git a/src/service_inspectors/http_inspect/hi_server.h b/src/service_inspectors/http_inspect/hi_server.h index 3b2f4773c..ff759d6ab 100644 --- a/src/service_inspectors/http_inspect/hi_server.h +++ b/src/service_inspectors/http_inspect/hi_server.h @@ -17,22 +17,14 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/** -** @file hi_server.h -** -** @author Daniel Roelker -** -** @brief Header file for HttpInspect Server Module -** -** This file defines the server structure and functions to access server -** inspection. -** -** NOTE: -** - Initial development. DJR -*/ +// hi_server.h author Daniel Roelker + #ifndef HI_SERVER_H #define HI_SERVER_H +// This file declares the server structure and functions to access server +// inspection. + #include "hi_include.h" #include "hi_util.h" #include "hi_main.h" diff --git a/src/service_inspectors/http_inspect/hi_si.h b/src/service_inspectors/http_inspect/hi_si.h index 9f56b69e5..e6591df35 100644 --- a/src/service_inspectors/http_inspect/hi_si.h +++ b/src/service_inspectors/http_inspect/hi_si.h @@ -40,8 +40,8 @@ #include "hi_client.h" #include "hi_server.h" #include "hi_ad.h" - #include "sfip/sfip_t.h" + struct Packet; /* diff --git a/src/service_inspectors/http_inspect/hi_stateful_inspect.h b/src/service_inspectors/http_inspect/hi_stateful_inspect.h deleted file mode 100644 index 604c5cf0c..000000000 --- a/src/service_inspectors/http_inspect/hi_stateful_inspect.h +++ /dev/null @@ -1,236 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2005-2013 Sourcefire, Inc. -// -// 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. -//-------------------------------------------------------------------------- - -/* - * hi_stateful_inspect.h: Defines, structs, function prototype(s) for - * HTTP inspect stateful inspection module. - * - * Author(s): Chris Sherwin - */ - -#ifndef HI_STATEFUL_INSPECT_H -#define HI_STATEFUL_INSPECT_H - -/* - * Flags modifying stateful inspection's behavior - * - * HI_ST_FLG_CLEAR: No flags set - * HI_ST_FLG_CRLF_EOM: Found a CRLF at the end of - * the previous pkt. - * HI_ST_FLG_POSTPARM: Request contains post parameters. - */ -#define HI_ST_FLG_CLEAR (0x0) -#define HI_ST_FLG_CRLF_EOM (0x1) -#define HI_ST_FLG_POSTPARM (0x2) - -/* - * States into which the HTTP request - * stateful processing can enter. - * - * HI_ST_STATE_URI_KEY: HTTP Inspect is searching for - * request method keyword which - * signifies URI. - * HI_ST_STATE_URI_CONT: HTTP Inspect is building the - * contents of the URI. - * HI_ST_STATE_HDR_KEY: HTTP Inspect is searching for - * a header keyword. - * HI_ST_STATE_HDR_CT: HTTP Inspect is processing a - * content-type header. - * HI_ST_STATE_HDR_PA: HTTP Inspect is processing a - * proxy-authenticate header. - * HI_ST_STATE_HDR_CONT: HTTP Inspect is examining the - * contents of a header. - * HI_ST_STATE_BDY_POST: HTTP Inspect is treating body - * as a set of post parameters. - * HI_ST_STATE_BDY_PIPE: HTTP Inspect is searching for - * a pipelined request. - * HI_ST_STATE_MSG_DONE: A complete HTTP request has - * been seen and processed. - */ -#define HI_ST_STATE_URI_KEY (0x1) -#define HI_ST_STATE_URI_CONT (0x2) -#define HI_ST_STATE_HDR_KEY (0x3) -#define HI_ST_STATE_HDR_CT (0x4) -#define HI_ST_STATE_HDR_PA (0x5) -#define HI_ST_STATE_HDR_CONT (0x6) -#define HI_ST_STATE_BDY_POST (0x7) -#define HI_ST_STATE_BDY_PIPE (0x8) -#define HI_ST_STATE_MSG_DONE (0x9) -#define HI_ST_NUM_STATES (8) - -/* - * - */ -#define HI_ST_MAXBUFLEN 10400 - -/* - * Recognized delimiter types. - */ -#define HI_ST_DELIM_NONE (0x0) -#define HI_ST_DELIM_CRLF (0x1) -#define HI_ST_DELIM_AHF (0x2) - -#define HI_ST_SUCCESS (0x1) -#define HI_ST_FAILURE (0x0) - -/* - * Flag values for BUFFER::buf_flags. These - * define any special processing of the buffer - * that may be needed/pending. - * - * HI_ST_BUFFLGS_NONE: No flags. - * HI_ST_BUFFLGS_COMPACT: Buffer "compacting" is required - */ -#define HI_ST_BUFFLGS_NONE (0x0) -#define HI_ST_BUFFLGS_COMPACT (0x1) - -#define HI_ST_MAX_BYTES_WO_HEADER 10 - -/* - * Default value for max header bytes. Used for - * header folding detection, etc. to alert on - * suspiciously long header fields. - */ -#define HI_ST_MAX_HEADER_BYTES 8190 - -/* Buffer structure used in stateful inspection - * packet processing. - * - * startp: Start of actual data in buffer. - * endp: End of actual data in buffer. - * curp: Pointer/index into the buffer data. - * bufendp: End of the allocated memory for the buffer. - * buf_flags: Flags indicating special processing which is required. - */ -typedef struct _BUF -{ - unsigned char* startp; - unsigned char* endp; - unsigned char* curp; - unsigned char* bufendp; - unsigned int buf_flags; -} BUFFER; - -/* Structure containing current state regarding headers for - * a request. - * - * num_headers: Number of headers seen in the current request. - * bytes_wo_header: Bytes examined since last header, w/o finding - * a new header. - * hf_bytes: Bytes examined so far in current header. Used for - * header folding inspection. - * startp: Pointer to start of headers section of request. - * endp: Pointer to end of headers section of request. - * base64startp: Pointer to start of base64 encoded portion of req. - * base64endp: Pointer to end of base64 encoded portion of req. - * - */ -typedef struct _HEADER_STATE -{ - int num_headers; - int bytes_wo_header; - int hf_bytes; - unsigned char* startp; - unsigned char* endp; - unsigned char* base64startp; - unsigned char* base64endp; -} HEADER_STATE; - -/* - * One of these structures is kept for each HTTP session - * tracked by HTTP inspect. - * - * request_buffer: - * mpse_state: Saved MPSE state from searches started in - * previous packet - * flags: State flags - * state: Current state of the inspectin state machine. - * request_type: Discovered method type for current request. - * uristate: State block containing discovered info about - * URI in current request. - * headerstate: State block containing discovered info about headers - * in current request. - * bodyp: Pointer to beginning of body portion of request. - * body_endp: Pointer to end of body portion of request. - */ -typedef struct _HI_SI_STATE -{ - BUFFER request_buffer; - int mpse_state; - int flags; - int state; - int request_type; - URI_PTR uristate; - HEADER_STATE headerstate; - unsigned char* bodyp; - unsigned char* body_endp; -} HI_SI_STATE; - -/* - * Match-types to be filled into HI_SI_MATCHDATA::type - * - * HI_ST_MATCHTYPE_NONE: No match - * HI_ST_MATCHTYPE_REQMETHOD: A req. method keyword has been found. - * HI_ST_MATCHTYPE_HEADER: A header keyword has been found. - * HI_ST_MATCHTYPE_CRLF: A delimiter token has been found. - * HI_ST_MATCHTYPE_POSTPARMCT: The post-param content-type has been found. - * HI_ST_MATCHTYPE_BASE64: A keyword indicating base64 enc. has been found. - */ -#define HI_ST_MATCHTYPE_NONE (0x0) -#define HI_ST_MATCHTYPE_REQMETHOD (0x1) -#define HI_ST_MATCHTYPE_HEADER (0x2) -#define HI_ST_MATCHTYPE_CRLF (0x3) -#define HI_ST_MATCHTYPE_POSTPARMCT (0x4) -#define HI_ST_MATCHTYPE_BASE64 (0x5) - -#define HI_ST_CT_KEYWORD "Content-Type:" -#define HI_ST_PA_KEYWORD "Proxy-Authorization:" - -/* - * Request method types - */ -#define HI_ST_METHOD_GET (0x1) -#define HI_ST_METHOD_HEAD (0x2) -#define HI_ST_METHOD_POST (0x3) -#define HI_ST_METHOD_PUT (0x4) -#define HI_ST_METHOD_DELETE (0x5) -#define HI_ST_METHOD_TRACE (0x6) -#define HI_ST_METHOD_CONNECT (0x7) - -/* One of these structs is passed into the MPSE search - * to be filled in by the match callback. - * - * index: The index of the match, in bytes, - * into the searched string - * type: The type of keyword found - * (e.g. request method or header ) - * data: Type-specific data. - * - * keywordp: Pointer to the keyword which matched. - */ -typedef struct _HI_SI_MATCHDATA -{ - int index; - int type; - int data; - unsigned char* keywordp; -} HI_SI_MATCHDATA; - -#endif /* HI_STATEFUL_INSPECT_H */ - diff --git a/src/service_inspectors/http_inspect/hi_paf.cc b/src/service_inspectors/http_inspect/hi_stream_splitter.cc similarity index 99% rename from src/service_inspectors/http_inspect/hi_paf.cc rename to src/service_inspectors/http_inspect/hi_stream_splitter.cc index 24a9dc8ae..a0c58d61a 100644 --- a/src/service_inspectors/http_inspect/hi_paf.cc +++ b/src/service_inspectors/http_inspect/hi_stream_splitter.cc @@ -17,12 +17,11 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// hi_stream_splitter.c author Russ Combs + //-------------------------------------------------------------------- // hi stuff // -// @file hi_paf.c -// @author Russ Combs - // the goal is to perform the minimal http paf parsing required for // correctness while maintaining loose coupling with hi proper: @@ -44,7 +43,7 @@ // * Range, Content-Range, and multipart //-------------------------------------------------------------------- -#include "hi_paf.h" +#include "hi_stream_splitter.h" #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/service_inspectors/http_inspect/hi_paf.h b/src/service_inspectors/http_inspect/hi_stream_splitter.h similarity index 93% rename from src/service_inspectors/http_inspect/hi_paf.h rename to src/service_inspectors/http_inspect/hi_stream_splitter.h index a84afb1f6..45ea20620 100644 --- a/src/service_inspectors/http_inspect/hi_paf.h +++ b/src/service_inspectors/http_inspect/hi_stream_splitter.h @@ -20,14 +20,14 @@ //-------------------------------------------------------------------- // hi stuff // -// @file hi_paf.h +// @file hi_stream_splitter.h // @author Russ Combs //-------------------------------------------------------------------- -#ifndef HI_PAF_H -#define HI_PAF_H +#ifndef HI_STREAM_SPLITTER_H +#define HI_STREAM_SPLITTER_H -#include "snort_types.h" +#include "main/snort_types.h" #include "stream/stream_api.h" #include "stream/stream_splitter.h" diff --git a/src/service_inspectors/http_inspect/hi_ui_config.h b/src/service_inspectors/http_inspect/hi_ui_config.h index d9f58e215..3a1f03828 100644 --- a/src/service_inspectors/http_inspect/hi_ui_config.h +++ b/src/service_inspectors/http_inspect/hi_ui_config.h @@ -34,25 +34,20 @@ #define HI_UI_CONFIG_H #include "hi_include.h" -#include "snort_bounds.h" -#include "sfrt/sfrt.h" -#include "sf_ip.h" #include "hi_util_kmap.h" +#include "sfrt/sfrt.h" +#include "sfip/sf_ip.h" #include "file_api/file_api.h" #include "decompress/file_decomp.h" #include "framework/bits.h" +#include "utils/snort_bounds.h" -/* -** Defines -*/ #define HI_UI_CONFIG_MAX_HDR_DEFAULT 0 #define HI_UI_CONFIG_MAX_HEADERS_DEFAULT 0 #define HI_UI_CONFIG_MAX_SPACES_DEFAULT 200 #define HI_UI_CONFIG_MAX_XFF_FIELD_NAMES 8 -/* -** Special characters treated as whitespace before or after URI -*/ +// Special characters treated as whitespace before or after URI #define HI_UI_CONFIG_WS_BEFORE_URI 0x01 #define HI_UI_CONFIG_WS_AFTER_URI 0x02 @@ -66,8 +61,7 @@ struct HTTPINSPECT_CONF_OPT int on; /**< if true, configuration option is on */ }; -/* The following are used to delineate server profiles for user output - * and debugging information. */ +// The following are used to delineate server profiles for user output and debugging information. enum PROFILES { HI_DEFAULT, @@ -95,10 +89,7 @@ struct HTTPINSPECT_GLOBAL_CONF int anomalous_servers; int proxy_alert; - /* - ** These variables are for tracking the IIS - ** Unicode Map configuration. - */ + // These variables are for tracking the IIS Unicode Map configuration uint8_t* iis_unicode_map; char* iis_unicode_map_filename; int iis_unicode_codepage; diff --git a/src/service_inspectors/http_inspect/hi_ui_iis_unicode_map.h b/src/service_inspectors/http_inspect/hi_ui_iis_unicode_map.h index 39ce349b1..1f0c0eb28 100644 --- a/src/service_inspectors/http_inspect/hi_ui_iis_unicode_map.h +++ b/src/service_inspectors/http_inspect/hi_ui_iis_unicode_map.h @@ -18,11 +18,7 @@ //-------------------------------------------------------------------------- /** -** @file hi_ui_iis_unicode_map.h -** ** @author Daniel Roelker -** -** @brief Header file for hi_ui_iis_unicode_map functions. */ #ifndef HI_UI_IIS_UNICODE_MAP_H #define HI_UI_IIS_UNICODE_MAP_H @@ -30,14 +26,13 @@ #include "hi_include.h" #include "hi_ui_config.h" -/** +/* ** This is the define for the iis_unicode_map array when there is no ** ASCII mapping. */ #define HI_UI_NON_ASCII_CODEPOINT -1 -int hi_ui_parse_iis_unicode_map(uint8_t** iis_unicode_map, char* filename, - int iCodePage); +int hi_ui_parse_iis_unicode_map(uint8_t** iis_unicode_map, char* filename, int iCodePage); bool get_default_unicode_map(uint8_t*& map, int& page); diff --git a/src/service_inspectors/http_inspect/hi_util.h b/src/service_inspectors/http_inspect/hi_util.h index b9fecad23..cdc355e4b 100644 --- a/src/service_inspectors/http_inspect/hi_util.h +++ b/src/service_inspectors/http_inspect/hi_util.h @@ -37,10 +37,6 @@ #include "hi_include.h" /* -** NAME -** hi_util_in_bounds:: -*/ -/** ** This function checks for in bounds condition on buffers. ** ** This is very important for much of what we do here, since inspecting @@ -50,12 +46,6 @@ ** This checks a half-open interval with the end pointer being one char ** after the end of the buffer. ** -** @param start the start of the buffer. -** @param end the end of the buffer. -** @param p the pointer within the buffer -** -** @return integer -** ** @retval 1 within bounds ** @retval 0 not within bounds */ diff --git a/src/service_inspectors/http_inspect/hi_util_kmap.cc b/src/service_inspectors/http_inspect/hi_util_kmap.cc index d4e7cab42..80829e70a 100644 --- a/src/service_inspectors/http_inspect/hi_util_kmap.cc +++ b/src/service_inspectors/http_inspect/hi_util_kmap.cc @@ -17,27 +17,9 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -* -* kmap.c - a generic map library - maps key + data pairs -* -* Uses Lexical Keyword Trie -* The tree uses linked lists to build the finite automata -* -* MapKeyFind(): Performs a setwise strcmp() equivalant. -* -* Notes: -* -* Keys may be ascii or binary, both may be of random sizes. -* Each key may be a different size, or all one size. -* Fast dictionary lookup, proportional to the length of the key, -* and independent of the number of keys in the table. -* May use more memory than a hash table, depends. -* Memory is allocated as needed, so none is wasted. -* -* Author: Marc Norton -* -*/ +// hi_util_kmap.cc author Marc Norton +// a generic map library - maps key + data pairs + #include "hi_util_kmap.h" #ifdef HAVE_CONFIG_H diff --git a/src/service_inspectors/http_inspect/hi_util_kmap.h b/src/service_inspectors/http_inspect/hi_util_kmap.h index 85e9fa900..0c077d6b5 100644 --- a/src/service_inspectors/http_inspect/hi_util_kmap.h +++ b/src/service_inspectors/http_inspect/hi_util_kmap.h @@ -17,23 +17,24 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -* kmap.h -* -* Keyword Trie based Map Table -* -* Author: Marc Norton -* -*/ +// hi_util_kmap.h author Marc Norton #ifndef HI_UTIL_KMAP_H #define HI_UTIL_KMAP_H +// Keyword Trie based Map Table +// The tree uses linked lists to build the finite automata +// +// MapKeyFind(): Performs a setwise strcmp() equivalant. +// +// Keys may be ascii or binary, both may be of random sizes. Each key may +// be a different size, or all one size. Fast dictionary lookup, +// proportional to the length of the key, and independent of the number of +// keys in the table. May use more memory than a hash table, depends. +// Memory is allocated as needed, so none is wasted. + #define ALPHABET_SIZE 256 -/* -* -*/ typedef struct _keynode { struct _keynode* next; @@ -43,9 +44,6 @@ typedef struct _keynode void* userdata; /* data associated with this pattern */ } KEYNODE; -/* -* -*/ typedef struct _kmapnode { int nodechar; /* node character */ @@ -56,9 +54,6 @@ typedef struct _kmapnode KEYNODE* knode; } KMAPNODE; -/* -* -*/ typedef void (* KMapUserFreeFunc)(void* p); typedef struct _kmap @@ -68,16 +63,13 @@ typedef struct _kmap KEYNODE* keylist; // list of key+data pairs KEYNODE* keynext; // findfirst/findnext node - KMapUserFreeFunc userfree; // fcn to free user data + KMapUserFreeFunc userfree; int nchars; // # character nodes int nocase; } KMAP; -/* -* PROTOTYPES -*/ KMAP* KMapNew(KMapUserFreeFunc userfree); void KMapSetNoCase(KMAP* km, int flag); int KMapAdd(KMAP* km, void* key, int ksize, void* userdata); diff --git a/src/service_inspectors/http_inspect/hi_util_xmalloc.cc b/src/service_inspectors/http_inspect/hi_util_xmalloc.cc index 7a2618265..33cfbc1fa 100644 --- a/src/service_inspectors/http_inspect/hi_util_xmalloc.cc +++ b/src/service_inspectors/http_inspect/hi_util_xmalloc.cc @@ -17,9 +17,6 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** util.c -*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -27,12 +24,14 @@ #include #include #include -#include #include #include "main/thread.h" +#include "hi_util_xmalloc.h" + //#define MDEBUG +// FIXIT-L these ifdefs won't compile without warnings static THREAD_LOCAL unsigned msize=0; @@ -92,29 +91,3 @@ void xfree(void* p) #endif } -void xshowmem(void) -{ -#ifdef MDEBUG - printf("xmalloc-mem: %u bytes\n",msize); -#endif -} - -char* xstrdup(const char* str) -{ - int data_size; - char* data = NULL; - - data_size = strlen(str) + 1; - data = (char*)xmalloc(data_size); - - if (data == NULL) - { - return NULL; - } - - strncpy(data, str, data_size - 1); - data[data_size - 1] = '\0'; - - return data; -} - diff --git a/src/service_inspectors/http_inspect/hi_util_xmalloc.h b/src/service_inspectors/http_inspect/hi_util_xmalloc.h index cadc5ccb0..71b12f0ef 100644 --- a/src/service_inspectors/http_inspect/hi_util_xmalloc.h +++ b/src/service_inspectors/http_inspect/hi_util_xmalloc.h @@ -23,9 +23,6 @@ #include void* xmalloc(size_t byteSize); -char* xstrdup(const char* str); - -void xshowmem(void); void xfree(void*); #endif diff --git a/src/service_inspectors/http_inspect/http_inspect.cc b/src/service_inspectors/http_inspect/http_inspect.cc index ad9c1b8f3..69b1f371c 100644 --- a/src/service_inspectors/http_inspect/http_inspect.cc +++ b/src/service_inspectors/http_inspect/http_inspect.cc @@ -57,7 +57,7 @@ #include "hi_util_kmap.h" #include "hi_util_xmalloc.h" #include "hi_cmd_lookup.h" -#include "hi_paf.h" +#include "hi_stream_splitter.h" #include "profiler.h" #include "detection_util.h" diff --git a/src/service_inspectors/imap/dev_notes.txt b/src/service_inspectors/imap/dev_notes.txt new file mode 100644 index 000000000..45797ce52 --- /dev/null +++ b/src/service_inspectors/imap/dev_notes.txt @@ -0,0 +1,7 @@ +This directory contains all files related to IMAP protocol processing. The +protocol aware flushing for IMAP determines IMAP PDU and this reassembled +IMAP PDU is processed by the IMAP inspector. Both IMAP requests/responses +are parsed and the MIME attachments in IMAP responses are processed using +the file API. The file API extracts and decodes the attachments. file_data +is then set to the start of these extracted/decoded attachments. This +inspector also identifies and whitelists the IMAPS traffic. diff --git a/src/service_inspectors/imap/imap.cc b/src/service_inspectors/imap/imap.cc index 17dffbb25..b3b042eca 100644 --- a/src/service_inspectors/imap/imap.cc +++ b/src/service_inspectors/imap/imap.cc @@ -15,14 +15,9 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * IMAP preprocessor - * Author: Bhagyashree Bantwal - * - * - */ +// imap.cc author Bhagyashree Bantwal + #include "imap.h" #ifdef HAVE_CONFIG_H diff --git a/src/service_inspectors/imap/imap.h b/src/service_inspectors/imap/imap.h index 61b31c83c..c3eaf3c08 100644 --- a/src/service_inspectors/imap/imap.h +++ b/src/service_inspectors/imap/imap.h @@ -15,53 +15,37 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * imap.h: Definitions, structs, function prototype(s) for - * Author: Bhagyashree Bantwal - */ +// imap.h author Bhagyashree Bantwal #ifndef IMAP_H #define IMAP_H +// Implementation header with definitions, datatypes and flowdata class for +// IMAP service inspector. + #include "protocols/packet.h" #include "stream/stream_api.h" -#include "profiler.h" +#include "time/profiler.h" #include "imap_config.h" -/* Direction packet is coming from, if we can figure it out */ + +// Direction packet is coming from, if we can figure it out #define IMAP_PKT_FROM_UNKNOWN 0 #define IMAP_PKT_FROM_CLIENT 1 #define IMAP_PKT_FROM_SERVER 2 -#define SEARCH_CMD 0 -#define SEARCH_RESP 1 -#define SEARCH_HDR 2 -#define SEARCH_DATA_END 3 -#define NUM_SEARCHES 4 - -#define BOUNDARY 0 - -#define STATE_DATA 0 /* Data state */ -#define STATE_TLS_CLIENT_PEND 1 /* Got STARTTLS */ -#define STATE_TLS_SERVER_PEND 2 /* Got STARTTLS */ -#define STATE_TLS_DATA 3 /* Successful handshake, TLS encrypted data */ +#define STATE_DATA 0 // Data state +#define STATE_TLS_CLIENT_PEND 1 // Got STARTTLS +#define STATE_TLS_SERVER_PEND 2 // Got STARTTLS +#define STATE_TLS_DATA 3 // Successful handshake, TLS encrypted data #define STATE_COMMAND 4 #define STATE_UNKNOWN 5 -#define STATE_DATA_INIT 0 -#define STATE_DATA_HEADER 1 /* Data header section of data state */ -#define STATE_DATA_BODY 2 /* Data body section of data state */ -#define STATE_MIME_HEADER 3 /* MIME header section within data section */ -#define STATE_DATA_UNKNOWN 4 - -/* session flags */ +// session flags #define IMAP_FLAG_NEXT_STATE_UNKNOWN 0x00000004 #define IMAP_FLAG_GOT_NON_REBUILT 0x00000008 #define IMAP_FLAG_CHECK_SSL 0x00000010 -/* Maximum length of header chars before colon, based on Exim 4.32 exploit */ -#define MAX_HEADER_NAME_LEN 64 typedef enum _IMAPCmdEnum { CMD_APPEND = 0, @@ -141,6 +125,7 @@ typedef enum _IMAPHdrEnum HDR_CONT_DISP, HDR_LAST } IMAPHdrEnum; + struct IMAPSearch { const char* name; @@ -154,13 +139,6 @@ struct IMAPToken int search_id; }; -struct IMAPCmdConfig -{ - char alert; /* 1 if alert when seen */ - char normalize; /* 1 if we should normalize this command */ - int max_line_len; /* Max length of this particular command */ -}; - struct IMAPSearchInfo { int id; diff --git a/src/service_inspectors/imap/imap_config.h b/src/service_inspectors/imap/imap_config.h index 40b1bc50e..8983efd9b 100644 --- a/src/service_inspectors/imap/imap_config.h +++ b/src/service_inspectors/imap/imap_config.h @@ -15,19 +15,18 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// #ifndef IMAP_CONFIG_H #define IMAP_CONFIG_H +// Configuration for Imap service inspector + #include "file_api/file_api.h" struct IMAP_PROTO_CONF { - uint32_t memcap; DecodeConfig decode_conf; MAIL_LogConfig log_config; }; #endif - diff --git a/src/service_inspectors/imap/imap_module.h b/src/service_inspectors/imap/imap_module.h index ad250b09f..9906c0c5f 100644 --- a/src/service_inspectors/imap/imap_module.h +++ b/src/service_inspectors/imap/imap_module.h @@ -21,6 +21,8 @@ #ifndef IMAP_MODULE_H #define IMAP_MODULE_H +// Interface to the IMAP service inspector + #include "framework/module.h" #include "framework/bits.h" #include "main/thread.h" @@ -67,4 +69,3 @@ private: }; #endif - diff --git a/src/service_inspectors/imap/imap_paf.h b/src/service_inspectors/imap/imap_paf.h index b38174719..1af944682 100644 --- a/src/service_inspectors/imap/imap_paf.h +++ b/src/service_inspectors/imap/imap_paf.h @@ -1,52 +1,55 @@ -/**************************************************************************** - * Copyright (C) 2015 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. - * - ****************************************************************************/ +//-------------------------------------------------------------------------- +// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2011-2013 Sourcefire, Inc. +// +// 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. +//-------------------------------------------------------------------------- + +// imap_paf.h author Hui Cao #ifndef IMAP_PAF_H #define IMAP_PAF_H -#include "snort_types.h" +// Protocol aware flushing for IMAP + +#include "main/snort_types.h" #include "stream/stream_api.h" #include "stream/stream_splitter.h" #include "file_api/file_api.h" struct ImapDataInfo { - int paren_cnt; /* The open parentheses count in fetch */ - const char* next_letter; /* The current command in fetch */ + int paren_cnt; // The open parentheses count in fetch + const char* next_letter; // The current command in fetch bool found_len; uint32_t length; - bool esc_nxt_char; /* true if the next charachter has been escaped */ + bool esc_nxt_char; // true if the next charachter has been escaped }; -/* State tracker for SMTP PAF */ +// States for IMAP PAF typedef enum _ImapPafState { - IMAP_PAF_REG_STATE, /* default state. eat until LF */ - IMAP_PAF_DATA_HEAD_STATE, /* parses the fetch header */ - IMAP_PAF_DATA_LEN_STATE, /* parse the literal length */ - IMAP_PAF_DATA_STATE, /* search for and flush on MIME boundaries */ - IMAP_PAF_FLUSH_STATE, /* flush if a termination sequence is found */ - IMAP_PAF_CMD_IDENTIFIER, /* determine the line identifier ('+', '*', tag) */ - IMAP_PAF_CMD_TAG, /* currently analyzing tag . identifier*/ - IMAP_PAF_CMD_STATUS, /* currently parsing second argument */ - IMAP_PAF_CMD_SEARCH /* currently searching data for a command */ + IMAP_PAF_REG_STATE, // default state. eat until LF + IMAP_PAF_DATA_HEAD_STATE, // parses the fetch header + IMAP_PAF_DATA_LEN_STATE, // parse the literal length + IMAP_PAF_DATA_STATE, // search for and flush on MIME boundaries + IMAP_PAF_FLUSH_STATE, // flush if a termination sequence is found + IMAP_PAF_CMD_IDENTIFIER, // determine the line identifier ('+', '*', tag) + IMAP_PAF_CMD_TAG, // currently analyzing tag . identifier + IMAP_PAF_CMD_STATUS, // currently parsing second argument + IMAP_PAF_CMD_SEARCH // currently searching data for a command } ImapPafState; typedef enum _ImapDataEnd @@ -55,12 +58,12 @@ typedef enum _ImapDataEnd IMAP_PAF_DATA_END_PAREN } ImapDataEnd; -/* State tracker for IMAP PAF */ +// State tracker for IMAP PAF struct ImapPafData { - MimeDataPafInfo mime_info; /* Mime response information */ - ImapPafState imap_state; /* The current IMAP paf stat */ - ImapDataInfo imap_data_info; /* Used for parsing data */ + MimeDataPafInfo mime_info; // Mime response information + ImapPafState imap_state; // The current IMAP paf stat + ImapDataInfo imap_data_info; // Used for parsing data ImapDataEnd data_end_state; bool end_of_data; }; @@ -80,6 +83,7 @@ public: ImapPafData state; }; +// Function: Check if IMAP data end is reached bool imap_is_data_end(void* ssn); #endif diff --git a/src/service_inspectors/nhttp_inspect/dev_notes.txt b/src/service_inspectors/nhttp_inspect/dev_notes.txt new file mode 100644 index 000000000..5ad2d5b00 --- /dev/null +++ b/src/service_inspectors/nhttp_inspect/dev_notes.txt @@ -0,0 +1,83 @@ +This is the new Snort HTTP inspector. The old Snort HTTP preprocessor has also +been ported to Snort++ and will be maintained until NHttpInspect is finished. +At that time NHttpInspect will be renamed HttpInspect and the old HttpInspect +will be retired. Meanwhile the abbreviations HI and NHI are sometimes used when +it is important to distinguish the two modules. + +HI and NHI are not intended to be used together. Only configure one of them +at a time. + +NHI is divided into two major parts. The NHttpStreamSplitter (splitter) accepts +TCP payload data from Stream and subdivides it into message sections. +NHttpInspect (inspector) processes individual message sections. + +Unlike other inspectors NHI has an empty eval() member. All processing is done +by the inspector process() member which is called directly from splitter +reassemble(). Thus the data flow for processing a message section is one or +more calls to splitter scan(), followed by one or more calls to splitter +reassemble(), the last of which calls process(). The reassembled buffer +returned to the framework is already ready for detection and the subsequent +eval() call does nothing. + +NHttpFlowData is a data class representing all NHI information relating to a +flow. It serves as persistent memory between invocations of NHI by the +framework. It also glues together the inspector, the client-to-server splitter, +and the server-to-client splitter which pass information through the flow data. + +Message section is a core concept of NHI. A message section is a piece of an +HTTP message that is processed together. There are six types of message +section: + +1. Request line (client-to-server start line) +2. Status line (server-to-client start line) +3. Headers (all headers after the start line as a group) +4. Message body (a block of message data usually not much larger than 16K) +5. Chunked message body (same but from a chunked body) +6. Trailers (all header lines following a chunked body as a group) + +Message sections are represented by message section objects that contain and +process them. There are nine message section classes that inherit as follows. +An asterisk denotes a virtual class. + +1. NHttpMsgSection* - top level with all common elements +2. NHttpMsgStart* : NHttpMsgSection - common elements of request and status +3. NHttpMsgRequest : NHttpMsgStart +4. NHttpMsgStatus : NHttpMsgStart +5. NHttpMsgHeadShared* : NHttpMsgSection - common elements of header and trailer +6. NHttpMsgHeader : NHttpMsgHeadShared +7. NHttpMsgTrailer : NHttpMsgHeadShared +8. NHttpMsgBody : NHttpMsgSection - message body processing in general +9. NHttpMsgChunk : NHttpMsgBody - special features of chunked bodies + +An NHttpTransaction is a container that keeps all the sections of a message +together and associates the request message with the response message. +Transactions may be organized into pipelines when an HTTP pipeline is present. +The current transaction and any pipeline live in the flow data. A transaction +may have only a request because the response is not (yet) received or only a +response because the corresponding request is unknown or unavailable. + +The attach_my_transaction() factory method contains all the logic that makes +this work. There are many corner cases. Don't mess with it until you fully +understand it. + +Message sections implement the Just-In-Time (JIT) principle for work products. +A mimimum of essential processing is done under process(). Other work products +are derived and stored the first time detection or some other customer asks for +them. The Field class is an important tool for managing JIT. It consists of a +pointer to a raw message field or derived work product with a length field. +Various negative length values specify the status of the field. For instance +STAT_NOTCOMPUTE means the item has not been computed yet, STAT_NOTPRESENT +means the item does not exist, and STAT_PROBLEMATIC means an attempt to compute +the item failed. Never dereference the pointer without first checking the +length value. + +All of these values and more are in nhttp_enums.h which is a general repository +for enumerated values in NHI. + +The NHI internal test tool is the NHttpTestInput class. It allows the developer +to write tests that simulate HTTP messages split into TCP segments at specified +points. The tests cover all of splitter and inspector and the impact on +downstream customers such as detection and file processing. A growing set of +tests is maintained in nhttp_test_msgs.txt. Read the header of that file for +documentation of how to write tests. + diff --git a/src/service_inspectors/nhttp_inspect/nhttp_test_input.cc b/src/service_inspectors/nhttp_inspect/nhttp_test_input.cc index 6f3611575..63475f625 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_test_input.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_test_input.cc @@ -152,6 +152,9 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id, else if ((command_length == strlen("break")) && !memcmp(command_value, "break", strlen("break"))) { + // Data leftover from previous test? Trash it. + previous_offset = 0; + data = msg_buf; need_break = true; } else if ((command_length == strlen("tcpclose")) && !memcmp(command_value, @@ -159,6 +162,26 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id, { tcp_closed = true; } + else if ((command_length > 4) && !memcmp(command_value, "fill", 4)) + { + int amount = 0; + for (int k = 4; k < command_length; k++) + { + if ((command_value[k] >= '0') && (command_value[k] <= '9')) + { + amount = amount * 10 + (command_value[k] - '0'); + assert(amount <= 2*MAX_OCTETS); + } + } + assert(amount > 0); + for (int k = 0; k < amount; k++) + { + // auto-fill ABCDEFGHIJABCD ... + data[length++] = 'A' + k%10; + } + end_offset = previous_offset + length; + return; + } else if (command_length > 0) { // Look for a test number diff --git a/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt b/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt index 5686242db..d6bbf12cb 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt +++ b/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt @@ -867,214 +867,72 @@ Accept-Language: is\r\n HTTP/1.1 200 Example with exactly 16384 octets\r\nTransfer-Encoding: chunked\r\n\r\n 400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -400\r\n -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234\r\n +@fill 1024 +\r\n400\r\n -0\r\n\r\n +@fill 1024 +\r\n0\r\n\r\n + +@9004 +@break +@response +HTTP/1.1 200 Example with various features including this illegal character\xAB!?\r\nTransfer-Encoding: identity,chunked\r\n\r\n +20\r\n1234567890abcdef + +fedcba0987654321\r + +\n012 ;messy chunk header\r\nxy + +1234567890ABCDEF + +\r\n10000\r\n + +@fill 65536 + +\r\n00000000000000000; lots: ofzeros\r\nx-madeupheader: 1234\r\n\r\n # *********************************************************************************************** # Invalid chunks diff --git a/src/service_inspectors/pop/dev_notes.txt b/src/service_inspectors/pop/dev_notes.txt new file mode 100644 index 000000000..d13a9e30c --- /dev/null +++ b/src/service_inspectors/pop/dev_notes.txt @@ -0,0 +1,8 @@ +This directory contains all files related to POP protocol processing. + +The protocol aware flushing for POP determines POP PDU and this reassembled +POP PDU is processed by the POP inspector. Both POP commands/responses are +parsed and the MIME attachments in POP responses are processed using the +file API. The file API extracts and decodes the attachments. file_data is +then set to the start of these extracted/decoded attachments. This +inspector also identifies and whitelists the POPS traffic. diff --git a/src/service_inspectors/pop/pop.cc b/src/service_inspectors/pop/pop.cc index 6a95d4b9f..d85325684 100644 --- a/src/service_inspectors/pop/pop.cc +++ b/src/service_inspectors/pop/pop.cc @@ -15,13 +15,9 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * POP preprocessor - * Author: Bhagyashree Bantwal < bbantwal@cisco.com> - * - */ +// pop.cc author Bhagyashree Bantwal < bbantwal@cisco.com> + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/service_inspectors/pop/pop.h b/src/service_inspectors/pop/pop.h index 47d6eb4ea..4a82a660e 100644 --- a/src/service_inspectors/pop/pop.h +++ b/src/service_inspectors/pop/pop.h @@ -15,54 +15,37 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * pop.h: Definitions, structs, function prototype(s) for - * the POP service inspectors. - * Author: Bhagyashree Bantwal - */ +// pop.h author Bhagyashree Bantwal #ifndef POP_H #define POP_H +// Implementation header with definitions, datatypes and flowdata class for +// POP service inspector. + #include "protocols/packet.h" #include "stream/stream_api.h" -#include "profiler.h" +#include "time/profiler.h" #include "pop_config.h" -/* Direction packet is coming from, if we can figure it out */ + +// Direction packet is coming from, if we can figure it out #define POP_PKT_FROM_UNKNOWN 0 #define POP_PKT_FROM_CLIENT 1 #define POP_PKT_FROM_SERVER 2 -#define SEARCH_CMD 0 -#define SEARCH_RESP 1 -#define SEARCH_HDR 2 -#define SEARCH_DATA_END 3 -#define NUM_SEARCHES 4 - -#define BOUNDARY 0 - -#define STATE_DATA 0 /* Data state */ -#define STATE_TLS_CLIENT_PEND 1 /* Got STARTTLS */ -#define STATE_TLS_SERVER_PEND 2 /* Got STARTTLS */ -#define STATE_TLS_DATA 3 /* Successful handshake, TLS encrypted data */ +#define STATE_DATA 0 // Data state +#define STATE_TLS_CLIENT_PEND 1 // Got STARTTLS +#define STATE_TLS_SERVER_PEND 2 // Got STARTTLS +#define STATE_TLS_DATA 3 // Successful handshake, TLS encrypted data #define STATE_COMMAND 4 #define STATE_UNKNOWN 5 -#define STATE_DATA_INIT 0 -#define STATE_DATA_HEADER 1 /* Data header section of data state */ -#define STATE_DATA_BODY 2 /* Data body section of data state */ -#define STATE_MIME_HEADER 3 /* MIME header section within data section */ -#define STATE_DATA_UNKNOWN 4 - -/* session flags */ +// session flags #define POP_FLAG_NEXT_STATE_UNKNOWN 0x00000004 #define POP_FLAG_GOT_NON_REBUILT 0x00000008 #define POP_FLAG_CHECK_SSL 0x00000010 -/* Maximum length of header chars before colon, based on Exim 4.32 exploit */ -#define MAX_HEADER_NAME_LEN 64 typedef enum _POPCmdEnum { CMD_APOP = 0, @@ -111,13 +94,6 @@ struct POPToken int search_id; }; -struct POPCmdConfig -{ - char alert; /* 1 if alert when seen */ - char normalize; /* 1 if we should normalize this command */ - int max_line_len; /* Max length of this particular command */ -}; - struct POPSearchInfo { int id; @@ -149,4 +125,3 @@ public: }; #endif - diff --git a/src/service_inspectors/pop/pop_config.h b/src/service_inspectors/pop/pop_config.h index f7e65fda7..cf4bf8a86 100644 --- a/src/service_inspectors/pop/pop_config.h +++ b/src/service_inspectors/pop/pop_config.h @@ -19,12 +19,12 @@ #ifndef POP_CONFIG_H #define POP_CONFIG_H +// Configuration for Pop service inspector #include "file_api/file_api.h" struct POP_PROTO_CONF { - uint32_t memcap; DecodeConfig decode_conf; MAIL_LogConfig log_config; }; diff --git a/src/service_inspectors/pop/pop_module.h b/src/service_inspectors/pop/pop_module.h index 20b95fd6e..6692a4483 100644 --- a/src/service_inspectors/pop/pop_module.h +++ b/src/service_inspectors/pop/pop_module.h @@ -25,6 +25,7 @@ #include "framework/bits.h" #include "main/thread.h" #include "pop_config.h" +// Interface to the IMAP service inspector #define GID_POP 142 @@ -67,4 +68,3 @@ private: }; #endif - diff --git a/src/service_inspectors/pop/pop_paf.h b/src/service_inspectors/pop/pop_paf.h index 21d16864a..04817c231 100644 --- a/src/service_inspectors/pop/pop_paf.h +++ b/src/service_inspectors/pop/pop_paf.h @@ -1,63 +1,66 @@ -/**************************************************************************** - * Copyright (C) 2015 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. - * - ****************************************************************************/ +//-------------------------------------------------------------------------- +// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2011-2013 Sourcefire, Inc. +// +// 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. +//-------------------------------------------------------------------------- + +// pop_paf.h author: Hui Cao #ifndef POP_PAF_H #define POP_PAF_H -#include "snort_types.h" +// Protocol aware flushing for POP. + +#include "main/snort_types.h" #include "stream/stream_api.h" #include "stream/stream_splitter.h" #include "file_api/file_api.h" -/* Structure used to record expected server termination sequence */ +// Structure used to record expected server termination sequence enum PopExpectedResp { - POP_PAF_SINGLE_LINE_STATE, /* server response will end with \r\n */ - POP_PAF_MULTI_LINE_STATE, /* server response will end with \r\n.\r\n */ - POP_PAF_DATA_STATE, /* Indicated MIME will be contained in response */ - POP_PAF_HAS_ARG /* Intermediate state when parsing LIST */ + POP_PAF_SINGLE_LINE_STATE, // server response will end with \r\n + POP_PAF_MULTI_LINE_STATE, // server response will end with \r\n.\r\n + POP_PAF_DATA_STATE, // Indicated MIME will be contained in response + POP_PAF_HAS_ARG // Intermediate state when parsing LIST }; enum PopParseCmdState { - POP_CMD_SEARCH, /* Search for Command */ - POP_CMD_FIN, /* Found space. Finished parsing Command */ - POP_CMD_ARG /* Parsing command with multi-line response iff arg given */ + POP_CMD_SEARCH, // Search for Command + POP_CMD_FIN, // Found space. Finished parsing Command + POP_CMD_ARG // Parsing command with multi-line response iff arg given }; -/* saves data when parsing client commands */ +// saves data when parsing client commands struct PopPafParseCmd { - const char* next_letter; /* a pointer to the current commands data */ - PopExpectedResp exp_resp; /* the expected termination sequence for this command */ - PopParseCmdState status; /* whether the current has already been found */ + const char* next_letter; // a pointer to the current commands data + PopExpectedResp exp_resp; // the expected termination sequence for this command + PopParseCmdState status; // whether the current has already been found }; -/* State tracker for POP PAF */ +// State tracker for POP PAF struct PopPafData { - PopExpectedResp pop_state; /* The current POP PAF state. */ - PopPafParseCmd cmd_state; /* all of the command parsing data */ - DataEndState end_state; /* Current termination sequence state */ - MimeDataPafInfo data_info; /* Mime Information */ - bool cmd_continued; /* data continued from previous packet? */ + PopExpectedResp pop_state; // The current POP PAF state. + PopPafParseCmd cmd_state; // all of the command parsing data + DataEndState end_state; // Current termination sequence state + MimeDataPafInfo data_info; // Mime Information + bool cmd_continued; // data continued from previous packet? bool end_of_data; }; @@ -76,6 +79,7 @@ public: PopPafData state; }; +// Function: Callback to check if POP data end is reached bool pop_is_data_end(void* ssn); #endif diff --git a/src/service_inspectors/rpc_decode/dev_notes.txt b/src/service_inspectors/rpc_decode/dev_notes.txt new file mode 100644 index 000000000..3207316d8 --- /dev/null +++ b/src/service_inspectors/rpc_decode/dev_notes.txt @@ -0,0 +1,8 @@ +This directory contains all files related to RPC Decode inspector. + +RPC Decode inspector normalizes the RPC requests from remote machines by +converting all fragments into one continuous stream. This is very useful +for doing things like defeating hostile attackers trying to stealth +themselves from IDS by fragmenting the request so the string 0186A0 is +broken up. RPC Decode will alert when multiple queries are in a given +packet, when a complete query exceeds the packet size. diff --git a/src/service_inspectors/rpc_decode/rpc_module.h b/src/service_inspectors/rpc_decode/rpc_module.h index 2ce407ba1..2a5ca79a5 100644 --- a/src/service_inspectors/rpc_decode/rpc_module.h +++ b/src/service_inspectors/rpc_decode/rpc_module.h @@ -20,6 +20,7 @@ #ifndef RPC_MODULE_H #define RPC_MODULE_H +// Interface to the RPC decode service inspector #include "framework/module.h" #include "framework/bits.h" @@ -54,4 +55,3 @@ public: }; #endif - diff --git a/src/service_inspectors/sip/dev_notes.txt b/src/service_inspectors/sip/dev_notes.txt new file mode 100644 index 000000000..71a638667 --- /dev/null +++ b/src/service_inspectors/sip/dev_notes.txt @@ -0,0 +1,23 @@ +Session Initiation Protocol (SIP) is an application-layer control +(signaling) protocol for creating, modifying, and terminating sessions +with one or more participants. These sessions include Internet telephone +calls, multimedia distribution, and multimedia conferences. SIP inspector +provides ways to tackle Common Vulnerabilities and Exposures (CVEs) related +with SIP found over the past few years. It also makes detecting new attacks +easier. + +SIP inspector scans the message headers and tracks dialogs. + +* Alert on malformed headers such as Call-ID, Via, To, From, CSeq, +Contact, Content-Type, Content-length etc. + +* SIP is based on an HTTP-like request/response transaction model. SIP +inspector tracks those dialogs in a linked list. To save memory, it tracks +limited number of dialogs that can be configured. + +* SIP inspector also processes SDP (message body) to track media +sessions. + +The media session information can help AppID identification and improves +performance by ignoring those media flows. + diff --git a/src/service_inspectors/sip/sip.h b/src/service_inspectors/sip/sip.h index deacfa961..d3927a9d4 100644 --- a/src/service_inspectors/sip/sip.h +++ b/src/service_inspectors/sip/sip.h @@ -17,17 +17,13 @@ //-------------------------------------------------------------------------- // -/* - * sip.h: Definitions, structs, function prototype(s) for - * the SIP service inspectors. - */ - #ifndef SIP_H #define SIP_H +// Implementation header with definitions, datatypes and flowdata class for SIP service inspector. #include "protocols/packet.h" #include "stream/stream_api.h" -#include "profiler.h" +#include "time/profiler.h" #include "sip_config.h" #include "sip_dialog.h" #include "sip_parser.h" @@ -58,9 +54,9 @@ public: static unsigned flow_id; SIPData session; }; - +// API to get SIP flow data from the packet flow SIPData* get_sip_session_data(Flow* flow); +// API to add SIP method SIPMethodNode *add_sip_method(char *tok); -#endif /* SIP_H */ - +#endif diff --git a/src/service_inspectors/sip/sip_common.h b/src/service_inspectors/sip/sip_common.h index 435601bab..f553472c9 100644 --- a/src/service_inspectors/sip/sip_common.h +++ b/src/service_inspectors/sip/sip_common.h @@ -16,35 +16,36 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -// sip_common.h -// Author: Hui Cao + +// sip_common.h author Hui Cao #ifndef SIP_COMMON_H #define SIP_COMMON_H +// Header containing datatypes/definitions shared by SSL inspector files. + typedef enum _SIP_method { - SIP_METHOD_NULL = 0, //0x0000, - SIP_METHOD_INVITE = 1, //0x0001, - SIP_METHOD_CANCEL = 2, //0x0002, - SIP_METHOD_ACK = 3, //0x0004, - SIP_METHOD_BYE = 4, //0x0008, - SIP_METHOD_REGISTER = 5, //0x0010, - SIP_METHOD_OPTIONS = 6, //0x0020, - SIP_METHOD_REFER = 7, //0x0040, - SIP_METHOD_SUBSCRIBE = 8, //0x0080, - SIP_METHOD_UPDATE = 9, //0x0100, - SIP_METHOD_JOIN = 10,//0x0200, - SIP_METHOD_INFO = 11,//0x0400, - SIP_METHOD_MESSAGE = 12,//0x0800, - SIP_METHOD_NOTIFY = 13,//0x1000, - SIP_METHOD_PRACK = 14,//0x2000, - SIP_METHOD_USER_DEFINE = 15,//0x4000, - SIP_METHOD_USER_DEFINE_MAX = 32//0x80000000, + SIP_METHOD_NULL = 0, // 0x0000, + SIP_METHOD_INVITE = 1, // 0x0001, + SIP_METHOD_CANCEL = 2, // 0x0002, + SIP_METHOD_ACK = 3, // 0x0004, + SIP_METHOD_BYE = 4, // 0x0008, + SIP_METHOD_REGISTER = 5, // 0x0010, + SIP_METHOD_OPTIONS = 6, // 0x0020, + SIP_METHOD_REFER = 7, // 0x0040, + SIP_METHOD_SUBSCRIBE = 8, // 0x0080, + SIP_METHOD_UPDATE = 9, // 0x0100, + SIP_METHOD_JOIN = 10, // 0x0200, + SIP_METHOD_INFO = 11, // 0x0400, + SIP_METHOD_MESSAGE = 12, // 0x0800, + SIP_METHOD_NOTIFY = 13, // 0x1000, + SIP_METHOD_PRACK = 14, // 0x2000, + SIP_METHOD_USER_DEFINE = 15, // 0x4000, + SIP_METHOD_USER_DEFINE_MAX = 32// 0x80000000, } SIPMethodsFlag; -typedef struct _SipHeaders +struct SipHeaders { const char* callid; const char* from; @@ -58,61 +59,61 @@ typedef struct _SipHeaders uint16_t userNameLen; SIPMethodsFlag methodFlag; -} SipHeaders; +}; -typedef enum _SIP_DialogState +enum SIP_DialogState { - SIP_DLG_CREATE = 1, //1 - SIP_DLG_INVITING, //2 - SIP_DLG_EARLY, //3 - SIP_DLG_AUTHENCATING, //4 - SIP_DLG_ESTABLISHED, //5 - SIP_DLG_REINVITING, //6 - SIP_DLG_TERMINATING, //7 - SIP_DLG_TERMINATED //8 -} SIP_DialogState; - -typedef struct _SIP_MediaData + SIP_DLG_CREATE = 1, // 1 + SIP_DLG_INVITING, // 2 + SIP_DLG_EARLY, // 3 + SIP_DLG_AUTHENCATING, // 4 + SIP_DLG_ESTABLISHED, // 5 + SIP_DLG_REINVITING, // 6 + SIP_DLG_TERMINATING, // 7 + SIP_DLG_TERMINATED // 8 +}; + +struct SIP_MediaData { sfip_t maddress; // media IP uint16_t mport; // media port uint8_t numPort; // number of media ports - struct _SIP_MediaData* nextM; -} SIP_MediaData; + SIP_MediaData* nextM; +} ; typedef SIP_MediaData* SIP_MediaDataList; -typedef struct _SIP_MediaSession +struct SIP_MediaSession { uint32_t sessionID; // a hash value of the session int savedFlag; // whether this data has been saved by a dialog, // if savedFlag = 1, this session will be deleted after sip message is // processed. - sfip_t maddress_default; //Default media IP - SIP_MediaDataList medias; //Media list in the session - struct _SIP_MediaSession* nextS; // Next media session -} SIP_MediaSession; + sfip_t maddress_default; // Default media IP + SIP_MediaDataList medias; // Media list in the session + SIP_MediaSession* nextS; // Next media session +}; typedef SIP_MediaSession* SIP_MediaList; -typedef struct _SipDialog +struct SipDialog { SIP_DialogState state; SIP_MediaList mediaSessions; bool mediaUpdated; -} SipDialog; +}; -typedef struct _SipEventData +struct SipEventData { const Packet* packet; const SipHeaders* headers; const SipDialog* dialog; -} SipEventData; +}; -typedef enum _SipEventType +enum SipEventType { SIP_EVENT_TYPE_SIP_DIALOG -} SipEventType; +}; -#endif /* SIP_COMMON_H */ +#endif diff --git a/src/service_inspectors/sip/sip_config.cc b/src/service_inspectors/sip/sip_config.cc index e5a1cc671..30c55b7f2 100644 --- a/src/service_inspectors/sip/sip_config.cc +++ b/src/service_inspectors/sip/sip_config.cc @@ -16,14 +16,8 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * SIP preprocessor - * Author: Hui Cao - * - * - */ +// sip_config.cc author Hui Cao #include "sip_config.h" #include "util.h" diff --git a/src/service_inspectors/sip/sip_config.h b/src/service_inspectors/sip/sip_config.h index 764d554e0..e1fc3660e 100644 --- a/src/service_inspectors/sip/sip_config.h +++ b/src/service_inspectors/sip/sip_config.h @@ -16,17 +16,18 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -//Author: Hui Cao +// sip_config.h author Hui Cao #ifndef SIP_CONFIG_H #define SIP_CONFIG_H +// Configuration for SIP service inspector + #include "protocols/packet.h" -#include "sip_common.h" #include "framework/counts.h" #include "main/thread.h" +#include "sip_common.h" #define SIP_METHOD_DEFAULT 0x003f #define SIP_METHOD_ALL 0xffffffff @@ -66,9 +67,8 @@ struct SIP_Stats extern THREAD_LOCAL SIP_Stats sip_stats; -/* - * Header fields and processing functions - */ + +// Header fields and processing functions struct SIPMethod { const char* name; @@ -87,47 +87,40 @@ struct SIPMethodNode typedef SIPMethodNode* SIPMethodlist; -/* -* SIP configuration. -* -* maxNumSessions: Maximum amount of run-time memory -* methods: Which methods to check -* maxUriLen: Maximum requst_URI size -* maxCallIdLen: Maximum call_ID size. -* maxRequestNameLen: Maximum length of request name in the CSeqID. -* maxFromLen: Maximum From field size -* maxToLen: Maximum To field size -* maxViaLen: Maximum Via field size -* maxContactLen: Maximum Contact field size -* maxContentLen: Maximum Content length -* ignoreChannel: Whether to ignore media channels found by SIP PP -*/ +// SIP configuration. + struct SIP_PROTO_CONF { - uint32_t maxNumSessions; + uint32_t maxNumSessions; // Maximum amount of run-time memory uint32_t maxNumDialogsInSession; uint32_t methodsConfig; - SIPMethodlist methods; - uint16_t maxUriLen; - uint16_t maxCallIdLen; - uint16_t maxRequestNameLen; - uint16_t maxFromLen; - uint16_t maxToLen; - uint16_t maxViaLen; - uint16_t maxContactLen; - uint16_t maxContentLen; - uint8_t ignoreChannel; + SIPMethodlist methods; // Which methods to check + uint16_t maxUriLen; // Maximum requst_URI size + uint16_t maxCallIdLen; // Maximum call_ID size. + uint16_t maxRequestNameLen; // Maximum length of request name in the CSeqID. + uint16_t maxFromLen; // Maximum From field size + uint16_t maxToLen; // Maximum To field size + uint16_t maxViaLen; // Maximum Via field size + uint16_t maxContactLen; // Maximum Contact field size + uint16_t maxContentLen; // Maximum Content length + uint8_t ignoreChannel; // Whether to ignore media channels found by SIP PP }; +// API to parse method list void SIP_ParseMethods( const char* cur_tokenp, uint32_t* methodsConfig, SIPMethodlist* pmethods); +// Sets the Default method lists void SIP_SetDefaultMethods(SIP_PROTO_CONF* config); + +// API to find a method int SIP_findMethod(char* token, SIPMethod* methods); +// API to add a user defined method to SIP config SIPMethodNode* SIP_AddUserDefinedMethod( const char* methodName, uint32_t* methodsConfig, SIPMethodlist* pmethods); +// API to delete a method from SIP config void SIP_DeleteMethods(SIPMethodNode*); #endif diff --git a/src/service_inspectors/sip/sip_dialog.cc b/src/service_inspectors/sip/sip_dialog.cc index 8a38ca28b..3099e5aee 100644 --- a/src/service_inspectors/sip/sip_dialog.cc +++ b/src/service_inspectors/sip/sip_dialog.cc @@ -16,9 +16,8 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -//Author: Hui Cao +// sip_dialog.cc author Hui Cao #include "sip_dialog.h" diff --git a/src/service_inspectors/sip/sip_dialog.h b/src/service_inspectors/sip/sip_dialog.h index 819c868d2..2941ca1ed 100644 --- a/src/service_inspectors/sip/sip_dialog.h +++ b/src/service_inspectors/sip/sip_dialog.h @@ -16,13 +16,14 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -//Author: Hui Cao +// sip_dialog.h author Hui Cao #ifndef SIP_DIALOG_H #define SIP_DIALOG_H +// Dialog management for SIP call flow analysis + #include "sip_config.h" #include "sip_parser.h" @@ -35,25 +36,25 @@ #define RESPONSE6XX 6 #define TOTAL_REQUESTS 0 -typedef struct _SIP_DialogData +struct SIP_DialogData { SIP_DialogID dlgID; SIP_DialogState state; SIPMethodsFlag creator; uint16_t status_code; SIP_MediaList mediaSessions; - struct _SIP_DialogData* nextD; - struct _SIP_DialogData* prevD; -} SIP_DialogData; + struct SIP_DialogData* nextD; + struct SIP_DialogData* prevD; +}; -typedef struct _SIP_DialogList +struct SIP_DialogList { SIP_DialogData* head; uint32_t num_dialogs; -}SIP_DialogList; +}; int SIP_updateDialog(SIPMsg* sipMsg, SIP_DialogList* dList, Packet* p, SIP_PROTO_CONF*); void sip_freeDialogs(SIP_DialogList* list); -#endif /* SIP_DIALOG_H */ +#endif diff --git a/src/service_inspectors/sip/sip_module.h b/src/service_inspectors/sip/sip_module.h index 2ff0553d0..3ac9b0eb9 100644 --- a/src/service_inspectors/sip/sip_module.h +++ b/src/service_inspectors/sip/sip_module.h @@ -21,6 +21,8 @@ #ifndef SIP_MODULE_H #define SIP_MODULE_H +// Interface to the SIP service inspector + #include "framework/module.h" #include "framework/bits.h" #include "main/thread.h" diff --git a/src/service_inspectors/sip/sip_parser.cc b/src/service_inspectors/sip/sip_parser.cc index 7b03f0cf6..019b78d61 100644 --- a/src/service_inspectors/sip/sip_parser.cc +++ b/src/service_inspectors/sip/sip_parser.cc @@ -17,7 +17,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -//Author: Hui Cao +// sip_parser.cc author Hui Cao #ifdef HAVE_CONFIG_H #include "config.h" @@ -41,7 +41,7 @@ #define SIP_PARSE_ERROR (-1) #define SIP_PARSE_SUCCESS (1) -/*Should at least have SIP/2.0 */ +/* Should at least have SIP/2.0 */ #define SIP_KEYWORD "SIP/" #define SIP_KEYWORD_LEN 4 #define SIP_VERSION_NUM_LEN 3 /*2.0 or 1.0 or 1.1*/ diff --git a/src/service_inspectors/sip/sip_parser.h b/src/service_inspectors/sip/sip_parser.h index 8362671d7..7e0257faa 100644 --- a/src/service_inspectors/sip/sip_parser.h +++ b/src/service_inspectors/sip/sip_parser.h @@ -16,23 +16,24 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -//Author: Hui Cao +// sip_parser.h author Hui Cao #ifndef SIP_PARSER_H #define SIP_PARSER_H +// functions for parsing and querying SIP configuration + #include "sip_config.h" -typedef struct _SIP_DialogID +struct SIP_DialogID { uint32_t callIdHash; uint32_t fromTagHash; uint32_t toTagHash; -} SIP_DialogID; +}; -typedef struct _SIPMsg +struct SIPMsg { uint16_t headerLen; uint16_t methodLen; @@ -55,7 +56,7 @@ typedef struct _SIPMsg SIP_MediaSession* mediaSession; char* authorization; const uint8_t* header; - const uint8_t* body_data; /* Set to NULL if not applicable */ + const uint8_t* body_data; // Set to NULL if not applicable uint64_t cseqnum; uint16_t userNameLen; @@ -63,8 +64,7 @@ typedef struct _SIPMsg uint16_t serverLen; bool mediaUpdated; - /* nothing after this point is zeroed ... - Input parameters*/ + // nothing after this point is zeroed ... Input parameters unsigned char isTcp; char* method; char* uri; @@ -83,7 +83,7 @@ typedef struct _SIPMsg const char* userAgent; const char* userName; const char* server; -} SIPMsg; +}; #define SIPMSG_ZERO_LEN offsetof(SIPMsg, isTcp) diff --git a/src/service_inspectors/sip/sip_roptions.h b/src/service_inspectors/sip/sip_roptions.h index 02b6b280e..479265a4d 100644 --- a/src/service_inspectors/sip/sip_roptions.h +++ b/src/service_inspectors/sip/sip_roptions.h @@ -16,43 +16,40 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -//Author: Hui Cao +// sip_roptions.h author Hui Cao #ifndef SIP_ROPTIONS_H #define SIP_ROPTIONS_H +// Definitions of sip rule option structures. + #include "sip_config.h" #define SIP_NUM_STAT_CODE_MAX 20 -/******************************************************************** - * Structures - ********************************************************************/ -typedef struct _SIP_Roptions + +struct SIP_Roptions { - /* sip_method data*/ - SIPMethodsFlag methodFlag; - /* sip_stat_code data*/ - uint16_t status_code; - /* sip header data */ - const uint8_t* header_data; /* Set to NULL if not applicable */ + SIPMethodsFlag methodFlag; // sip_method data + uint16_t status_code; // sip_stat_code data + + const uint8_t* header_data; // Set to NULL if not applicable uint16_t header_len; - /* sip body data */ - const uint8_t* body_data; /* Set to NULL if not applicable */ + + const uint8_t* body_data; // Set to NULL if not applicable uint16_t body_len; -} SIP_Roptions; +}; -typedef struct _SipMethodRuleOptData +struct SipMethodRuleOptData { int flags; int mask; -} SipMethodRuleOptData; +}; -typedef struct _SipStatCodeRuleOptData +struct SipStatCodeRuleOptData { uint16_t stat_codes[SIP_NUM_STAT_CODE_MAX]; -} SipStatCodeRuleOptData; +}; -#endif /* SIP_ROPTIONS_H */ +#endif diff --git a/src/service_inspectors/sip/sip_utils.cc b/src/service_inspectors/sip/sip_utils.cc index 0436ee191..15225cbc1 100644 --- a/src/service_inspectors/sip/sip_utils.cc +++ b/src/service_inspectors/sip/sip_utils.cc @@ -16,9 +16,8 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -//Author: Hui Cao +// sip_utils.cc author: Hui Cao #include "sip_utils.h" diff --git a/src/service_inspectors/sip/sip_utils.h b/src/service_inspectors/sip/sip_utils.h index 29f352ba1..750f16f40 100644 --- a/src/service_inspectors/sip/sip_utils.h +++ b/src/service_inspectors/sip/sip_utils.h @@ -16,20 +16,21 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -//Author: Hui Cao +// sip_utils.h author Hui Cao #ifndef SIP_UTILS_H #define SIP_UTILS_H -#include "sip_config.h" -#include "sfhashfcn.h" +// Utility functions for SIP inspector + +#include "hash/sfhashfcn.h" #include "sip_config.h" int SIP_IsEmptyStr(char*); int SIP_TrimSP(const char*, const char*, char**, char**); SIPMethodNode* SIP_FindMethod(SIPMethodlist, char*, unsigned int); uint32_t strToHash(const char*, int); -#endif /* SIP_UTILS_H */ + +#endif diff --git a/src/service_inspectors/smtp/dev_notes.txt b/src/service_inspectors/smtp/dev_notes.txt new file mode 100644 index 000000000..730f4fd95 --- /dev/null +++ b/src/service_inspectors/smtp/dev_notes.txt @@ -0,0 +1,12 @@ +This directory contains all files related to SMTP protocol processing. + +The protocol aware flushing for SMTP determines SMTP PDU and this +reassembled SMTP PDU is processed by the SMTP inspector. Both SMTP +requests/responses are parsed and the MIME attachments in SMTP responses +are processed using the file API. The file API extracts and decodes the +attachments. file_data is then set to the start of these extracted/decoded +attachments. This inspector also identifies and whitelists the SMTPS +traffic. + +SMTP inspector logs the filename, email addresses, attachment names when +configured. The SMTP commands are also normalized based on the config. diff --git a/src/service_inspectors/smtp/smtp.cc b/src/service_inspectors/smtp/smtp.cc index 615e639de..a526a24e2 100644 --- a/src/service_inspectors/smtp/smtp.cc +++ b/src/service_inspectors/smtp/smtp.cc @@ -37,6 +37,7 @@ #include "parser.h" #include "framework/inspector.h" #include "utils/sfsnprintfappend.h" +#include "utils/snort_bounds.h" #include "target_based/snort_protocols.h" #include "smtp_paf.h" #include "smtp_util.h" diff --git a/src/service_inspectors/smtp/smtp.h b/src/service_inspectors/smtp/smtp.h index 678576387..cc6314521 100644 --- a/src/service_inspectors/smtp/smtp.h +++ b/src/service_inspectors/smtp/smtp.h @@ -16,27 +16,26 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * smtp.h: Definitions, structs, function prototype(s) for - * the SMTP service inspectors. - * Author: Bhagyashree Bantwal - */ +// smtp.h author Bhagyashree Bantwal #ifndef SMTP_H #define SMTP_H +// Implementation header with definitions, datatypes and flowdata class for +// SMTP service inspector. + #include "protocols/packet.h" #include "stream/stream_api.h" #include "main/thread.h" -#include "profiler.h" +#include "time/profiler.h" #include "smtp_config.h" -/* Direction packet is coming from, if we can figure it out */ +// Direction packet is coming from, if we can figure it out #define SMTP_PKT_FROM_UNKNOWN 0 #define SMTP_PKT_FROM_CLIENT 1 #define SMTP_PKT_FROM_SERVER 2 -/* Inspection type */ +// Inspection type #define SMTP_STATELESS 0 #define SMTP_STATEFUL 1 @@ -49,34 +48,29 @@ #define BOUNDARY 0 #define STATE_CONNECT 0 -#define STATE_COMMAND 1 /* Command state of SMTP transaction */ -#define STATE_DATA 2 /* Data state */ -#define STATE_BDATA 3 /* Binary data state */ -#define STATE_TLS_CLIENT_PEND 4 /* Got STARTTLS */ -#define STATE_TLS_SERVER_PEND 5 /* Got STARTTLS */ -#define STATE_TLS_DATA 6 /* Successful handshake, TLS encrypted data */ +#define STATE_COMMAND 1 // Command state of SMTP transaction +#define STATE_DATA 2 // Data state +#define STATE_BDATA 3 // Binary data state +#define STATE_TLS_CLIENT_PEND 4 // Got STARTTLS +#define STATE_TLS_SERVER_PEND 5 // Got STARTTLS +#define STATE_TLS_DATA 6 // Successful handshake, TLS encrypted data #define STATE_AUTH 7 #define STATE_XEXCH50 8 #define STATE_UNKNOWN 9 #define STATE_DATA_INIT 0 -#define STATE_DATA_HEADER 1 /* Data header section of data state */ -#define STATE_DATA_BODY 2 /* Data body section of data state */ -#define STATE_MIME_HEADER 3 /* MIME header section within data section */ +#define STATE_DATA_HEADER 1 // Data header section of data state +#define STATE_DATA_BODY 2 // Data body section of data state +#define STATE_MIME_HEADER 3 // MIME header section within data section #define STATE_DATA_UNKNOWN 4 -/* state flags */ -#define SMTP_FLAG_GOT_MAIL_CMD 0x00000001 -#define SMTP_FLAG_GOT_RCPT_CMD 0x00000002 -#define SMTP_FLAG_BDAT 0x00001000 -#define SMTP_FLAG_ABORT 0x00002000 -/* state flags */ +// state flags #define SMTP_FLAG_GOT_MAIL_CMD 0x00000001 #define SMTP_FLAG_GOT_RCPT_CMD 0x00000002 #define SMTP_FLAG_BDAT 0x00001000 #define SMTP_FLAG_ABORT 0x00002000 -/* session flags */ +// session flags #define SMTP_FLAG_XLINK2STATE_GOTFIRSTCHUNK 0x00000001 #define SMTP_FLAG_XLINK2STATE_ALERTED 0x00000002 #define SMTP_FLAG_NEXT_STATE_UNKNOWN 0x00000004 @@ -89,10 +83,7 @@ SSL_BAD_TYPE_FLAG | \ SSL_UNKNOWN_FLAG) -/* Maximum length of header chars before colon, based on Exim 4.32 exploit */ -#define MAX_HEADER_NAME_LEN 64 - -#define MAX_AUTH_NAME_LEN 20 /* Max length of SASL mechanisms, defined in RFC 4422 */ +#define MAX_AUTH_NAME_LEN 20 // Max length of SASL mechanisms, defined in RFC 4422 enum SMTPRespEnum { @@ -177,4 +168,3 @@ public: extern THREAD_LOCAL bool smtp_normalizing; #endif - diff --git a/src/service_inspectors/smtp/smtp_config.h b/src/service_inspectors/smtp/smtp_config.h index 2b03dad6b..6f29c0656 100644 --- a/src/service_inspectors/smtp/smtp_config.h +++ b/src/service_inspectors/smtp/smtp_config.h @@ -15,13 +15,15 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// #ifndef SMTP_CONFIG_H #define SMTP_CONFIG_H +// Configuration for SMTP inspector + #include "file_api/file_api.h" #include "search_engines/search_tool.h" + enum NORM_TYPES { NORMALIZE_NONE = 0, @@ -100,8 +102,8 @@ enum SMTPCmdTypeEnum struct SMTPCmdConfig { bool alert; - bool normalize; /* 1 if we should normalize this command */ - int max_line_len; /* Max length of this particular command */ + bool normalize; // 1 if we should normalize this command + int max_line_len; // Max length of this particular command }; struct SMTPSearch @@ -142,4 +144,3 @@ struct SMTP_PROTO_CONF }; #endif - diff --git a/src/service_inspectors/smtp/smtp_module.h b/src/service_inspectors/smtp/smtp_module.h index ae8f2537d..206ef0fa2 100644 --- a/src/service_inspectors/smtp/smtp_module.h +++ b/src/service_inspectors/smtp/smtp_module.h @@ -21,6 +21,8 @@ #ifndef SMTP_MODULE_H #define SMTP_MODULE_H +// Interface to the SMTP service inspector + #include "framework/module.h" #include "framework/bits.h" #include "main/thread.h" @@ -39,9 +41,9 @@ #define SMTP_DECODE_MEMCAP_EXCEEDED 9 #define SMTP_B64_DECODING_FAILED 10 #define SMTP_QP_DECODING_FAILED 11 -/* Do not delete or reuse this SID. Commenting this SID as this alert is no longer valid.* - * * #define SMTP_BITENC_DECODING_FAILED 12 - * */ +//FIXIT-L Move up the sids? +// Do not delete or reuse this SID. Commenting this SID as this alert is no longer valid. +//#define SMTP_BITENC_DECODING_FAILED 12 #define SMTP_UU_DECODING_FAILED 13 #define SMTP_AUTH_ABORT_AUTH 14 @@ -104,4 +106,3 @@ private: }; #endif - diff --git a/src/service_inspectors/smtp/smtp_normalize.h b/src/service_inspectors/smtp/smtp_normalize.h index 6fcd09817..301f3041f 100644 --- a/src/service_inspectors/smtp/smtp_normalize.h +++ b/src/service_inspectors/smtp/smtp_normalize.h @@ -1,5 +1,6 @@ //-------------------------------------------------------------------------- -// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2011-2013 Sourcefire, Inc. // // 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 @@ -19,9 +20,10 @@ #ifndef SMTP_NORMALIZE_H #define SMTP_NORMALIZE_H +// Implementation of normalizing SMTP traffic into the alternate buffer + #include "protocols/packet.h" int SMTP_NormalizeCmd(Packet*, const uint8_t*, const uint8_t*, const uint8_t*); #endif - diff --git a/src/service_inspectors/smtp/smtp_paf.h b/src/service_inspectors/smtp/smtp_paf.h index d64e3f916..19cda6c53 100644 --- a/src/service_inspectors/smtp/smtp_paf.h +++ b/src/service_inspectors/smtp/smtp_paf.h @@ -16,21 +16,25 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// smtp_paf.h author Hui Cao + #ifndef SMTP_PAF_H #define SMTP_PAF_H -#include "snort_types.h" +// Protocol aware flushing for SMTP + +#include "main/snort_types.h" #include "stream/stream_api.h" #include "stream/stream_splitter.h" #include "file_api/file_api.h" -/* State tracker for SMTP PAF */ +// State tracker for SMTP PAF enum SmtpPafState { SMTP_PAF_CMD_STATE, SMTP_PAF_DATA_STATE }; -/* State tracker for data command */ +// State tracker for data command typedef enum _SmtpPafCmdState { SMTP_PAF_CMD_UNKNOWN, @@ -47,7 +51,7 @@ struct SmtpCmdSearchInfo const char* search_state; }; -/* State tracker for SMTP PAF */ +// State tracker for SMTP PAF struct SmtpPafData { DataEndState data_end_state; @@ -73,7 +77,7 @@ public: SmtpPafData state; }; +// Function: Check if IMAP data end is reached bool smtp_is_data_end(void* ssn); #endif - diff --git a/src/service_inspectors/smtp/smtp_util.cc b/src/service_inspectors/smtp/smtp_util.cc index 71ff1f4a0..eb93d2846 100644 --- a/src/service_inspectors/smtp/smtp_util.cc +++ b/src/service_inspectors/smtp/smtp_util.cc @@ -16,22 +16,8 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- - /* - * Author: Andy Mullican - * - * Description: - * - * This file contains SMTP helper functions. - * - * Entry point functions: - * - * safe_strchr() - * safe_strstr() - * copy_to_space() - * safe_sscanf() - * - * - */ +// smtp_util.cc author Andy Mullican +// This file contains SMTP helper functions. #include "smtp_util.h" diff --git a/src/service_inspectors/smtp/smtp_util.h b/src/service_inspectors/smtp/smtp_util.h index a9e314624..ea1c60339 100644 --- a/src/service_inspectors/smtp/smtp_util.h +++ b/src/service_inspectors/smtp/smtp_util.h @@ -1,5 +1,6 @@ //-------------------------------------------------------------------------- -// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2011-2013 Sourcefire, Inc. // // 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 @@ -16,18 +17,17 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/************************************************************************* - * - * smtp_util.h - * - * Author: Andy Mullican - * Author: Todd Wease - * - *************************************************************************/ +// smtp_util.h authors Andy Mullican and Todd Wease #ifndef SMTP_UTIL_H #define SMTP_UTIL_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// SMTP helper functions + #include "smtp_config.h" #include "protocols/packet.h" @@ -46,4 +46,3 @@ const uint8_t* SMTP_GetAltBuffer(unsigned& len); void SMTP_ResetAltBuffer(); #endif - diff --git a/src/service_inspectors/smtp/smtp_xlink2state.cc b/src/service_inspectors/smtp/smtp_xlink2state.cc index 6ca0918c1..81b4759d0 100644 --- a/src/service_inspectors/smtp/smtp_xlink2state.cc +++ b/src/service_inspectors/smtp/smtp_xlink2state.cc @@ -1,5 +1,6 @@ //-------------------------------------------------------------------------- -// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2011-2013 Sourcefire, Inc. // // 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 @@ -16,23 +17,8 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- - -/************************************************************************ - * - * smtp_xlink2state.c - * - * Author: Andy Mullican - * - * Description: - * - * This file handles the X-Link2State vulnerability. - * - * Entry point function: - * - * ParseXLink2State() - * - * - ************************************************************************/ +// smtp_xlink2state.c author Andy Mullican +// This file handles the X-Link2State vulnerability. #include "smtp_xlink2state.h" diff --git a/src/service_inspectors/smtp/smtp_xlink2state.h b/src/service_inspectors/smtp/smtp_xlink2state.h index 503c35c07..7f536c4cf 100644 --- a/src/service_inspectors/smtp/smtp_xlink2state.h +++ b/src/service_inspectors/smtp/smtp_xlink2state.h @@ -1,5 +1,6 @@ //-------------------------------------------------------------------------- -// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2011-2013 Sourcefire, Inc. // // 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 @@ -16,17 +17,13 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- - -/************************************************************************* - * smtp_xlink2state.h - * - * Author: Andy Mullican - * - *************************************************************************/ +// smtp_xlink2state.h author Andy Mullican #ifndef SMTP_XLINK2STATE_H #define SMTP_XLINK2STATE_H +// declares the API to handle the X-Link2State vulnerability + #include "protocols/packet.h" #include "smtp.h" #include "smtp_config.h" @@ -34,4 +31,3 @@ int ParseXLink2State(SMTP_PROTO_CONF*, Packet*, SMTPData*, const uint8_t*); #endif - diff --git a/src/service_inspectors/ssh/dev_notes.txt b/src/service_inspectors/ssh/dev_notes.txt new file mode 100644 index 000000000..5701dbba5 --- /dev/null +++ b/src/service_inspectors/ssh/dev_notes.txt @@ -0,0 +1,17 @@ +This directory contains all files related to SSH protocol inspection. + +The SSH inspector processes the stream reassembled packets and detects the +following exploits: Challenge-Response Buffer Overflow, CRC 32, Secure CRT, +and the Protocol Mismatch exploit. + +Both Challenge-Response Overflow and CRC 32 attacks occur after the key +exchange, and are therefore encrypted. Both attacks involve sending a +large payload (20kb+) to the server immediately after the authentication +challenge. To detect the attacks, the SSH inspector counts the number of +bytes transmitted to the server. If those bytes exceed a pre-defined limit +within a pre-define number of packets, an alert is generated. Since +Challenge-Response Overflow only effects SSHv2 and CRC 32 only effects +SSHv1, the SSH version string exchange is used to distinguish the attacks. + +The Secure CRT and protocol mismatch exploits are observable before the key +exchange. diff --git a/src/service_inspectors/ssh/ssh.cc b/src/service_inspectors/ssh/ssh.cc index f83b11525..5fedb6060 100644 --- a/src/service_inspectors/ssh/ssh.cc +++ b/src/service_inspectors/ssh/ssh.cc @@ -16,19 +16,11 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// /* * SSH preprocessor * Author: Chris Sherwin * Contributors: Adam Keeton, Ryan Jordan - * - * - * Alert for Gobbles, CRC32, protocol mismatch (Cisco catalyst vulnerability), - * and a SecureCRT vulnerability. Will also alert if the client or server - * traffic appears to flow the wrong direction, or if packets appear - * malformed/spoofed. - * */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/service_inspectors/ssh/ssh.h b/src/service_inspectors/ssh/ssh.h index 268ffbb70..d5fbc2516 100644 --- a/src/service_inspectors/ssh/ssh.h +++ b/src/service_inspectors/ssh/ssh.h @@ -16,39 +16,33 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * ssh.h: Definitions, structs, function prototype(s) for - * the SSH service inspectors. - * Author: Chris Sherwin - */ +// ssh.h author Chris Sherwin #ifndef SSH_H #define SSH_H +// Implementation header with definitions, datatypes and flowdata class for +// SSH service inspector. + +// Alert for Gobbles, CRC32, protocol mismatch (Cisco catalyst +// vulnerability), and a SecureCRT vulnerability. Will also alert if the +// client or server traffic appears to flow the wrong direction, or if +// packets appear malformed/spoofed. + #include "protocols/packet.h" #include "stream/stream_api.h" -#include "profiler.h" +#include "time/profiler.h" #include "ssh_config.h" -/* - * Per-session data block containing current state - * of the SSH preprocessor for the session. - * - * version: Version of SSH detected for this session. - * num_enc_pkts: Number of encrypted packets seen on this session. - * num_client_bytes: Number of bytes of encrypted data sent by client, - * without a server response. - * state_flags: Bit vector describing the current state of the - * session. - */ +// Per-session data block containing current state +// of the SSH preprocessor for the session. struct SSHData { - uint8_t version; - uint16_t num_enc_pkts; - uint16_t num_client_bytes; - uint32_t state_flags; + uint8_t version; // Version of SSH detected for this session + uint16_t num_enc_pkts; // encrypted packets seen on this session + uint16_t num_client_bytes; // bytes of encrypted data sent by client without a server response + uint32_t state_flags; // Bit vector describing the current state of the session }; class SshFlowData : public FlowData @@ -67,16 +61,8 @@ public: SSHData session; }; - -/* - * * Error codes. - * */ -#define SSH_SUCCESS (1) -#define SSH_FAILURE (0) - -/* - * Session state flags for SSHData::state_flags - */ +// FIXIT-L move these to ssh.cc +// Session state flags for SSHData::state_flags #define SSH_FLG_CLEAR (0x0) #define SSH_FLG_CLIENT_IDSTRING_SEEN (0x1) #define SSH_FLG_SERV_IDSTRING_SEEN (0x2) @@ -98,9 +84,7 @@ public: #define SSH_FLG_REASSEMBLY_SET (0x20000) #define SSH_FLG_AUTODETECTED (0x40000) -/* - * Some convenient combinations of state flags. - */ +// Some convenient combinations of state flags. #define SSH_FLG_BOTH_IDSTRING_SEEN \ (SSH_FLG_CLIENT_IDSTRING_SEEN | \ SSH_FLG_SERV_IDSTRING_SEEN ) @@ -125,43 +109,27 @@ public: SSH_FLG_GEX_REPLY_SEEN | \ SSH_FLG_NEWKEYS_SEEN ) -/* - * SSH version values for SSHData::version - */ +// SSH version values for SSHData::version #define SSH_VERSION_UNKNOWN (0x0) #define SSH_VERSION_1 (0x1) #define SSH_VERSION_2 (0x2) -/* - * Length of SSH2 header, in bytes. - */ +// Length of SSH2 header, in bytes. #define SSH2_HEADERLEN (5) #define SSH2_PACKET_MAX_SIZE (256 * 1024) -/* - * SSH2 binary packet struct. - * - * packet_length: Length of packet in bytes not including - * this field or the mesg auth code (mac) - * padding_length: Length of padding section. - * packet_data: Variable length packet payload + padding + MAC. - */ -typedef struct _ssh2Packet +struct SSH2Packet { - uint32_t packet_length; - uint8_t padding_length; - char packet_data[1]; -} SSH2Packet; - -/* - * SSH v1 message types (of interest) - */ + uint32_t packet_length; // Length not including this field or the mesg auth code (mac) + uint8_t padding_length; // Length of padding section. + char packet_data[1]; // Variable length packet payload + padding + MAC. +}; + +// SSH v1 message types (of interest) #define SSH_MSG_V1_SMSG_PUBLIC_KEY 2 #define SSH_MSG_V1_CMSG_SESSION_KEY 3 -/* - * SSH v2 message types (of interest) - */ +// SSH v2 message types (of interest) #define SSH_MSG_KEXINIT 20 #define SSH_MSG_NEWKEYS 21 #define SSH_MSG_KEXDH_INIT 30 @@ -172,9 +140,8 @@ typedef struct _ssh2Packet #define SSH_MSG_KEXDH_GEX_INIT 32 #define SSH_MSG_KEXDH_GEX_REPLY 31 -/* Direction of sent message. */ +// Direction of sent message. #define SSH_DIR_FROM_SERVER (0x1) #define SSH_DIR_FROM_CLIENT (0x2) -#endif /* SSH_H */ - +#endif diff --git a/src/service_inspectors/ssh/ssh_config.h b/src/service_inspectors/ssh/ssh_config.h index e8d6a8061..937a9c79f 100644 --- a/src/service_inspectors/ssh/ssh_config.h +++ b/src/service_inspectors/ssh/ssh_config.h @@ -16,26 +16,14 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// -/* - * ssh_config.h: Definitions of SSH conf - * Author: Chris Sherwin - */ +// ssh_config.h author Chris Sherwin #ifndef SSH_CONFIG_H #define SSH_CONFIG_H -/* - * Global SSH preprocessor configuration. - * - * MaxEncryptedPackets: Maximum number of encrypted packets examined per - * session. - * MaxClientBytes: Maximum bytes of encrypted data that can be - * sent by client without a server response. - * MaxServerVersionLen: Maximum length of a server's version string. - * Configurable threshold for Secure CRT-style overflow. - */ +// Configuration for SSH service inspector + struct SSH_PROTO_CONF { uint16_t MaxEncryptedPackets; @@ -47,6 +35,4 @@ struct SSH_PROTO_CONF #define SSH_DEFAULT_MAX_CLIENT_BYTES 19600 #define SSH_DEFAULT_MAX_SERVER_VERSION_LEN 80 - #endif - diff --git a/src/service_inspectors/ssh/ssh_module.h b/src/service_inspectors/ssh/ssh_module.h index 9543a502b..5d695c730 100644 --- a/src/service_inspectors/ssh/ssh_module.h +++ b/src/service_inspectors/ssh/ssh_module.h @@ -21,6 +21,8 @@ #ifndef SSH_MODULE_H #define SSH_MODULE_H +// Interface to the SSH service inspector + #include "framework/module.h" #include "framework/bits.h" #include "main/thread.h" @@ -69,4 +71,3 @@ private: }; #endif - diff --git a/src/service_inspectors/ssl/dev_notes.txt b/src/service_inspectors/ssl/dev_notes.txt new file mode 100644 index 000000000..92c80c88f --- /dev/null +++ b/src/service_inspectors/ssl/dev_notes.txt @@ -0,0 +1,29 @@ +This directory contains all files related to SSL inspector. The SSL +inspector inspects stream reassembled SSL and TLS traffic and optionally +determines if and when to stop inspection of it. + +Typically, SSL is used over port 443 as HTTPS. By enabling the SSL +inspector to inspect port 443, only the SSL handshake of each connection +will be inspected. Once the traffic is determined to be encrypted, no +further inspection of the data on the connection is made. + +Each stream reassembled packet containing SSL traffic has an unencrypted +portion that provides some information about the traffic itself, and the +state of the connection. SSL inspector uses this information to determine +whether or not a handshake is occurring or if a handshake previously +occurred. + +By default, SSL inspector looks for a handshake followed by encrypted +traffic traveling to both sides. If one side responds with an indication +that something has failed, such as the handshake, the session is not marked +as encrypted. Verifying that faultless encrypted traffic is sent from both +endpoints ensures two things: the last client-side handshake packet was not +crafted to evade Snort, and that the traffic is legitimately encrypted. + +In some cases, especially when packets may be missed, the only observed +response from one endpoint will be TCP ACKs. Therefore, if a user knows +that server-side encrypted data can be trusted to mark the session as +encrypted, the user should use the 'trustservers' option. + +SSL inspector also inspects the heartbeat records and identifies the +heartbleed evasion. diff --git a/src/service_inspectors/ssl/ssl_config.h b/src/service_inspectors/ssl/ssl_config.h index 5cb28139d..a433c214a 100644 --- a/src/service_inspectors/ssl/ssl_config.h +++ b/src/service_inspectors/ssl/ssl_config.h @@ -15,17 +15,15 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// #ifndef SSL_CONFIG_H #define SSL_CONFIG_H +// Configuration for SSL service inspector + #define SSLPP_TRUSTSERVER_FLAG 0x0002 -/* - * Global SSL preprocessor configuration. - * - */ +//FIXIT-L flags could be converted to bool trustservers. struct SSL_PROTO_CONF { uint16_t flags; @@ -33,4 +31,3 @@ struct SSL_PROTO_CONF }; #endif - diff --git a/src/service_inspectors/ssl/ssl_inspector.h b/src/service_inspectors/ssl/ssl_inspector.h index 2d46ff621..07b18b2fc 100644 --- a/src/service_inspectors/ssl/ssl_inspector.h +++ b/src/service_inspectors/ssl/ssl_inspector.h @@ -15,19 +15,15 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// - -/* - * ssl.h: Definitions, structs, function prototype(s) for - * the SSL service inspectors. - */ #ifndef SSL_INSPECTOR_H #define SSL_INSPECTOR_H +// Implementation header with definitions, datatypes and flowdata class for SSL service inspector. + #include "protocols/packet.h" #include "stream/stream_api.h" -#include "profiler.h" +#include "time/profiler.h" #include "ssl_config.h" #define SSLPP_ENCRYPTED_FLAGS \ @@ -79,9 +75,9 @@ public: static unsigned flow_id; SSLData session; }; - +//Function: API to get the ssl flow data from the packet flow. SSLData* get_ssl_session_data(Flow* flow); -void SSL_InitGlobals(void); -#endif /* SSL_INSPECTOR_H */ +void SSL_InitGlobals(void); +#endif diff --git a/src/service_inspectors/ssl/ssl_module.h b/src/service_inspectors/ssl/ssl_module.h index 01f96f29b..48d7c3c2d 100644 --- a/src/service_inspectors/ssl/ssl_module.h +++ b/src/service_inspectors/ssl/ssl_module.h @@ -21,6 +21,8 @@ #ifndef SSL_MODULE_H #define SSL_MODULE_H +// Interface to the SSL service inspector + #include "framework/module.h" #include "framework/bits.h" #include "main/thread.h" @@ -66,4 +68,3 @@ private: }; #endif - diff --git a/src/service_inspectors/wizard/CMakeLists.txt b/src/service_inspectors/wizard/CMakeLists.txt index 5655fdd74..689525e30 100644 --- a/src/service_inspectors/wizard/CMakeLists.txt +++ b/src/service_inspectors/wizard/CMakeLists.txt @@ -5,7 +5,6 @@ set(FILE_LIST hexes.cc spells.cc wizard.cc - wizard.h wiz_module.cc wiz_module.h ) diff --git a/src/service_inspectors/wizard/Makefile.am b/src/service_inspectors/wizard/Makefile.am index a63576f3d..23182c57a 100644 --- a/src/service_inspectors/wizard/Makefile.am +++ b/src/service_inspectors/wizard/Makefile.am @@ -4,7 +4,7 @@ file_list = \ magic.cc magic.h \ hexes.cc \ spells.cc \ -wizard.cc wizard.h \ +wizard.cc \ wiz_module.cc wiz_module.h if STATIC_INSPECTORS diff --git a/src/service_inspectors/wizard/dev_notes.txt b/src/service_inspectors/wizard/dev_notes.txt new file mode 100644 index 000000000..7caf74daf --- /dev/null +++ b/src/service_inspectors/wizard/dev_notes.txt @@ -0,0 +1,39 @@ +The wizard uses hexes and spells to determine the most likely service on a +flow. It does not determine the service with certainty; that is the job of +the service inspector or appId. The goal is to get the most likely service +inspector engaged as quickly as possible. + +For TCP, the wizard uses a stream splitter to examine the in order data as +it becomes available. If the splitter finds a match, it sets the service +on the flow which will result in a reevaluation of the bindings. If a +service inspector is bound, its spliter is activated and the stream is +rewound to the start. + +The wizard is deactivated from the flow upon finding a match or finding +that there is no possible match. + +Hexes, which support binary protocol matching, and spells, which support +text protocol matching, are similar but deliberately different: + +* spells allow wild cards matching any number of consecutive characters + whereas hexes allow a single wild char. + +* spells are case insensitive whereas hexes are case sensitive. + +* spells automatically skip leading whitespace (at very start of flow). + +Binary protocols are difficult to match with just a short stream prefix. +For example suppose one has the pattern "0x12 ?" and another has "? 0x34". +A match on the first doesn't preclude a match on the second. The current +implementation disregards this possibility and takes the first match. + +Having the various service inspectors provide the patterns was rejected +because it would have made it difficult to swap out the wizard with a new +and different implementation and different pattern logic and syntax. +Encapsulating everything in the wizard allows the patterns to be easily +tweaked as well. + +The current implementation of the magic is very straightforward. Due to +the limited number of patterns, space is not a concern and each state has +256 byte array of pointers to the next. + diff --git a/src/service_inspectors/wizard/magic.h b/src/service_inspectors/wizard/magic.h index a4d0b5ae5..865eae7a9 100644 --- a/src/service_inspectors/wizard/magic.h +++ b/src/service_inspectors/wizard/magic.h @@ -41,6 +41,8 @@ struct MagicPage typedef std::vector HexVector; +// MagicBook is a set of MagicPages implementing a trie + class MagicBook { public: diff --git a/src/service_inspectors/wizard/wiz_module.cc b/src/service_inspectors/wizard/wiz_module.cc index 867841a1a..54dbcfcb4 100644 --- a/src/service_inspectors/wizard/wiz_module.cc +++ b/src/service_inspectors/wizard/wiz_module.cc @@ -26,7 +26,6 @@ #include using namespace std; -#include "wizard.h" #include "magic.h" //------------------------------------------------------------------------- diff --git a/src/service_inspectors/wizard/wiz_module.h b/src/service_inspectors/wizard/wiz_module.h index 47e3c63e0..9b3e15f02 100644 --- a/src/service_inspectors/wizard/wiz_module.h +++ b/src/service_inspectors/wizard/wiz_module.h @@ -21,8 +21,11 @@ #ifndef WIZ_MODULE_H #define WIZ_MODULE_H +// wizard management interface + #include #include + #include "framework/module.h" #include "main/thread.h" diff --git a/src/service_inspectors/wizard/wizard.cc b/src/service_inspectors/wizard/wizard.cc index afcc614b4..e8115f0eb 100644 --- a/src/service_inspectors/wizard/wizard.cc +++ b/src/service_inspectors/wizard/wizard.cc @@ -17,8 +17,6 @@ //-------------------------------------------------------------------------- // wizard.cc author Russ Combs -#include "wizard.h" - #include using namespace std; diff --git a/src/service_inspectors/wizard/wizard.h b/src/service_inspectors/wizard/wizard.h deleted file mode 100644 index 63d82f9a1..000000000 --- a/src/service_inspectors/wizard/wizard.h +++ /dev/null @@ -1,26 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2015 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. -//-------------------------------------------------------------------------- -// wizard.cc author Russ Combs - -#ifndef WIZARD_H -#define WIZARD_H - -#include - -#endif - diff --git a/src/sfip/dev_notes.txt b/src/sfip/dev_notes.txt new file mode 100644 index 000000000..cd333ae3c --- /dev/null +++ b/src/sfip/dev_notes.txt @@ -0,0 +1,9 @@ +This directory contains IP and IP variables related helper functions. + +* Supports basic IP operations and helper functions + +* Provides variable table for storing and looking up variables + +* Supports basic IP variable operations and manages a list of IP variables + through variable table + diff --git a/src/sfip/sf_ip.h b/src/sfip/sf_ip.h index 6899c9630..1208ba622 100644 --- a/src/sfip/sf_ip.h +++ b/src/sfip/sf_ip.h @@ -26,6 +26,9 @@ #ifndef SF_IP_H #define SF_IP_H +// Provides many convenient functions to process IP. It is a small tool box for +// IP operations. + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/src/sfip/sf_ipvar.h b/src/sfip/sf_ipvar.h index f1182dc49..cceee5efe 100644 --- a/src/sfip/sf_ipvar.h +++ b/src/sfip/sf_ipvar.h @@ -26,6 +26,9 @@ #ifndef SF_IPVAR_H #define SF_IPVAR_H +// Supports basic IP variable operations +// Manages a doubly linked list of IP variables for the variable table + /* Flags */ #define SFIP_NEGATED 1 #define SFIP_ANY 2 diff --git a/src/sfip/sf_vartable.h b/src/sfip/sf_vartable.h index 123b88592..2f372df54 100644 --- a/src/sfip/sf_vartable.h +++ b/src/sfip/sf_vartable.h @@ -22,13 +22,14 @@ * sf_vartable.h * 11/17/06 * - * Library for implementing a variable table. * All API calls have the prefix "sfvt". */ #ifndef SF_VARTABLE_H #define SF_VARTABLE_H +// Library for implementing a variable table. + #include #include "sfip/sf_returns.h" diff --git a/src/sfip/sfip_t.h b/src/sfip/sfip_t.h index 10ed5a13d..3773526b3 100644 --- a/src/sfip/sfip_t.h +++ b/src/sfip/sfip_t.h @@ -26,6 +26,10 @@ #ifndef SFIP_SFIP_T_H #define SFIP_SFIP_T_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/src/sfrt/dev_notes.txt b/src/sfrt/dev_notes.txt new file mode 100644 index 000000000..88b3dcc90 --- /dev/null +++ b/src/sfrt/dev_notes.txt @@ -0,0 +1,74 @@ +SFRT implements two different routing table lookup methods that have been +adapted to return a void pointers. Any generic information may be +associated with a given IP or CIDR block. + +As of this writing, the two methods used are Stefan Nilsson and Gunnar +Karlsson's LC-trie, and a multibit-trie method similar to Gupta et-al.'s +DIR-n-m. Presently, the LC-trie is used for testing purposes as the +current implementation does not allow for fast, dynamic inserts. + +The intended use is to associate large IP blocks with specific information. + +NOTE information should only move from less specific to more specific, ie: + + First insert: 1.1.0.0/16 -> some data + Second insert: 1.1.2.3 -> some other data + +As opposed to: + + First insert: 1.1.2.3 -> some other data + Second insert: 1.1.0.0/16 -> some data + +If more general information is to overwrite existing entries, the table +should be free'ed and rebuilt. This is due to the difficulty of cleaning +out stale entries with the current implementation. At runtime, this won't +be a significant issue since inserts should apply to specific IP addresses +and not entire blocks of IPs. + + +*Basic Implementation* + +The routing tables associate an index into a "data" table with each CIDR. +Each entry in the data table stores a pointer to actual data. This +implementation was chosen so each routing entry only needs one word to +either index the data array, or point to another table. + +Inserts are performed by specifying a CIDR and a pointer to its associated +data. Since a new routing table entry may overwrite previous entries, +a flag selects whether the insert favors the most recent or favors the most +specific. Favoring most specific should be the default behvior. If +the user wishes to overwrite routing entries with more general data, the +table should be flushed, rather than using favor-most-recent. + +Before modifying the routing or data tables, the insert function performs a +lookup on the CIDR-to-be-insertted. If no entry or an entry of differing +bit length is found, the data is insertted into the data table, and its +index is used for the new routing table entry. If an entry is found that +is as specific as the new CIDR, the index stored points to where the new +data is written into the data table. + +If more specific CIDR blocks overwrote the data table, then the more +general routing table entries that were not overwritten will be referencing +the wrong data. Alternatively, less specific entries can only overwrite +existing routing table entries if favor-most-recent inserts are used. + +Because there is no quick way to clean the data-table if a user wishes to +use a favor-most-recent insert for more general data, the user should flush +the table with sfrt_free and create one anew. Alternatively, a small +memory leak occurs with the data table, as it will be storing pointers that +no routing table entry cares about. + +The API calls that should be used are: + +* sfrt_new - create new table +* sfrt_insert - insert entry +* sfrt_lookup - lookup entry +* sfrt_free - free table + +*Flat Implementation* + +This is based on the original implementation, but using the flat segment memory. +When allocating memory, it uses memory in the segment, and returns the offset. +When accessing memory, it must use the base address and offset to correctly +refer to it. + diff --git a/src/sfrt/sfrt.cc b/src/sfrt/sfrt.cc index cf0ed547b..687fcb004 100644 --- a/src/sfrt/sfrt.cc +++ b/src/sfrt/sfrt.cc @@ -693,7 +693,7 @@ int sfrt_remove(sfip_t* ip, unsigned char len, GENERIC* ptr, if (!table || !table->data || !table->remove || !table->lookup ) { - //remove operation will fail for LCT since this operation is not implemented + // remove operation will fail for LCT since this operation is not implemented return RT_REMOVE_FAILURE; } @@ -749,7 +749,7 @@ static inline int allocateTableIndex(table_t* table) { uint32_t index; - //0 is special index for failed entries. + // 0 is special index for failed entries. for (index = table->lastAllocatedIndex+1; index != table->lastAllocatedIndex; index = (index+1) % table->max_size) diff --git a/src/sfrt/sfrt.h b/src/sfrt/sfrt.h index 408acdd6a..0ff6e554c 100644 --- a/src/sfrt/sfrt.h +++ b/src/sfrt/sfrt.h @@ -17,79 +17,8 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * @file sfrt.h - * @author Adam Keeton - * @date Thu July 20 10:16:26 EDT 2006 - * - * SFRT implements two different routing table lookup methods that have been - * adapted to return a void pointers. Any generic information may be - * associated with a given IP or CIDR block. - * - * As of this writing, the two methods used are Stefan Nilsson and Gunnar - * Karlsson's LC-trie, and a multibit-trie method similar to Gupta et-al.'s - * DIR-n-m. Presently, the LC-trie is used for testing purposes as the - * current implementation does not allow for fast, dynamic inserts. - * - * The intended use is to associate large IP blocks with specific information; - * such as what may be written into the table by RNA. - * - * NOTE: information should only move from less specific to more specific, ie: - * - * First insert: 1.1.0.0/16 -> some data - * Second insert: 1.1.2.3 -> some other data - * - * As opposed to: - * - * First insert: 1.1.2.3 -> some other data - * Second insert: 1.1.0.0/16 -> some data - * - * If more general information is to overwrite existing entries, the table - * should be free'ed and rebuilt. This is due to the difficulty of cleaning - * out stale entries with the current implementation. At runtime, this won't - * be a significant issue since inserts should apply to specific IP addresses - * and not entire blocks of IPs. - * - * - * Implementation: - * - * The routing tables associate an index into a "data" table with each CIDR. - * Each entry in the data table stores a pointer to actual data. This - * implementation was chosen so each routing entry only needs one word to - * either index the data array, or point to another table. - * - * Inserts are performed by specifying a CIDR and a pointer to its associated - * data. Since a new routing table entry may overwrite previous entries, - * a flag selects whether the insert favors the most recent or favors the most - * specific. Favoring most specific should be the default behvior. If - * the user wishes to overwrite routing entries with more general data, the - * table should be flushed, rather than using favor-most-recent. - * - * Before modifying the routing or data tables, the insert function performs a - * lookup on the CIDR-to-be-insertted. If no entry or an entry *of differing - * bit length* is found, the data is insertted into the data table, and its - * index is used for the new routing table entry. If an entry is found that - * is as specific as the new CIDR, the index stored points to where the new - * data is written into the data table. - * - * If more specific CIDR blocks overwrote the data table, then the more - * general routing table entries that were not overwritten will be referencing - * the wrong data. Alternatively, less specific entries can only overwrite - * existing routing table entries if favor-most-recent inserts are used. - * - * Because there is no quick way to clean the data-table if a user wishes to - * use a favor-most-recent insert for more general data, the user should flush - * the table with sfrt_free and create one anew. Alternatively, a small - * memory leak occurs with the data table, as it will be storing pointers that - * no routing table entry cares about. - * - * - * The API calls that should be used are: - * sfrt_new - create new table - * sfrt_insert - insert entry - * sfrt_lookup - lookup entry - * sfrt_free - free table -*/ +// sfrt.h author Adam Keeton +// Thu July 20 10:16:26 EDT 2006 #ifndef SFRT_H #define SFRT_H @@ -100,6 +29,7 @@ #include #include + #include "main/snort_debug.h" #include "sfrt/sfrt_trie.h" #include "sfip/sfip_t.h" diff --git a/src/sfrt/sfrt_dir.h b/src/sfrt/sfrt_dir.h index 2ad867ac4..8bb4b0de5 100644 --- a/src/sfrt/sfrt_dir.h +++ b/src/sfrt/sfrt_dir.h @@ -22,13 +22,14 @@ * @author Adam Keeton * @date Thu July 20 10:16:26 EDT 2006 * - * The implementation uses an multibit-trie that is similar to Gupta et-al's - * DIR-n-m. -*/ + */ #ifndef SFRT_DIR_H #define SFRT_DIR_H + // The implementation uses an multibit-trie that is similar to Gupta et-al's + // DIR-n-m. + #include /*******************************************************************/ diff --git a/src/sfrt/sfrt_flat.h b/src/sfrt/sfrt_flat.h index 4734571b0..38d54f2d9 100644 --- a/src/sfrt/sfrt_flat.h +++ b/src/sfrt/sfrt_flat.h @@ -19,16 +19,16 @@ /* ** 9/7/2011 - Initial implementation ... Hui Cao ** -** This is based on the original sfrt.h, but using the flat segment memory. -** When allocating memory, it uses memory in the segment, and returns -** the offset. -** When accessing memory, it must use the base address and offset to -** correctly refer to it. */ #ifndef SFRT_FLAT_H #define SFRT_FLAT_H +// This is based on the original sfrt.h, but using the flat segment memory. +// When allocating memory, it uses memory in the segment, and returns the offset. +// When accessing memory, it must use the base address and offset to +// correctly refer to it. + #include "utils/segment_mem.h" typedef MEM_OFFSET INFO; /* To be replaced with a pointer to a policy */ diff --git a/src/stream/base/stream_module.h b/src/stream/base/stream_module.h index bdfc03cf8..56e7c08aa 100644 --- a/src/stream/base/stream_module.h +++ b/src/stream/base/stream_module.h @@ -21,7 +21,7 @@ #ifndef STREAM_MODULE_H #define STREAM_MODULE_H -#include "snort_types.h" +#include "main/snort_types.h" #include "framework/module.h" #include "flow/flow_control.h" diff --git a/src/stream/dev_notes.txt b/src/stream/dev_notes.txt new file mode 100644 index 000000000..ebeab1d48 --- /dev/null +++ b/src/stream/dev_notes.txt @@ -0,0 +1,39 @@ +This directory contains the implementation of the Stream preprocessor +components: + +* Stream constants and data types used across stream components or by + clients of the stream api. + +* Prototype definitions and implementation for all stream API methods. + +* Virtual base class defining the Stream Splitter interface. + Implementation of stream splitters for accumulated TCP over maximum + flushing (atom splitter) and length of given segment flushing (log + splitter). + +* Prototype definitions and implementation for the stream Protocol Aware + Flushing API methods (PAF is now realized by stream splitter subclasses). + +Major subcomponents of the Stream inspector are each implemented in a +subdirectory located here. These include the following: + +* base - implements the Stream class as a subclass of Inspector, handles + stream configuration, provides entry point for Stream evaluation of a + Packet, stream statistics managment. + +* tcp - implements module for handling Stream tcp sessions. This includes + normalization protocol tracking, normalization, and reassembly. + +* upd - implements module for handling Stream udp sessions. Tracking only. + +* icmp - implements module for handling Stream icmp sessions. Tracking + only. + +* ip - implements module for handling Stream ip sessions. Tracking only. + +* file - implements module for handling Stream file session. This directly + sets file data and invokes file processing and detection. + +* user - implements module for handling Stream user session. This handles + payload only, eg from a socket. Does splitter based reassembly like TCP. + diff --git a/src/stream/file/file_module.h b/src/stream/file/file_module.h index 61cb2e6dd..6a2901b28 100644 --- a/src/stream/file/file_module.h +++ b/src/stream/file/file_module.h @@ -20,9 +20,9 @@ #ifndef FILE_MODULE_H #define FILE_MODULE_H -#include "snort_types.h" -#include "framework/module.h" +#include "main/snort_types.h" #include "main/thread.h" +#include "framework/module.h" #include "stream/stream.h" struct SnortConfig; diff --git a/src/stream/icmp/icmp_module.h b/src/stream/icmp/icmp_module.h index 8a54f785b..6546f5ae1 100644 --- a/src/stream/icmp/icmp_module.h +++ b/src/stream/icmp/icmp_module.h @@ -21,9 +21,9 @@ #ifndef ICMP_MODULE_H #define ICMP_MODULE_H -#include "snort_types.h" -#include "framework/module.h" +#include "main/snort_types.h" #include "main/thread.h" +#include "framework/module.h" #include "stream/stream.h" extern const PegInfo icmp_pegs[]; diff --git a/src/stream/ip/ip_defrag.h b/src/stream/ip/ip_defrag.h index 153130a1f..7b0f77361 100644 --- a/src/stream/ip/ip_defrag.h +++ b/src/stream/ip/ip_defrag.h @@ -21,9 +21,8 @@ #ifndef IP_DEFRAG_H #define IP_DEFRAG_H -// FIXIT-L integrate into stream api -//int fpAddFragAlert(Packet *p, OptTreeNode *otn); -//int fpFragAlerted(Packet *p, OptTreeNode *otn); +// ip datagram reassembly + int drop_all_fragments(Packet* p); int fragGetApplicationProtocolId(Packet* p); diff --git a/src/stream/ip/ip_module.h b/src/stream/ip/ip_module.h index 51a8f8dea..3709426bb 100644 --- a/src/stream/ip/ip_module.h +++ b/src/stream/ip/ip_module.h @@ -21,9 +21,9 @@ #ifndef IP_MODULE_H #define IP_MODULE_H -#include "snort_types.h" -#include "framework/module.h" +#include "main/snort_types.h" #include "main/thread.h" +#include "framework/module.h" #include "stream/stream.h" struct SnortConfig; diff --git a/src/stream/ip/stream_ip.h b/src/stream/ip/stream_ip.h index 0c4dcfb1c..8946d6a06 100644 --- a/src/stream/ip/stream_ip.h +++ b/src/stream/ip/stream_ip.h @@ -17,11 +17,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * @file stream_ip.h - * @author Russ Combs - * - */ +// file stream_ip.h author Russ Combs #ifndef STREAM_IP_H #define STREAM_IP_H diff --git a/src/stream/paf.h b/src/stream/paf.h index 97466079e..e1918f2b8 100644 --- a/src/stream/paf.h +++ b/src/stream/paf.h @@ -26,7 +26,8 @@ #define PAF_H #include -#include "snort_types.h" + +#include "main/snort_types.h" #include "stream/stream_api.h" #include "stream/stream_splitter.h" diff --git a/src/stream/stream.h b/src/stream/stream.h index 31163f528..bc9c0660e 100644 --- a/src/stream/stream.h +++ b/src/stream/stream.h @@ -20,14 +20,10 @@ #ifndef STREAM_H #define STREAM_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include #include -#include "snort_types.h" +#include "main/snort_types.h" #include "stream/stream_api.h" #include "network_inspectors/normalize/norm.h" diff --git a/src/stream/stream_api.h b/src/stream/stream_api.h index 5fcc80ea1..d557773a8 100644 --- a/src/stream/stream_api.h +++ b/src/stream/stream_api.h @@ -17,20 +17,16 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* stream_api.h - * AUTHOR: Steven Sturges - * - * Purpose: Definition of the StreamAPI. To be used as a common interface - * for TCP (and later UDP & ICMP) Stream access for other - * preprocessors and detection plugins. - */ +// stream_api.h author Steven Sturges #ifndef STREAM_API_H #define STREAM_API_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +/* + * Purpose: Definition of the StreamAPI. To be used as a common interface + * for TCP (and later UDP & ICMP) Stream access for other + * preprocessors and detection plugins. + */ #include @@ -94,119 +90,100 @@ public: SO_PRIVATE Stream(); SO_PRIVATE ~Stream(); + // Looks in the flow cache for flow session with specified key and returns + // pointer to flow session oject if found, otherwise null. static Flow* get_session(const FlowKey*); + + // Allocates a flow session object from the flow cache table for the protocol + // type of the specified key. If no cache exists for that protocol type null is + // returned. If a flow already exists for the key a pointer to that session + // object is returned. + // If a new session object can not be allocated the program is terminated. static Flow* new_session(const FlowKey*); + + // Removes the flow session object from the flow cache table and returns + // the resources allocated to that flow to the free list. static void delete_session(const FlowKey*); + // Examines the source and destination ip addresses and ports to determine if the + // packet is from the client or server side of the flow and sets bits in the + // packet_flags field of the Packet struct to indicate the direction determined. static uint32_t get_packet_direction(Packet*); + // Sets the stream session into proxy mode. FIXIT-L method name is misleading static void proxy_started(Flow*, unsigned dir); - /* Stop inspection for session, up to count bytes (-1 to ignore - * for life or until resume). - * - * If response flag is set, automatically resume inspection up to - * count bytes when a data packet in the other direction is seen. - * - * Also marks the packet to be ignored - */ + // Stop inspection on a flow for up to count bytes (-1 to ignore for life or until resume). + // If response flag is set, automatically resume inspection up to count bytes when a data + // packet in the other direction is seen. Also marks the packet to be ignored + // FIXIT: method does not currently support the bytes/response parameters static void stop_inspection(Flow*, Packet*, char dir, int32_t bytes, int rspFlag); - /* Turn off inspection for potential session. - * Adds session identifiers to a hash table. - * TCP only. - */ + // Adds entry to the expected session cache with a flow key generated from the network + // n-tuple parameters specified. Inspection will be turned off for this expected session + // when it arrives. int ignore_session( const sfip_t *addr1, uint16_t p1, const sfip_t *addr2, uint16_t p2, PktType, char dir, uint32_t ppId); - /* Resume inspection for session. - */ + // Resume inspection for flow. + // FIXIT-L does this just work for a flow that has been stop by call to stop_inspection?? static void resume_inspection(Flow*, char dir); - /* Drop traffic arriving on session. - */ + // Set Active status to force drop the current packet and set flow state to drop + // subsequent packets arriving from the direction specified. static void drop_traffic(Flow*, char dir); - /* Drop retransmitted packet arriving on session. - */ + // Mark a flow as dropped, release allocated resources, and set flow state such that any + // subsequent packets received on this flow are dropped. static void drop_session(const Packet*); - // FIXIT-L these are misnomers in ips mode and may be used incorrectly + // FIXIT-L flush_request & flush response are misnomers in ips mode and may be used incorrectly. + + // Flush queued data on the listener side of a stream flow. The listener is the side of the + // connection the packet is destined, so if the Packet is from the client, then the + // server side tracker is flushed. static void flush_request(Packet*); // flush listener - static void flush_response(Packet*); // flush talker - /* Add session alert - true if added - */ + // Flush queued data on the talker side of a stream flow. The talker is the side of the + // connection the packet originated from, so if the Packet is from the client, then the + // client side tracker is flushed. + static void flush_response(Packet*); // flush talker + + // Add session alert - true if added static bool add_session_alert(Flow*, Packet*, uint32_t gid, uint32_t sid); - /* Check session alert - true if previously alerted - */ + // Check session alert - true if previously alerted static bool check_session_alerted(Flow*, Packet* p, uint32_t gid, uint32_t sid); - /* Set Extra Data Logging - * - * Returns - * 0 success - * -1 failure ( no alerts ) - */ + // Set Extra Data Logging static int update_session_alert( Flow*, Packet* p, uint32_t gid, uint32_t sid, uint32_t eventId, uint32_t eventSecond); - /* Get Flowbits data - * - * Returns - * Ptr to Flowbits Data - */ + // Get pointer to Flowbits data static StreamFlowData* get_flow_data(const Packet*); - /* Get reassembly direction for given session - * - * Returns - * direction(s) of reassembly for session - */ + // Get reassembly direction for given session static char get_reassembly_direction(Flow*); - /* Get true/false as to whether stream data is in - * sequence or packets are missing - * - * Returns - * true/false - */ + // Returns true if stream data for the flow is in sequence, otherwise return false. static bool is_stream_sequenced(Flow*, uint8_t dir); - /* Get whether there are missing packets before, after or - * before and after reassembled buffer - * - * Returns - * SSN_MISSING_BOTH if missing before and after - * SSN_MISSING_BEFORE if missing before - * SSN_MISSING_AFTER if missing after - * SSN_MISSING_NONE if none missing - */ + // Get state of missing packets for the flow. + // SSN_MISSING_BOTH if missing before and after + // SSN_MISSING_BEFORE if missing before + // SSN_MISSING_AFTER if missing after + // SSN_MISSING_NONE if none missing static int missing_in_reassembled(Flow*, uint8_t dir); - /* Get true/false as to whether packets were missed on - * the stream - * - * Returns - * true/false - */ + // Returns true if packets were missed on the stream, otherwise returns false. static bool missed_packets(Flow*, uint8_t dir); - /* Get the protocol identifier from a stream - * - * Returns - * integer protocol identifier - */ + // Get the protocol identifier from a stream static int16_t get_application_protocol_id(Flow*); - /* Set the protocol identifier for a stream - * - * Returns - * integer protocol identifier - */ + // Set the protocol identifier for a stream static int16_t set_application_protocol_id(Flow*, int16_t appId); // initialize response count and expiration time @@ -216,33 +193,21 @@ public: static StreamSplitter* get_splitter(Flow*, bool toServer); static bool is_paf_active(Flow*, bool toServer); - /* Turn off inspection for potential session. - * Adds session identifiers to a hash table. - * TCP only. - * - * Returns - * 0 on success - * -1 on failure - */ + // Turn off inspection for potential session. Adds session identifiers to a hash table. + // TCP only. int set_application_protocol_id_expected( const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, PktType, int16_t appId, FlowData*); - /** Retrieve application session data based on the lookup tuples for - * cases where Snort does not have an active packet that is - * relevant. - * - * Returns - * Application Data reference (pointer) - */ + // Get pointer to application data for a flow based on the lookup tuples for cases where + // Snort does not have an active packet that is relevant. static FlowData* get_application_data_from_ip_port( uint8_t type, uint8_t proto, const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, uint16_t vlanId, uint32_t mplsId, uint16_t addrSpaceId, unsigned flow_id); - /* Get the application data from the session key - */ - static FlowData* get_application_data_from_key(const FlowKey*, unsigned flow_id); + // Get pointer to application data for a flow using the FlowKey as the lookup criteria + static FlowData* get_application_data_from_key(const FlowKey*, unsigned flow_id); // -- extra data methods uint32_t reg_xtra_data_cb(LogFunction); @@ -253,28 +218,20 @@ public: static void clear_extra_data(Flow*, Packet*, uint32_t); void log_extra_data(Flow*, uint32_t mask, uint32_t id, uint32_t sec); - /** Retrieve stream session pointer based on the lookup tuples for - * cases where Snort does not have an active packet that is - * relevant. - * - * Returns - * Stream session pointer - */ - static Flow* get_session_ptr_from_ip_port( + // Get pointer to a session flow instance for a flow based on the lookup tuples for + // cases where Snort does not have an active packet that is relevant. + static Flow* get_session_ptr_from_ip_port( uint8_t type, uint8_t proto, const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, uint16_t vlanId, uint32_t mplsId, uint16_t addrSpaceId); - /* Delete the session if it is in the closed session state. - */ + // Delete the session if it is in the closed session state. void check_session_closed(Packet*); - /* Create a session key from the Packet - */ + // Create a session key from the Packet static FlowKey* get_session_key(Packet*); - /* Populate a session key from the Packet - */ + // Populate a session key from the Packet static void populate_session_key(Packet*, FlowKey*); void update_direction(Flow*, char dir, const sfip_t* ip, uint16_t port); @@ -292,7 +249,7 @@ public: static int set_ignore_direction(Flow*, int ignore_direction); // Get the TTL value used at session setup - // outer=false to get inner ip ttl for ip in ip; else outer=true + // Set outer=false to get inner ip ttl for ip in ip; else outer=true static uint8_t get_session_ttl(Flow*, char dir, bool outer); static bool expired_session(Flow*, Packet*); diff --git a/src/stream/tcp/tcp_module.h b/src/stream/tcp/tcp_module.h index 40d27bec3..847bb55da 100644 --- a/src/stream/tcp/tcp_module.h +++ b/src/stream/tcp/tcp_module.h @@ -24,9 +24,9 @@ #include #include -#include "snort_types.h" -#include "framework/module.h" +#include "main/snort_types.h" #include "main/thread.h" +#include "framework/module.h" #include "stream/stream.h" #define GID_STREAM_TCP 129 diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index 85a860286..b595adf9d 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -18,9 +18,10 @@ //-------------------------------------------------------------------------- /* - * @file stream_tcp.c - * @author Martin Roesch - * @author Steven Sturges + * stream_tcp.c authors: + * Martin Roesch + * Steven Sturges + * Russ Combs */ /* @@ -1890,7 +1891,7 @@ static inline unsigned int getSegmentFlushSize( { unsigned int flushSize = ss->size; - //copy only till flush buffer gets full + // copy only till flush buffer gets full if ( flushSize > flushBufSize ) flushSize = flushBufSize; diff --git a/src/stream/tcp/tcp_session.h b/src/stream/tcp/tcp_session.h index a4b07e63f..51cd6b97d 100644 --- a/src/stream/tcp/tcp_session.h +++ b/src/stream/tcp/tcp_session.h @@ -20,6 +20,10 @@ #ifndef TCP_SESSION_H #define TCP_SESSION_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "stream_tcp.h" #include "stream/paf.h" #include "flow/session.h" diff --git a/src/stream/udp/udp_module.h b/src/stream/udp/udp_module.h index 51a58963e..a45e3380e 100644 --- a/src/stream/udp/udp_module.h +++ b/src/stream/udp/udp_module.h @@ -24,9 +24,9 @@ #include #include -#include "snort_types.h" -#include "framework/module.h" +#include "main/snort_types.h" #include "main/thread.h" +#include "framework/module.h" #include "stream/stream.h" struct SnortConfig; diff --git a/src/stream/user/user_module.h b/src/stream/user/user_module.h index b1a20e8e1..bfbfa0451 100644 --- a/src/stream/user/user_module.h +++ b/src/stream/user/user_module.h @@ -20,9 +20,9 @@ #ifndef USER_MODULE_H #define USER_MODULE_H -#include "snort_types.h" -#include "framework/module.h" +#include "main/snort_types.h" #include "main/thread.h" +#include "framework/module.h" #include "stream/stream.h" struct SnortConfig; diff --git a/src/target_based/dev_notes.txt b/src/target_based/dev_notes.txt new file mode 100644 index 000000000..2a3023902 --- /dev/null +++ b/src/target_based/dev_notes.txt @@ -0,0 +1,14 @@ +The idea of a target-based system is to model the actual targets on the +network instead of merely modeling the protocols and looking for attacks +within them. When TCP/IP stacks are written for different operating +systems, they are usually implemented by people who read the RFCs and then +their interpretation of what the RFC outlines into code. Unfortunately, +there are ambiguities in the way that the RFCs define some of the edge +conditions that may occur and when this happens different people implement +certain aspects of their TCP/IP stacks differently. For an IDS this is a +big problem. + +The basic idea behind target-based IDS is that we tell the IDS information +about hosts on the network so that it can avoid attacks based on information +about how an individual target TCP/IP stack operates. + diff --git a/src/target_based/sftarget_data.h b/src/target_based/sftarget_data.h index 9b980feba..89a219de0 100644 --- a/src/target_based/sftarget_data.h +++ b/src/target_based/sftarget_data.h @@ -17,19 +17,12 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * Author: Steven Sturges - * sftarget_data.c - */ +// sftarget_data.c author Steven Sturges #ifndef SFTARGET_DATA_H #define SFTARGET_DATA_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "sfip_t.h" +#include "sfip/sfip_t.h" #define SFAT_OK 0 #define SFAT_ERROR -1 diff --git a/src/target_based/sftarget_hostentry.h b/src/target_based/sftarget_hostentry.h index ee3b304fa..397b7bba3 100644 --- a/src/target_based/sftarget_hostentry.h +++ b/src/target_based/sftarget_hostentry.h @@ -17,35 +17,38 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * Author: Steven Sturges - * sftarget_hostentry.h - */ +// sftarget_hostentry.h author Steven Sturges #ifndef SFTARGET_HOSTENTRY_H #define SFTARGET_HOSTENTRY_H -#include "sftarget_reader.h" -#include "sftarget_data.h" +#include "target_based/sftarget_reader.h" +#include "target_based/sftarget_data.h" #define SFTARGET_MATCH 1 #define SFTARGET_NOMATCH 0 /* API for HostAttributeEntry 'class' */ +// FIXIT-L used locally only int hasService(const HostAttributeEntry* hostEntry, int ipprotocol, int protocol, int application); + +// FIXIT-L used locally only int hasClient(const HostAttributeEntry* hostEntry, int ipprotocol, int protocol, int application); + +// FIXIT-L not used anywhere int hasProtocol(const HostAttributeEntry* hostEntry, int ipprotocol, int protocol, int application); +// FIXIT-L not used anywhere int getProtocol(const HostAttributeEntry* hostEntry, int ipprotocol, uint16_t port); @@ -55,6 +58,7 @@ int getApplicationProtocolId(const HostAttributeEntry* host_entry, uint16_t port, char direction); +// FIXIT-L not used anywhere #define SFAT_UNKNOWN_STREAM_POLICY 0 uint16_t getStreamPolicy(const HostAttributeEntry* host_entry); #define SFAT_UNKNOWN_FRAG_POLICY 0 diff --git a/src/target_based/sftarget_reader.h b/src/target_based/sftarget_reader.h index bcac95cb5..8f4bcb691 100644 --- a/src/target_based/sftarget_reader.h +++ b/src/target_based/sftarget_reader.h @@ -17,15 +17,14 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* - * Author: Steven Sturges - * sftarget_reader.h - */ +// sftarget_reader.h author Steven Sturges #ifndef SFTARGET_READER_H #define SFTARGET_READER_H -#include "sftarget_data.h" +// Provides attribute table initialization, lookup, swap, and releasing. + +#include "target_based/sftarget_data.h" #define DEFAULT_MAX_ATTRIBUTE_HOSTS 10000 #define DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST 100 diff --git a/src/target_based/snort_protocols.h b/src/target_based/snort_protocols.h index 8753314f5..33f1d5651 100644 --- a/src/target_based/snort_protocols.h +++ b/src/target_based/snort_protocols.h @@ -22,7 +22,7 @@ #ifndef SNORT_PROTOCOLS_H #define SNORT_PROTOCOLS_H -#include "snort_types.h" +#include "main/snort_types.h" // FIXIT-L use logical type instead of int16_t // for all reference protocols diff --git a/src/test/dev_notes.txt b/src/test/dev_notes.txt new file mode 100644 index 000000000..37ae129d8 --- /dev/null +++ b/src/test/dev_notes.txt @@ -0,0 +1,8 @@ +=== Unit Test + +This directory contains the unit-test interface as well as specific test +suites. Currently, there are unit test suites defined for sfrf, sfrt, and +sfthd. + +The unit tests use the check unit test framework. For more on check, see +the documentation at http://check.sourceforge.net/. diff --git a/src/test/unit_test.cc b/src/test/unit_test.cc index 1846936d9..4cac4299a 100644 --- a/src/test/unit_test.cc +++ b/src/test/unit_test.cc @@ -46,22 +46,22 @@ static SuiteCtor_f s_suites[] = void unit_test_mode(const char* s) { - if ( !s || !strcasecmp(s, "off") ) + if ( !s || !strcasecmp(s, UNIT_TEST_MODE_OFF) ) s_mode = CK_LAST; - else if ( !strcasecmp(s, "silent") ) + else if ( !strcasecmp(s, UNIT_TEST_MODE_SILENT) ) s_mode = CK_SILENT; - else if ( !strcasecmp(s, "minimal") ) + else if ( !strcasecmp(s, UNIT_TEST_MODE_MINIMAL) ) s_mode = CK_MINIMAL; - else if ( !strcasecmp(s, "normal") ) + else if ( !strcasecmp(s, UNIT_TEST_MODE_NORMAL) ) s_mode = CK_NORMAL; - else if ( !strcasecmp(s, "verbose") ) + else if ( !strcasecmp(s, UNIT_TEST_MODE_VERBOSE) ) s_mode = CK_VERBOSE; - else //if ( !strcasecmp(s, "env") ) + else //if ( !strcasecmp(s, UNIT_TEST_MODE_ENV) ) s_mode = CK_ENV; } diff --git a/src/test/unit_test.h b/src/test/unit_test.h index be0599247..e7b7b50bd 100644 --- a/src/test/unit_test.h +++ b/src/test/unit_test.h @@ -20,9 +20,19 @@ #ifndef UNIT_TEST_H #define UNIT_TEST_H -// "silent" | "minimal" | "normal" | "verbose" | "env" -// "env" -> getenv("CK_VERBOSITY") for one of the above -// can also be set to "off" +// Unit test interface + +// These are the available arguments to unit_test_mode() +#define UNIT_TEST_MODE_SILENT "silent" +#define UNIT_TEST_MODE_MINIMAL "minimal" +#define UNIT_TEST_MODE_NORMAL "normal" +#define UNIT_TEST_MODE_VERBOSE "verbose" +#define UNIT_TEST_MODE_ENV "env" +#define UNIT_TEST_MODE_OFF "off" + +// Use "env" test mode to allow setting verbosity via this environment variable +#define UNIT_TEST_MODE_ENVVAR "CK_VERBOSITY" + void unit_test_mode(const char* = nullptr); bool unit_test_enabled(); int unit_test(); diff --git a/src/time/cpuclock.h b/src/time/cpuclock.h index acb0bd910..583dcd1d4 100644 --- a/src/time/cpuclock.h +++ b/src/time/cpuclock.h @@ -20,14 +20,14 @@ #ifndef CPUCLOCK_H #define CPUCLOCK_H -/* Assembly to find clock ticks. */ +// Assembly to find clock ticks #ifdef HAVE_CONFIG_H #include "config.h" #endif #include -/* INTEL LINUX/BSD/.. */ +// INTEL LINUX/BSD/.. #if (defined(__i386) || defined(__amd64) || defined(__x86_64__)) #define get_clockticks(val) \ { \ @@ -49,7 +49,7 @@ val = _Asm_mov_from_ar (_AREG_ITC); \ } #else -/* POWER PC */ +// POWER PC #if (defined(__GNUC__) && (defined(__powerpc__) || (defined(__ppc__)))) #define get_clockticks(val) \ { \ @@ -63,7 +63,7 @@ val = ((uint64_t)tbl) | (((uint64_t)tbu0) << 32); \ } #else -/* SPARC */ +// SPARC #ifdef SPARCV9 #ifdef _LP64 #define get_clockticks(val) \ @@ -79,14 +79,14 @@ : "=r" (a), "=r" (b)); \ val = ((uint64_t)a) | (((uint64_t)b) << 32); \ } -#endif /* _LP64 */ +#endif // _LP64 #else #define get_clockticks(val) -#endif /* SPARC */ -#endif /* POWERPC || PPC */ -#endif /* IA64 && HPUX */ -#endif /* IA64 && GNUC */ -#endif /* I386 || AMD64 || X86_64 */ +#endif // SPARCV9 +#endif // __GNUC__ && __powerpc__ || __ppc__ +#endif // __ia64 && __hpux +#endif // __ia64 && __GNUC__ +#endif // __i386 || __amd64 || __x86_64__ static inline double get_ticks_per_usec(void) { @@ -99,5 +99,5 @@ static inline double get_ticks_per_usec(void) return (double)(end-start)/1e6; } -#endif /* CPUCLOCK_H */ +#endif diff --git a/src/time/dev_notes.txt b/src/time/dev_notes.txt new file mode 100644 index 000000000..1ac3127c3 --- /dev/null +++ b/src/time/dev_notes.txt @@ -0,0 +1,10 @@ +This module provides miscellaneous utilities related to timing. + +* Packet Performance monitoring provides facilities for gathering + statistics about the packet processing system as a whole. These + statistics include timing information for rule evaluation, packet + decoding and event processing, as well as counts for actions taken on + packets before and during rule evaluation. + +* Performance Profiling provides facilities for evaluating the performance + of individual preprocessors and rule subtrees. diff --git a/src/time/packet_time.h b/src/time/packet_time.h index c2a08b238..1b63856ce 100644 --- a/src/time/packet_time.h +++ b/src/time/packet_time.h @@ -20,12 +20,8 @@ #ifndef PACKET_TIME_H #define PACKET_TIME_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include -#include +#include void packet_time_update(const struct timeval* cur_tv); time_t packet_time(void); diff --git a/src/time/periodic.h b/src/time/periodic.h index 225e72e66..db5a4b402 100644 --- a/src/time/periodic.h +++ b/src/time/periodic.h @@ -20,12 +20,12 @@ #ifndef PERIODIC_H #define PERIODIC_H -#include "snort_types.h" +#include "main/snort_types.h" -typedef void (* PeriodicFunc)(void*); +using PeriodicFunc = void (*)(void*); void periodic_register( -PeriodicFunc, void* arg, uint16_t priority, uint32_t period); + PeriodicFunc, void* arg, uint16_t priority, uint32_t period); void periodic_check(); void periodic_release(); diff --git a/src/time/ppm.h b/src/time/ppm.h index bfd62afa2..2552512d3 100644 --- a/src/time/ppm.h +++ b/src/time/ppm.h @@ -16,24 +16,23 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- - -/* - ** ppm.h - packet performance monitor - ** - ** Author: Marc Norton - */ +// ppm.h author Marc Norton #ifndef PPM_H #define PPM_H +// Provide facilities for packet performance monitoring + #ifdef HAVE_CONFIG_H #include "config.h" #endif +// FIXIT-M: Instead of an empty source file, use CMake/Make to enable/disable +// this compilation unit #ifdef PPM_MGR #include "main/snort_types.h" #include "main/thread.h" -#include "cpuclock.h" +#include "time/cpuclock.h" #include "detection/detection_options.h" #define cputime get_clockticks @@ -44,38 +43,38 @@ typedef unsigned int PPM_SECS; struct ppm_cfg_t { - /* config section */ + // config section int enabled; PPM_TICKS max_pkt_ticks; - int pkt_log; /* alert,console,syslog */ - int pkt_action; /* suspend */ + int pkt_log; // alert,console,syslog + int pkt_action; // suspend PPM_TICKS max_rule_ticks; - uint64_t rule_threshold; /* rules must fail this many times in a row to suspend */ + uint64_t rule_threshold; // rules must fail this many times in a row to suspend - int rule_log; /* alert,console,syslog */ - int rule_action; /* suspend */ + int rule_log; // alert,console,syslog + int rule_action; // suspend uint64_t max_suspend_ticks; }; struct ppm_stats_t { - /* stats section */ + // stats section unsigned int rule_event_cnt; unsigned int pkt_event_cnt; - uint64_t tot_pkt_time; /* ticks */ + uint64_t tot_pkt_time; // ticks uint64_t tot_pkts; - uint64_t tot_rule_time; /* ticks */ + uint64_t tot_rule_time; // ticks uint64_t tot_rules; - uint64_t tot_nc_rule_time; /* ticks */ + uint64_t tot_nc_rule_time; // ticks uint64_t tot_nc_rules; - uint64_t tot_pcre_rule_time; /* ticks */ + uint64_t tot_pcre_rule_time; // ticks uint64_t tot_pcre_rules; }; @@ -98,7 +97,7 @@ typedef struct PPM_TICKS max_rule_ticks; } ppm_rule_timer_t; -/* global data */ +// global data #define PPM_MAX_TIMERS 10 extern PPM_TICKS ppm_tpu; extern THREAD_LOCAL ppm_pkt_timer_t ppm_pkt_times[PPM_MAX_TIMERS]; @@ -115,12 +114,12 @@ extern THREAD_LOCAL int ppm_suspend_this_rule; #define PPM_LOG_MESSAGE 2 #define PPM_ACTION_SUSPEND 1 -/* Config flags */ +// config flags #define PPM_ENABLED() (snort_conf->ppm_cfg->enabled > 0) #define PPM_PKTS_ENABLED() (snort_conf->ppm_cfg->max_pkt_ticks > 0) #define PPM_RULES_ENABLED() (snort_conf->ppm_cfg->max_rule_ticks > 0) -/* packet, rule event flags */ +// packet, rule event flags #define PPM_PACKET_ABORT_FLAG() ppm_abort_this_pkt #define PPM_RULE_SUSPEND_FLAG() ppm_suspend_this_rule @@ -156,7 +155,7 @@ extern THREAD_LOCAL int ppm_suspend_this_rule; #define PPM_PRINT_PKT_TIME(a) LogMessage(a, ppm_ticks_to_usecs((PPM_TICKS)ppm_pt->tot) ); #ifdef PPM_TEST -/* use usecs instead of ticks for rule suspension during pcap playback */ +// use usecs instead of ticks for rule suspension during pcap playback #define PPM_RULE_TIME(p) ((p->pkth->ts.tv_sec * 1000000) + p->pkth->ts.tv_usec) #else #define PPM_RULE_TIME(p) ppm_cur_time @@ -188,14 +187,9 @@ extern THREAD_LOCAL int ppm_suspend_this_rule; { \ ppm_pkt_index--; \ if ( ppm_pkt_index > 0 ) \ - { \ - /*ppm_pkt_times[ppm_pkt_index-1].subtract=ppm_pt->tot; */ \ ppm_pt = &ppm_pkt_times[ppm_pkt_index-1]; \ - } \ else \ - { \ ppm_pt=0; \ - } \ } #define PPM_INIT_RULE_TIMER() \ @@ -219,11 +213,11 @@ extern THREAD_LOCAL int ppm_suspend_this_rule; } \ } -/* use PPM_GET_TIME; first to get the current time */ +// use PPM_GET_TIME; first to get the current time #define PPM_PACKET_TEST() \ if ( ppm_pt ) \ { \ - ppm_pt->tot = ppm_cur_time - ppm_pt->start /*- ppm_pt->subtract*/; \ + ppm_pt->tot = ppm_cur_time - ppm_pt->start; \ if (ppm_pt->tot > ppm_pt->max_pkt_ticks) \ { \ if ( snort_conf->ppm_cfg->pkt_action & PPM_ACTION_SUSPEND ) \ @@ -241,7 +235,7 @@ extern THREAD_LOCAL int ppm_suspend_this_rule; #define PPM_DBG_CSV(state, otn, when) #endif -/* use PPM_GET_TIME; first to get the current time */ +// use PPM_GET_TIME; first to get the current time #define PPM_RULE_TEST(root,p) \ if ( ppm_rt ) \ { \ @@ -330,12 +324,12 @@ void ppm_set_rule(detection_option_tree_root_t*, PPM_TICKS); #define PPM_PRINT_CFG(x) ppm_print_cfg(x) #define PPM_PRINT_SUMMARY(x) ppm_print_summary(x) -#else /* !PPM_MGR */ +#else #define PPM_GET_TIME() #define PPM_SET_TIME() -#endif /* PPM_MGR */ +#endif // PPM_MGR -#endif /* PPM_H */ +#endif diff --git a/src/time/ppm_module.h b/src/time/ppm_module.h index 80d4dfadc..a2f759073 100644 --- a/src/time/ppm_module.h +++ b/src/time/ppm_module.h @@ -15,21 +15,25 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- - // ppm_module.h author Russ Combs #ifndef PPM_MODULE_H #define PPM_MODULE_H +// Configuration module for packet performance monitoring + #ifdef HAVE_CONFIG_H #include "config.h" #endif +// FIXIT-M: Instead of an empty source file, use CMake/Make to enable/disable +// this compilation unit #ifdef PPM_MGR #include "framework/module.h" #define GID_PPM 134 +// SIDs #define PPM_EVENT_RULE_TREE_DISABLED 1 #define PPM_EVENT_RULE_TREE_ENABLED 2 #define PPM_EVENT_PACKET_ABORTED 3 @@ -48,6 +52,6 @@ public: { return GID_PPM; } }; -#endif +#endif // PPM_MGR #endif diff --git a/src/time/profiler.cc b/src/time/profiler.cc index 8fa31da25..34cdbc9bd 100644 --- a/src/time/profiler.cc +++ b/src/time/profiler.cc @@ -43,9 +43,10 @@ using namespace std; #include "framework/module.h" #include "hash/sfghash.h" +// FIXIT-M: Instead of using preprocessor directives, use the build system +// to control compilation of this module #ifdef PERF_PROFILING -/* Data types *****************************************************************/ typedef struct _ProfileStatsNode { ProfileStats stats; @@ -79,7 +80,6 @@ typedef struct _Preproc_WorstPerformer double pct_of_total; } Preproc_WorstPerformer; -/* Globals ********************************************************************/ static THREAD_LOCAL double ticks_per_microsec = 0.0; static OTN_WorstPerformer* worstPerformers = NULL; diff --git a/src/time/profiler.h b/src/time/profiler.h index 6b99badb5..fb443f8e6 100644 --- a/src/time/profiler.h +++ b/src/time/profiler.h @@ -1,7 +1,6 @@ //-------------------------------------------------------------------------- // Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. // Copyright (C) 2005-2013 Sourcefire, Inc. -// Author: Steven Sturges // // 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 @@ -18,9 +17,13 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// profiler.h author Steven Sturges + #ifndef PROFILER_H #define PROFILER_H +// Facilities for performance profiling + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -41,7 +44,7 @@ struct ProfileStats #include "main/thread.h" #include "time/cpuclock.h" -/* Sort preferences for rule profiling */ +// Sort preferences for rule profiling #define PROFILE_SORT_CHECKS 1 #define PROFILE_SORT_MATCHES 2 #define PROFILE_SORT_NOMATCHES 3 @@ -50,7 +53,7 @@ struct ProfileStats #define PROFILE_SORT_AVG_TICKS_PER_NOMATCH 6 #define PROFILE_SORT_TOTAL_TICKS 7 -/* MACROS that handle profiling of rules and preprocessors */ +// MACROS that handle profiling of rules and preprocessors #define PROFILE_VARS_NAMED(name) uint64_t name ## _ticks_start, name ## _ticks_end #define PROFILE_VARS PROFILE_VARS_NAMED(snort) @@ -155,7 +158,11 @@ struct ProfileStats } #define MODULE_PROFILE_TMPEND(ppstat) MODULE_PROFILE_TMPEND_NAMED(snort, ppstat) -/************** Profiling API ******************/ + +// ----------------------------------------------------------------------------- +// Profiling API +// ----------------------------------------------------------------------------- + struct ProfileConfig { int num; @@ -166,11 +173,11 @@ void ShowRuleProfiles(void); void ResetRuleProfiling(void); // thread local access method -typedef ProfileStats* (* get_profile_func)(const char*); +using get_profile_func = ProfileStats* (*)(const char*); void RegisterProfile( -const char* keyword, const char* parent, -get_profile_func, class Module* owner = nullptr); + const char* keyword, const char* parent, + get_profile_func, class Module* owner = nullptr); void RegisterProfile(class Module*); @@ -203,7 +210,7 @@ extern THREAD_LOCAL ProfileStats metaPerfStats; #define MODULE_PROFILE_REENTER_END_NAMED(name, ppstat) #define MODULE_PROFILE_TMPEND(ppstat) #define MODULE_PROFILE_TMPEND_NAMED(name, ppstat) -#endif +#endif // PERF_PROFILING static inline void ShowAllProfiles() { diff --git a/src/time/timersub.h b/src/time/timersub.h index 5465590a2..a74b06358 100644 --- a/src/time/timersub.h +++ b/src/time/timersub.h @@ -18,14 +18,19 @@ 02110-1301, USA */ -/* never worry about timersub type activies again -- from GLIBC and upcased. */ +#ifndef TIMERSUB_H +#define TIMERSUB_H + +// never worry about timersub type activies again -- from GLIBC and upcased. #define TIMERSUB(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ } while (0) +#endif + diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index a6d7a68f8..0cf14a4d1 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -31,8 +31,6 @@ ADD_LIBRARY( utils STATIC boyer_moore.h dyn_array.cc dyn_array.h - ring.h - ring_logic.h segment_mem.cc sf_email_attach_decode.cc sf_email_attach_decode.h diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am index fd13882b7..546bf3506 100644 --- a/src/utils/Makefile.am +++ b/src/utils/Makefile.am @@ -17,7 +17,6 @@ util.h libutils_a_SOURCES = \ boyer_moore.cc boyer_moore.h \ dyn_array.cc dyn_array.h \ -ring.h ring_logic.h \ segment_mem.cc \ sf_base64decode.cc sf_base64decode.h \ sf_email_attach_decode.cc sf_email_attach_decode.h \ diff --git a/src/utils/bitop.h b/src/utils/bitop.h index 0bed10e26..21997e077 100644 --- a/src/utils/bitop.h +++ b/src/utils/bitop.h @@ -16,21 +16,14 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** Dan Roelker -** Marc Norton -** -** NOTES -** 5.15.02 - Initial Source Code. Norton/Roelker -** 5.23.02 - Moved bitop functions to bitop.h to inline. Norton/Roelker -** 1.21.04 - Added static initialization. Roelker -** 9.13.05 - Separated type and inline func definitions. Sturges -** -*/ +// bitop.h authors Dan Roelker +// and Marc Norton #ifndef BITOP_H #define BITOP_H +// A poor man's bit vector implementation + #include #include #include @@ -40,296 +33,135 @@ // FIXIT-L replace this with a dynamic bitset or some such // at least reimplement into a reasonable class -typedef struct _BITOP +struct _BITOP { unsigned char* pucBitBuffer; unsigned int uiBitBufferSize; unsigned int uiMaxBits; -} BITOP; - -/* -** NAME -** boInitStaticBITOP:: -*/ -/** -** This function is for use if you handle the bitop buffer allocation -** yourself. Just pass in the char array and the number of bytes the array -** is and this function sets up the structure for you. -** -** You must zero the buffer before init or reset before use. it is not -** cleared here. -** -** @retval int -** -** @return 0 successful -** @return !0 failed -*/ -static inline int boInitStaticBITOP(BITOP* BitOp,int iBytes,unsigned char* buf) +}; + +using BITOP = struct _BITOP; + +// Initialize the BITOP struct. +// Use this if you handle the bitop buffer allocation yourself. +// You must zero the buffer yourself before use. +// returns 0 if successful, 1 otherwise +// FIXIT-L: Change return type to bool +// FIXIT-L: Change int len -> size_t len +static inline int boInitStaticBITOP(BITOP* BitOp, int len, unsigned char* buf) { - if (iBytes < 1 || !buf || !BitOp) + if ( len < 1 || !buf || !BitOp ) return 1; - BitOp->pucBitBuffer = buf; - BitOp->uiBitBufferSize = (unsigned int)iBytes; - BitOp->uiMaxBits = (unsigned int)(iBytes << 3); + BitOp->pucBitBuffer = buf; + BitOp->uiBitBufferSize = (unsigned int)len; + BitOp->uiMaxBits = (unsigned int)(len << 3); return 0; } -/* -** -** NAME -** boInitBITOP -** -** DESCRIPTION -** Initializes the BITOP structure for use. -** -** NOTE: -** BITOP structure must be zeroed to avoid misinterpretation -** of initialization. -** -** FORMAL INPUTS -** BITOP * - the structure to initialize -** int - the number of bit positions to hold. -** -** FORMAL OUTPUTS -** int - 0 if successful, 1 if failed. -** -*/ -static inline int boInitBITOP(BITOP* BitOp, int iBytes) +// Initializes the BITOP structure for use. +// returns 0 if successful, 1 otherwise +// FIXIT-L: Change return type to bool +// FIXIT-L: Change int len -> size_t len +static inline int boInitBITOP(BITOP* BitOp, int len) { - int iSize; - - /* - ** Sanity check for size - */ - if ((iBytes < 1) || (BitOp == NULL)) - { + if ( len < 1 || !BitOp ) return 1; - } - - /* - ** Check for already initialized buffer, and - ** if it is already initialized then we return that it - ** is initialized. - */ - if (BitOp->pucBitBuffer) - { - return 0; - } - iSize = iBytes << 3; + // Check for already initialized buffer + if ( BitOp->pucBitBuffer ) + return 0; - BitOp->pucBitBuffer = (unsigned char*)calloc(1, iBytes); - if (BitOp->pucBitBuffer == NULL) - { + BitOp->pucBitBuffer = (unsigned char*)calloc(1, len); + if ( !BitOp->pucBitBuffer ) return 1; - } - BitOp->uiBitBufferSize = (unsigned int)iBytes; - BitOp->uiMaxBits = (unsigned int)iSize; + BitOp->uiBitBufferSize = (unsigned int)len; + BitOp->uiMaxBits = (unsigned int)(len << 3); return 0; } -/* -** -** NAME -** boResetBITOP -** -** DESCRIPTION -** This resets the bit buffer so that it can be used again. -** -** FORMAL INPUTS -** BITOP * - structure to reset -** -** FORMAL OUTPUT -** int - 0 if successful, 1 if failed. -** -*/ +// Reset the bit buffer so that it can be reused +// returns 0 if successful, 1 otherwise +// FIXIT-L: Change return type to bool static inline int boResetBITOP(BITOP* BitOp) { - if (BitOp == NULL) + if ( !BitOp ) return 1; - memset(BitOp->pucBitBuffer, 0x00, BitOp->uiBitBufferSize); + memset(BitOp->pucBitBuffer, 0, BitOp->uiBitBufferSize); return 0; } -/* -** -** NAME -** boSetAllBits -** -** DESCRIPTION -** This resets the bit buffer to all 1's so that it can be used again. -** -** FORMAL INPUTS -** BITOP * - structure to reset -** -** FORMAL OUTPUT -** int - 0 if successful, 1 if failed. -** -*/ +// Reset the bit buffer to all 1's so that it can be reused +// returns 0 if successful, 1 otherwise +// FIXIT-L: Change return type to bool static inline int boSetAllBits(BITOP* BitOp) { - if (BitOp == NULL) + if ( !BitOp ) return 1; memset(BitOp->pucBitBuffer, 0xff, BitOp->uiBitBufferSize); return 0; } -/* -** -** NAME -** boSetBit -** -** DESCRIPTION -** Set the bit in the specified position within the bit buffer. -** -** FORMAL INPUTS -** BITOP * - the structure with the bit buffer -** int - the position to set within the bit buffer -** -** FORMAL OUTPUTS -** int - 0 if the bit was set, 1 if there was an error. -** -*/ -static inline int boSetBit(BITOP* BitOp, unsigned int uiPos) +// Set the bit in the specified position within the bit buffer. +// returns 0 if successful, 1 otherwise +// FIXIT-L: Change return type to bool +static inline int boSetBit(BITOP* BitOp, unsigned int bit) { - unsigned char mask; - - /* - ** Sanity Check while setting bits - */ - if ((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos)) + if ( !BitOp || BitOp->uiMaxBits <= bit ) return 1; - mask = (unsigned char)( 0x80 >> (uiPos & 7)); + unsigned char mask = (unsigned char)(0x80 >> (bit & 7)); - BitOp->pucBitBuffer[uiPos >> 3] |= mask; + BitOp->pucBitBuffer[bit >> 3] |= mask; return 0; } -/* -** -** NAME -** boIsBitSet -** -** DESCRIPTION -** Checks for the bit set in iPos of bit buffer. -** -** FORMAL INPUTS -** BITOP * - structure that holds the bit buffer -** int - the position number in the bit buffer -** -** FORMAL OUTPUTS -** int - 0 if bit not set, 1 if bit is set. -** -*/ -//KEEP -static inline int boIsBitSet(BITOP* BitOp, unsigned int uiPos) +// Checks if the bit at the specified position is set +// returns 0 if bit not set, 1 if bit is set. +// FIXIT-L: Change return type to bool +static inline int boIsBitSet(BITOP* BitOp, unsigned int bit) { - unsigned char mask; - - /* - ** Sanity Check while setting bits - */ - if ((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos)) + if ( !BitOp || BitOp->uiMaxBits <= bit ) return 0; - mask = (unsigned char)(0x80 >> (uiPos & 7)); + unsigned char mask = (unsigned char)(0x80 >> (bit & 7)); - return (mask & BitOp->pucBitBuffer[uiPos >> 3]); + return mask & BitOp->pucBitBuffer[bit >> 3]; } -/* -** -** NAME -** boClearBit -** -** DESCRIPTION -** Clear the bit in the specified position within the bit buffer. -** -** FORMAL INPUTS -** BITOP * - the structure with the bit buffer -** int - the position to clear within the bit buffer -** -** FORMAL OUTPUTS -** int - 0 if the bit was cleared, 1 if there was an error. -** -*/ -static inline void boClearBit(BITOP* BitOp, unsigned int uiPos) +// Clear the bit in the specified position within the bit buffer. +static inline void boClearBit(BITOP* BitOp, unsigned int bit) { - unsigned char mask; - - /* - ** Sanity Check while clearing bits - */ - if ((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos)) + if ( !BitOp || BitOp->uiMaxBits <= bit ) return; - mask = (unsigned char)(0x80 >> (uiPos & 7)); - - BitOp->pucBitBuffer[uiPos >> 3] &= ~mask; + unsigned char mask = (unsigned char)(0x80 >> (bit & 7)); + BitOp->pucBitBuffer[bit >> 3] &= ~mask; } -/* -** -** NAME -** boClearByte -** -** DESCRIPTION -** Clear the byte in the specified position within the bit buffer. -** -** FORMAL INPUTS -** BITOP * - the structure with the bit buffer -** int - the position to clear within the bit buffer -** -** FORMAL OUTPUTS -** int - 0 if the byte was cleared, 1 if there was an error. -** -*/ -static inline void boClearByte(BITOP* BitOp, unsigned int uiPos) +// Clear the byte in the specified position within the bit buffer. +static inline void boClearByte(BITOP* BitOp, unsigned int pos) { - /* - ** Sanity Check while clearing bytes - */ - if ((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos)) - return; - - BitOp->pucBitBuffer[uiPos >> 3] = 0; + if ( BitOp && BitOp->uiMaxBits > pos ) + BitOp->pucBitBuffer[pos >> 3] = 0; } -/* - ** - ** NAME - ** boFreeBITOP - ** - ** DESCRIPTION - ** Frees memory created by boInitBITOP - specifically - ** BitOp->pucBitBuffer - ** - ** NOTE: - ** !!! ONLY USE THIS FUNCTION IF YOU USED boInitBITOP !!! - ** - ** FORMAL INPUTS - ** BITOP * - the structure initially passed to boInitBITOP - ** - ** FORMAL OUTPUTS - ** void function - ** - **/ +// Frees memory created by boInitBITOP +// Only use this function if you used boInitBITOP to create the buffer! static inline void boFreeBITOP(BITOP* BitOp) { - if ((BitOp == NULL) || (BitOp->pucBitBuffer == NULL)) + if ( !BitOp || !BitOp->pucBitBuffer ) return; free(BitOp->pucBitBuffer); - BitOp->pucBitBuffer = NULL; + BitOp->pucBitBuffer = nullptr; } -#endif /* _BITOPT_FUNCS_H_ */ +#endif diff --git a/src/utils/boyer_moore.h b/src/utils/boyer_moore.h index aff9bc9f4..a9a7c1ec8 100644 --- a/src/utils/boyer_moore.h +++ b/src/utils/boyer_moore.h @@ -21,9 +21,11 @@ #ifndef BOYER_MOORE_H #define BOYER_MOORE_H +// Boyer-Moore pattern matching routines + #include "main/snort_types.h" -// boyer_moore.h was split out of mstring.h +// FIXIT-M: No associated resource destructor for make_skip & make_shift :( int* make_skip(char*, int); int* make_shift(char*, int); int mSearch(const char*, int, const char*, int, int*, int*); diff --git a/src/utils/dev_notes.txt b/src/utils/dev_notes.txt new file mode 100644 index 000000000..1dcc7d957 --- /dev/null +++ b/src/utils/dev_notes.txt @@ -0,0 +1,3 @@ +This unit contains a mixed bag of legacy utilities that haven't found a home in any +other directory. In many cases, the STL provides better options. + diff --git a/src/utils/dnet_header.h b/src/utils/dnet_header.h index 3a1428422..32d63349e 100644 --- a/src/utils/dnet_header.h +++ b/src/utils/dnet_header.h @@ -21,6 +21,8 @@ #ifndef UTILS_DNET_HEADER_H #define UTILS_DNET_HEADER_H +// Provide the correct dnet interface + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -36,7 +38,6 @@ #pragma GCC diagnostic ignored "-Wpedantic" #endif -// Encoder FOO #ifdef HAVE_DUMBNET_H #include #else diff --git a/src/utils/dyn_array.h b/src/utils/dyn_array.h index 8e5f01597..132343f0a 100644 --- a/src/utils/dyn_array.h +++ b/src/utils/dyn_array.h @@ -20,18 +20,8 @@ #ifndef DYN_ARRAY_H #define DYN_ARRAY_H -/* Dynamic array bound checks: - * If index is greater than maxElement then realloc like operation is performed. - * - * @param dynArray - dynamic array - * - * @param index - 0 based. Index of element that will be accessed by application - * either as rvalue or lvalue. - * - * @param maxElements - Number of elements already allocated in dynArray. - * 0 value means no elements are allocated - * and therefore dynArray[0] will cause memory allocation. - */ +// FIXIT-L: Change to vector +// FIXIT-L: Change return type to bool int sfDynArrayCheckBounds( void** dynArray, unsigned int index, unsigned int* maxElements); diff --git a/src/utils/segment_mem.h b/src/utils/segment_mem.h index 8aaaca7d6..2d6b72da0 100644 --- a/src/utils/segment_mem.h +++ b/src/utils/segment_mem.h @@ -16,15 +16,16 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// 8/7/2011 - Initial implementation ... Hui Cao +// segment_mem.h author Hui Cao #ifndef SEGMENT_MEM_H #define SEGMENT_MEM_H -#include +// Segment memory allocation used by sfrt + #include "main/snort_types.h" -typedef uint32_t MEM_OFFSET; +using MEM_OFFSET = uint32_t; int segment_meminit(uint8_t*, size_t); MEM_OFFSET segment_malloc(size_t size); diff --git a/src/utils/sf_base64decode.h b/src/utils/sf_base64decode.h index c723e9abb..2ca798d4f 100644 --- a/src/utils/sf_base64decode.h +++ b/src/utils/sf_base64decode.h @@ -16,15 +16,21 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// Writen by Patrick Mullen +// sf_base64decode.h author Patrick Mullen #ifndef SF_BASE64DECODE_H #define SF_BASE64DECODE_H +// A Base-64 decoder + #include "main/snort_types.h" -#include "util_unfold.h" -SO_PUBLIC int sf_base64decode(uint8_t*, uint32_t, uint8_t*, uint32_t, uint32_t*); +// FIXIT-L: inbuf should probably be const uint8_t* +SO_PUBLIC int sf_base64decode( + uint8_t* inbuf, uint32_t inbuf_size, + uint8_t* outbuf, uint32_t outbuf_size, + uint32_t* bytes_written +); #endif diff --git a/src/utils/sf_email_attach_decode.cc b/src/utils/sf_email_attach_decode.cc index 047e9a846..8d360bd16 100644 --- a/src/utils/sf_email_attach_decode.cc +++ b/src/utils/sf_email_attach_decode.cc @@ -20,8 +20,10 @@ #include "sf_email_attach_decode.h" -#include "snort_types.h" +#include "snort_bounds.h" #include "util.h" +#include "util_unfold.h" +#include "sf_base64decode.h" #define UU_DECODE_CHAR(c) (((c) - 0x20) & 0x3f) diff --git a/src/utils/sf_email_attach_decode.h b/src/utils/sf_email_attach_decode.h index f036286b3..fc50a59d4 100644 --- a/src/utils/sf_email_attach_decode.h +++ b/src/utils/sf_email_attach_decode.h @@ -16,21 +16,25 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// Writen by Bhagyashree Bantwal +// sf_email_attach_decode.h author Bhagyashree Bantwal #ifndef SF_EMAIL_ATTACH_DECODE_H #define SF_EMAIL_ATTACH_DECODE_H -#include "snort_types.h" -#include "util_unfold.h" -#include "sf_base64decode.h" -#include "snort_bounds.h" +// Email attachment decoder + +#include + +#include "main/snort_types.h" #define MAX_BUF 65535 + +// FIXIT-L: Should make this a (scoped?) enum #define DECODE_SUCCESS 0 -#define DECODE_EXCEEDED 1 /* Decode Complete when we reach the max depths */ +#define DECODE_EXCEEDED 1 // Decode Complete when we reach the max depths #define DECODE_FAIL -1 +// FIXIT-L: Should be a scoped enum typedef enum { DECODE_NONE = 0, @@ -73,6 +77,7 @@ struct BitEnc_DecodeState int depth; }; +// Should be a C++ OOP struct with constructor, etc struct Email_DecodeState { DecodeType decode_type; @@ -97,7 +102,6 @@ struct MimeStats uint64_t decoded_bytes[DECODE_ALL]; }; -// end :: start + length int EmailDecode(const uint8_t* start, const uint8_t* end, Email_DecodeState*); static inline int getCodeDepth(int code_depth, int64_t file_depth) @@ -112,13 +116,14 @@ static inline int getCodeDepth(int code_depth, int64_t file_depth) return code_depth; } +// FIXIT-L: Should be an (inline?) method of struct Email_DecodeState static inline void SetEmailDecodeState(Email_DecodeState* ds, void* data, int buf_size, int b64_depth, int qp_depth, int uu_depth, int bitenc_depth, int64_t file_depth) { ds->decode_type = DECODE_NONE; ds->decode_present = 0; ds->prev_encoded_bytes = 0; - ds->prev_encoded_buf = NULL; + ds->prev_encoded_buf = nullptr; ds->decoded_bytes = 0; ds->encodeBuf = (uint8_t*)data; @@ -140,6 +145,7 @@ static inline void SetEmailDecodeState(Email_DecodeState* ds, void* data, int bu ds->bitenc_state.bytes_read = 0; } +// FIXIT-L: Should refactor as a constructor for struct Email_DecodeState static inline Email_DecodeState* NewEmailDecodeState( int max_depth, int b64_depth, int qp_depth, int uu_depth, int bitenc_depth, int64_t file_depth) @@ -156,11 +162,13 @@ static inline Email_DecodeState* NewEmailDecodeState( return ds; } +// FIXIT-L: Should refactor as a destructor for struct Email_DecodeState static inline void DeleteEmailDecodeState(Email_DecodeState* ds) { free(ds); } +// FIXIT-L: An assignment by value is more intuitive than by reference static inline void updateMaxDepth(int64_t file_depth, int* max_depth) { if ((!file_depth) || (file_depth > MAX_BUF)) @@ -173,12 +181,14 @@ static inline void updateMaxDepth(int64_t file_depth, int* max_depth) } } +// FIXIT-L: Should refactor as a method of struct Email_DecodeState static inline void ClearPrevEncodeBuf(Email_DecodeState* ds) { ds->prev_encoded_bytes = 0; - ds->prev_encoded_buf = NULL; + ds->prev_encoded_buf = nullptr; } +// FIXIT-L: Should refactor as a method of struct Email_DecodeState static inline void ResetBytesRead(Email_DecodeState* ds) { ds->uu_state.begin_found = ds->uu_state.end_found = 0; @@ -189,6 +199,7 @@ static inline void ResetBytesRead(Email_DecodeState* ds) ds->bitenc_state.bytes_read = 0; } +// FIXIT-L: Should refactor as a method of struct Email_DecodeState static inline void ResetDecodedBytes(Email_DecodeState* ds) { ds->decodePtr = nullptr; @@ -196,9 +207,10 @@ static inline void ResetDecodedBytes(Email_DecodeState* ds) ds->decode_present = 0; } +// FIXIT-L: Should refactor as a method of struct Email_DecodeState static inline void ResetEmailDecodeState(Email_DecodeState* ds) { - if ( ds == NULL ) + if ( ds == nullptr ) return; ds->uu_state.begin_found = ds->uu_state.end_found = 0; @@ -206,9 +218,10 @@ static inline void ResetEmailDecodeState(Email_DecodeState* ds) ClearPrevEncodeBuf(ds); } +// FIXIT-L: Should refactor as a method of struct Email_DecodeState static inline void ClearEmailDecodeState(Email_DecodeState* ds) { - if (ds == NULL) + if (ds == nullptr) return; ds->decode_type = DECODE_NONE; diff --git a/src/utils/sflsq.h b/src/utils/sflsq.h index a9a2bee9a..af7e608d1 100644 --- a/src/utils/sflsq.h +++ b/src/utils/sflsq.h @@ -16,37 +16,24 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// sflsq.h author Marc Norton -//--------------------------------------------------------------- -// if you are thinking to use these for new code, please consider -// instead using STL containers which give you all this and much -// more. :) -//--------------------------------------------------------------- - -/* -* sflsq.h -* -* Simple LIST, STACK, QUEUE DICTIONARY(LIST BASED)interface -* -* All of these functions are based on lists, which use -* the standard malloc. -* -* Note that NODE_DATA can be redifined with the -* define below. -* -* Author: Marc Norton -*/ #ifndef SFLSQ_H #define SFLSQ_H -/* -* -*/ +// Simple LIST, STACK, QUEUE DICTIONARY (LIST BASED) interface +// All of these functions are based on lists, which use +// the standard malloc. +// Use STL containers instead of these if possible. + +// FIXIT-L: If we're going to keep this interface around +// (instead of using STL data structures) +// it would make sense to template the interfaces +// instead of using a void* for data +// Note that NODE_DATA can be redefined with the typedef below typedef void* NODE_DATA; -/* -* Simple list,stack or queue NODE -*/ +// Simple list, stack, or queue NODE typedef struct sf_lnode { struct sf_lnode* next; @@ -55,9 +42,7 @@ typedef struct sf_lnode } SF_QNODE,SF_SNODE,SF_LNODE; -/* -* Integer Stack - uses an array from the subroutines stack -*/ +// Integer Stack - uses an array from the subroutines stack struct SF_ISTACK { unsigned* stack; @@ -65,9 +50,7 @@ struct SF_ISTACK unsigned n; }; -/* -* Pointer Stack - uses an array from the subroutines stack -*/ +// Pointer Stack - uses an array from the subroutines stack struct SF_PSTACK { void** stack; @@ -75,9 +58,7 @@ struct SF_PSTACK unsigned n; }; -/* -* Simple Structure for Queue's, stacks, lists -*/ +// Simple Structure for Queue's, stacks, lists struct sf_list { SF_LNODE* head, * tail; @@ -88,9 +69,9 @@ typedef sf_list SF_QUEUE; typedef sf_list SF_STACK; typedef sf_list SF_LIST; -/* -* Linked List Interface -*/ +// ----------------------------------------------------------------------------- +// Linked List Interface +// ----------------------------------------------------------------------------- SF_LIST* sflist_new(void); void sflist_init(SF_LIST*); int sflist_add_tail(SF_LIST*, NODE_DATA); @@ -108,9 +89,9 @@ void sflist_free_all(SF_LIST*, void (* free)(void*) ); void sflist_static_free_all(SF_LIST*, void (* nfree)(void*)); void sflist_static_free(SF_LIST*); -/* -* Stack Interface ( LIFO - Last in, First out ) -*/ +// ----------------------------------------------------------------------------- +// Stack Interface ( LIFO - Last in, First out ) +// ----------------------------------------------------------------------------- SF_STACK* sfstack_new(void); int sfstack_add(SF_STACK*, NODE_DATA); NODE_DATA sfstack_remove(SF_STACK*); @@ -120,9 +101,9 @@ void sfstack_free_all(SF_STACK*, void (* free)(void*) ); void sfstack_static_free_all(SF_STACK*, void (* nfree)(void*)); void sfstack_static_free(SF_STACK*); -/* -* Queue Interface ( FIFO - First in, First out ) -*/ +// ----------------------------------------------------------------------------- +// Queue Interface ( FIFO - First in, First out ) +// ----------------------------------------------------------------------------- SF_QUEUE* sfqueue_new(void); int sfqueue_add(SF_QUEUE*, NODE_DATA); NODE_DATA sfqueue_remove(SF_QUEUE*); @@ -132,11 +113,9 @@ void sfqueue_free_all(SF_QUEUE*, void (* free)(void*) ); void sfqueue_static_free_all(SF_QUEUE*,void (* nfree)(void*)); void sfqueue_static_free(SF_QUEUE*); -/* -* Performance Stack functions for Integer/Unsigned and Pointers, uses -* user provided array storage, perhaps from the program stack or a global. -* These are efficient, and use no memory functions. -*/ +// Performance Stack functions for Integer/Unsigned and Pointers, uses +// user provided array storage, perhaps from the program stack or a global. +// These are efficient, and use no memory functions. int sfistack_init(SF_ISTACK*, unsigned* a, unsigned n); int sfistack_push(SF_ISTACK*, unsigned value); int sfistack_pop(SF_ISTACK*, unsigned* value); diff --git a/src/utils/sfmemcap.h b/src/utils/sfmemcap.h index 85eeda1fc..f277a2ade 100644 --- a/src/utils/sfmemcap.h +++ b/src/utils/sfmemcap.h @@ -17,12 +17,11 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -/* -** sfmemcap.h -*/ #ifndef SFMEMCAP_H #define SFMEMCAP_H +// malloc and free wrappers that enforce a memory cap + struct MEMCAP { unsigned long memused; @@ -30,6 +29,7 @@ struct MEMCAP int nblocks; }; +// FIXIT-L: Could be refactored as a class void sfmemcap_init(MEMCAP* mc, unsigned long nbytes); MEMCAP* sfmemcap_new(unsigned nbytes); void sfmemcap_delete(MEMCAP* mc); diff --git a/src/utils/sfsnprintfappend.h b/src/utils/sfsnprintfappend.h index c7c2f7c7a..13fef2789 100644 --- a/src/utils/sfsnprintfappend.h +++ b/src/utils/sfsnprintfappend.h @@ -16,23 +16,16 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- +// sfsnprintfappend.h author Steven Sturges -/* -* -* sfsnprintfappend.h -* -* snprintf that appends to destination buffer -* -* -* Author: Steven Sturges -* -*/ #ifndef SFSNPRINTFAPPEND_H #define SFSNPRINTFAPPEND_H +// snprintf that appends to destination buffer + #include "main/snort_types.h" SO_PUBLIC int sfsnprintfappend(char* dest, int dsize, const char* format, ...); -#endif /* SFSNPRINTFAPPEND_H */ +#endif diff --git a/src/utils/snort_bounds.h b/src/utils/snort_bounds.h index aaafbf2a2..a0c6ebc42 100644 --- a/src/utils/snort_bounds.h +++ b/src/utils/snort_bounds.h @@ -16,11 +16,13 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// Chris Green +// snort_bounds.h author Chris Green #ifndef SNORT_BOUNDS_H #define SNORT_BOUNDS_H +// Bounds checking for pointers to buffers + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -35,6 +37,7 @@ #endif #include +// FIXIT-L: Change dependent return types to bool and git rid of these #define SAFEMEM_ERROR 0 #define SAFEMEM_SUCCESS 1 @@ -47,12 +50,9 @@ #define MAXPORTS 65536 #define MAXPORTS_STORAGE 8192 -/* - * Check to make sure that p is less than or equal to the ptr range - * pointers - * - * 1 means it's in bounds, 0 means it's not - */ +// Check to make sure that p is less than or equal to the ptr range +// returns 1 if in bounds, 0 otherwise +// FIXIT-L: Change return type to bool static inline int inBounds(const void* start, const void* end, const void* p) { const uint8_t* pstart = (uint8_t*)start; @@ -64,6 +64,7 @@ static inline int inBounds(const void* start, const void* end, const void* p) return 0; } +// FIXIT-L: Change return type to bool static inline int SafeMemCheck(const void* dst, size_t n, const void* start, const void* end) { @@ -87,19 +88,10 @@ static inline int SafeMemCheck(const void* dst, size_t n, return SAFEMEM_SUCCESS; } -/** - * A Safer Memcpy - * - * @param dst where to copy to - * @param src where to copy from - * @param n number of bytes to copy - * @param start start of the dest buffer - * @param end end of the dst buffer - * - * @return SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success - */ -static inline int SafeMemcpy(void* dst, const void* src, size_t n, const void* start, const - void* end) +// returns SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success +// FIXIT-L: Change return type to bool +static inline int SafeMemcpy( + void* dst, const void* src, size_t n, const void* start, const void* end) { if ( !n ) return SAFEMEM_SUCCESS; @@ -111,20 +103,11 @@ static inline int SafeMemcpy(void* dst, const void* src, size_t n, const void* s return SAFEMEM_SUCCESS; } -/** - * A Safer Memmove - * dst and src can be in the same buffer - * - * @param dst where to copy to - * @param src where to copy from - * @param n number of bytes to copy - * @param start start of the dest buffer - * @param end end of the dst buffer - * - * @return SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success - */ -static inline int SafeMemmove(void* dst, const void* src, size_t n, const void* start, const - void* end) +// dst and src can be in the same buffer +// returns SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success +// FIXIT-L: Change return type to bool +static inline int SafeMemmove( + void* dst, const void* src, size_t n, const void* start, const void* end) { if (SafeMemCheck(dst, n, start, end) != SAFEMEM_SUCCESS) ERRORRET; @@ -134,20 +117,11 @@ static inline int SafeMemmove(void* dst, const void* src, size_t n, const void* return SAFEMEM_SUCCESS; } -/** - * A Safer Memmove - * dst and src can be in the same buffer - * - * @param dst where to copy to - * @param src where to copy from - * @param n number of bytes to copy - * @param start start of the dest buffer - * @param end end of the dst buffer - * - * @return SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success - */ -static inline int SafeBoundsMemmove(void* dst, const void* src, size_t n, const void* start, const - void* end) +// dst and src can be in the same buffer +// returns SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success +// FIXIT-L: Change return type to bool +static inline int SafeBoundsMemmove( + void* dst, const void* src, size_t n, const void* start, const void* end) { size_t overlap = 0; if (SafeMemCheck(dst, n, start, end) != SAFEMEM_SUCCESS) @@ -178,19 +152,10 @@ static inline int SafeBoundsMemmove(void* dst, const void* src, size_t n, const return SAFEMEM_SUCCESS; } -/** - * A Safer Memset - * dst and src can be in the same buffer - * - * @param dst where to copy to - * @param c character to set memory with - * @param n number of bytes to set - * @param start start of the dst buffer - * @param end end of the dst buffer - * - * @return SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success - */ -static inline int SafeMemset(void* dst, uint8_t c, size_t n, const void* start, const void* end) +// returns SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success +// FIXIT-L: Change return type to bool +static inline int SafeMemset( + void* dst, uint8_t c, size_t n, const void* start, const void* end) { if (SafeMemCheck(dst, n, start, end) != SAFEMEM_SUCCESS) ERRORRET; @@ -198,16 +163,8 @@ static inline int SafeMemset(void* dst, uint8_t c, size_t n, const void* start, return SAFEMEM_SUCCESS; } -/** - * A Safer *a = *b - * - * @param start start of the dst buffer - * @param end end of the dst buffer - * @param dst the location to write to - * @param src the source to read from - * - * @return 0 on failure, 1 on success - */ +// returns 0 on failure, 1 on success +// FIXIT-L: Change return type to bool static inline int SafeWrite(uint8_t* start, uint8_t* end, uint8_t* dst, uint8_t* src) { if (!inBounds(start, end, dst)) @@ -219,6 +176,8 @@ static inline int SafeWrite(uint8_t* start, uint8_t* end, uint8_t* dst, uint8_t* return 1; } +// returns 0 on failure, 1 on success +// FIXIT-L: Change return type to bool static inline int SafeRead(uint8_t* start, uint8_t* end, uint8_t* src, uint8_t* read) { if (!inBounds(start,end, src)) @@ -230,10 +189,8 @@ static inline int SafeRead(uint8_t* start, uint8_t* end, uint8_t* src, uint8_t* return 1; } -/* An wrapper around snprintf to make it safe. - * - * This wrapper of snprintf returns the number of bytes written to the buffer. - */ +// An wrapper around snprintf to make it safe. +// returns the number of bytes written to the buffer static inline size_t SafeSnprintf(char* str, size_t size, const char* format, ...) { va_list ap; @@ -252,5 +209,5 @@ static inline size_t SafeSnprintf(char* str, size_t size, const char* format, .. return (size_t)ret; } -#endif /* SNORT_BOUNDS_H */ +#endif diff --git a/src/utils/stats.cc b/src/utils/stats.cc index 004104332..bf9d5c936 100644 --- a/src/utils/stats.cc +++ b/src/utils/stats.cc @@ -92,6 +92,11 @@ void LogLabel(const char* s) } } +void LogValue(const char* s, const char* v) +{ + LogMessage("%25.25s: %s\n", s, v); +} + void LogCount(const char* s, uint64_t c) { if ( c ) diff --git a/src/utils/stats.h b/src/utils/stats.h index 5257a2b39..2e9f7f7d1 100644 --- a/src/utils/stats.h +++ b/src/utils/stats.h @@ -20,9 +20,7 @@ #ifndef STATS_H #define STATS_H -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +// Provides facilities for displaying Snort exit stats #include #include @@ -36,7 +34,7 @@ #include "main/snort_types.h" #include "framework/counts.h" -// FIXIT-L split this out into appropriate modules +// FIXIT-L: split this out into appropriate modules struct PacketCount { PegCount total_from_daq; @@ -87,6 +85,7 @@ extern const PegInfo pc_names[]; extern const PegInfo proc_names[]; void LogLabel(const char*); +void LogValue(const char*, const char*); void LogCount(const char*, uint64_t); void LogStat(const char*, uint64_t n, uint64_t tot); void LogStat(const char*, double); diff --git a/src/utils/strvec.h b/src/utils/strvec.h index 8afcec4f3..f0a9a256b 100644 --- a/src/utils/strvec.h +++ b/src/utils/strvec.h @@ -21,6 +21,9 @@ #ifndef STRVEC_H #define STRVEC_H +// Vanilla string vector implementation +// FIXIT-L: Replace with an STL vector? + void* StringVector_New(void); void StringVector_Delete(void*); diff --git a/src/utils/util.h b/src/utils/util.h index 066672ad2..ead085411 100644 --- a/src/utils/util.h +++ b/src/utils/util.h @@ -21,10 +21,12 @@ #ifndef UTIL_H #define UTIL_H +// Miscellaneous functions and macros + #define TIMEBUF_SIZE 26 #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include @@ -44,8 +46,6 @@ #include "main/snort_types.h" #include "log/messages.h" -/* Macros *********************************************************************/ - #define SNORT_SNPRINTF_SUCCESS 0 #define SNORT_SNPRINTF_TRUNCATION 1 #define SNORT_SNPRINTF_ERROR -1 @@ -71,10 +71,8 @@ x[8] = y[8]; x[9] = y[9]; x[10] = y[10]; x[11] = y[11]; \ x[12] = y[12]; x[13] = y[13]; x[14] = y[14]; x[15] = y[15]; -/* Externs ********************************************************************/ SO_PUBLIC extern char** protocol_names; -/* Public function prototypes *************************************************/ void StoreSnortInfoStrings(void); int DisplayBanner(void); int gmt2local(time_t); @@ -90,10 +88,10 @@ void InitGroups(int, int); void SetChroot(std::string root_dir, std::string& log_dir); void InitProtoNames(void); -SO_PUBLIC int SnortSnprintf(char*, size_t, const char*, ...) __attribute__((format (printf, 3, - 4))); -SO_PUBLIC int SnortSnprintfAppend(char*, size_t, const char*, ...) __attribute__((format (printf, - 3, 4))); +SO_PUBLIC int SnortSnprintf(char*, size_t, const char*, ...) + __attribute__((format (printf, 3, 4))); +SO_PUBLIC int SnortSnprintfAppend(char*, size_t, const char*, ...) + __attribute__((format (printf, 3, 4))); SO_PUBLIC char* SnortStrdup(const char*); int SnortStrncpy(char*, const char*, size_t); @@ -115,12 +113,10 @@ void PrintVersion(void); void SetNoCores(void); #endif -/*********************************************************** - If you use any of the functions in this section, you need - to call free() on the char * that is returned after you are - done using it. Otherwise, you will have created a memory - leak. -***********************************************************/ +// If you use any of the functions in this section, you need +// to call free() on the char * that is returned after you are +// done using it. Otherwise, you will have created a memory +// leak. char* hex(const u_char*, int); char* fasthex(const u_char*, int); @@ -141,9 +137,8 @@ static inline void* new_calloc(size_t num, size_t size) { void* ret_val = calloc(num, size); if (ret_val == nullptr) - { throw std::bad_alloc(); - } + return ret_val; } @@ -168,8 +163,7 @@ static inline unsigned long SnortStrtoul(const char* nptr, char** endptr, int ba // Checks to make sure we're not going to evaluate a negative number for which // strtoul() gladly accepts and parses returning an underflowed wrapped unsigned // long without error. -// -// Buffer passed in MUST be NULL terminated. +// Buffer passed in MUST be '\0' terminated. // // Returns // int @@ -278,5 +272,5 @@ SO_PUBLIC const char* get_error(int errnum); // reentrant. char* get_tok(char* s, const char* delim); -#endif /*__UTIL_H__*/ +#endif diff --git a/src/utils/util_jsnorm.cc b/src/utils/util_jsnorm.cc index 5eb839ea9..72d50657d 100644 --- a/src/utils/util_jsnorm.cc +++ b/src/utils/util_jsnorm.cc @@ -19,6 +19,8 @@ // Writen by Bhagyashree Bantwal #include "util_jsnorm.h" + +#include #include "main/thread.h" #define INVALID_HEX_VAL -1 diff --git a/src/utils/util_jsnorm.h b/src/utils/util_jsnorm.h index cf3bdd516..d01f6a63b 100644 --- a/src/utils/util_jsnorm.h +++ b/src/utils/util_jsnorm.h @@ -16,21 +16,18 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// Writen by Bhagyashree Bantwal +// util_jsnorm.h author Bhagyashree Bantwal -#include -#include -#include -#include -#include +#ifndef UTIL_JSNORM_H +#define UTIL_JSNORM_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +// Javascript Normalization + +#include #define ALERT_SPACES_EXCEEDED 0x1 #define ALERT_LEVELS_EXCEEDED 0x2 -#define ALERT_MIXED_ENCODINGS 0x4 +#define ALERT_MIXED_ENCODINGS 0x4 #define MAX_ALLOWED_OBFUSCATION 1 @@ -39,8 +36,10 @@ typedef struct int allowed_spaces; int allowed_levels; uint16_t alerts; -}JSState; +} JSState; int JSNormalizeDecode(char*, uint16_t, char*, uint16_t destlen, char**, int*, JSState*, uint8_t*); void InitJSNormLookupTable(void); +#endif + diff --git a/src/utils/util_math.cc b/src/utils/util_math.cc index 47e1e4942..70d72c745 100644 --- a/src/utils/util_math.cc +++ b/src/utils/util_math.cc @@ -29,7 +29,10 @@ */ #include "util_math.h" -#include "snort_types.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /** * Calculate the percentage of something. diff --git a/src/utils/util_math.h b/src/utils/util_math.h index d8cca325c..23cd640c0 100644 --- a/src/utils/util_math.h +++ b/src/utils/util_math.h @@ -16,29 +16,15 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- - -/** - * @file util_math.h - * @author Chris Green - * @date Fri Jun 27 10:12:57 2003 - * - * @brief math related util functions - * - * Place simple math functions that are useful all over the place - * here. - */ +// util_math.h author Chris Green #ifndef UTIL_MATH_H #define UTIL_MATH_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "snort_types.h" +#include "main/snort_types.h" double calc_percent(double amt, double total); double calc_percent64(uint64_t amt, uint64_t total); -#endif /* UTIL_MATH_H */ +#endif diff --git a/src/utils/util_net.h b/src/utils/util_net.h index ba9af916b..80cc1082b 100644 --- a/src/utils/util_net.h +++ b/src/utils/util_net.h @@ -16,25 +16,20 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- - -/** - * @file util_net.h - * @author Chris Green - * @date Fri Jun 27 10:20:31 2003 - * - * @brief simple network related functions - * - * Put your simple network related functions here - */ +// util_net.h author Chris Green #ifndef UTIL_NET_H #define UTIL_NET_H +// Miscellaneous "to string" functions. +// Both functions return pointers to static buffers. +// Be aware that subsequent calls will overwrite the memory that is pointed to + #include "main/snort_types.h" #include "sfip/sfip_t.h" SO_PUBLIC char* inet_ntoax(const sfip_t*); SO_PUBLIC char* mktcpflag_str(int flags); -#endif /* UTIL_NET_H */ +#endif diff --git a/src/utils/util_unfold.h b/src/utils/util_unfold.h index 0e4710247..5099040f8 100644 --- a/src/utils/util_unfold.h +++ b/src/utils/util_unfold.h @@ -16,12 +16,14 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// Writen by Bhagyashree Bantwal +// util_unfold.h author Bhagyashree Bantwal #ifndef UTIL_UNFOLD_H #define UTIL_UNFOLD_H -#include "snort_types.h" +// Utilities to deal with line endings and other whitespace. AKA "Header unfolding" + +#include "main/snort_types.h" SO_PUBLIC int sf_unfold_header(const uint8_t*, uint32_t, uint8_t*, uint32_t, uint32_t*, int, int*); SO_PUBLIC int sf_strip_CRLF(const uint8_t*, uint32_t, uint8_t*, uint32_t, uint32_t*); diff --git a/src/utils/util_utf.h b/src/utils/util_utf.h index 94cec76d9..7f309c001 100644 --- a/src/utils/util_utf.h +++ b/src/utils/util_utf.h @@ -20,11 +20,15 @@ #ifndef UTIL_UTF_H #define UTIL_UTF_H -/* return codes */ +// Some UTF-{16,32}{le,be} normalization functions + +// FIXIT-L: Should get rid of these and change dependent return types to bool +// return codes #define DECODE_UTF_SUCCESS 0 #define DECODE_UTF_FAILURE -1 -/* character set types */ +// FIXIT-L: Should be an enum +// Character set types #define CHARSET_DEFAULT 0 #define CHARSET_UTF7 1 #define CHARSET_UTF16LE 2 @@ -33,26 +37,29 @@ #define CHARSET_UTF32BE 5 #define CHARSET_UNKNOWN 255 -/* Since payloads don't have to end on 2/4-byte boundaries, callers to - DecodeUTF are responsible for keeping a decode_utf_state_t. This carries - state between subsequent calls. */ +// Since payloads don't have to end on 2/4-byte boundaries, callers to +// DecodeUTF are responsible for keeping a decode_utf_state_t. This carries +// state between subsequent calls. typedef struct decode_utf_state { int state; int charset; } decode_utf_state_t; -/* Init & Terminate functions for decode_utf_state_t. */ +// Init & Terminate functions for decode_utf_state_t int init_decode_utf_state(decode_utf_state_t*); int term_decode_utf_state(decode_utf_state_t*); -/* setters & getters */ +// setters & getters int set_decode_utf_state_charset(decode_utf_state_t* dstate, int charset); int get_decode_utf_state_charset(decode_utf_state_t* dstate); -/* UTF-Decoding function prototypes */ -int DecodeUTF(char* src, unsigned int src_len, char* dst, unsigned int dst_len, int* bytes_copied, - decode_utf_state_t* dstate); +// UTF-Decoding function prototypes +int DecodeUTF( + char* src, unsigned int src_len, char* dst, unsigned int dst_len, + int* bytes_copied, + decode_utf_state_t* dstate +); -#endif /* UTIL_UTF_H */ +#endif