+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
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 \
--- /dev/null
+#!/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 <<END > $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 <<END
+=== ${h/$d\//}
+~Path = ${h}~
+
+[source,cpp]
+-----------------------
+include::$h[]
+-----------------------
+
+END
+ done
+done >> $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
+
}
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
}
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
#include <string>
+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
// 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"
#ifndef ACTIONS_H
#define ACTIONS_H
+// Define action types and provide hooks to apply a given action to a packet
+
#include <stdint.h>
#define ACTION_LOG "log"
#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,
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*);
void action_apply(RuleType, struct Packet*);
static inline bool pass_action(RuleType a)
-{
- return ( a == RULE_TYPE__PASS );
-}
+{ return ( a == RULE_TYPE__PASS ); }
#endif
--- /dev/null
+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.
--- /dev/null
+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.
{ 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)
{
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<uint32_t&>(raw.len) -= (ESP_AUTH_DATA_LEN + ESP_TRAILER_LEN);
/* Adjust the packet length to account for the padding.
{ 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&)
{
void Icmp4Codec::get_protocol_ids(std::vector<uint16_t>& 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)
break;
}
- /* Run a bunch of ICMP decoder rules */
ICMP4MiscTests(icmph, codec, (uint16_t)raw.len - len);
snort.set_pkt_type(PktType::ICMP);
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<ICMPHdr*>(raw_pkt);
snort.set_pkt_type(PktType::ICMP);
}
void Icmp6Codec::get_protocol_ids(std::vector<uint16_t>& 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)
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,
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)
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,
if ( !ip_len)
codec_event(codec, DECODE_ZERO_LENGTH_FRAG);
- /* set the packet fragment flag */
snort.decode_flags |= DECODE_FRAG;
}
else
return true;
}
-//------------------------------------------------------------------
-// decode.c::IP4 misc
-//--------------------------------------------------------------------
-
void Ipv4Codec::IP4AddrTests(
const IP4Hdr* iph, const CodecData& codec, DecodeData& snort)
{
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;
}
}
-/* 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();
}
}
-/* Check for multiple IPv6 Multicast-related alerts */
void Ipv6Codec::CheckIPV6Multicast(const ip::IP6Hdr* const ip6h, const CodecData& codec)
{
ip::MulticastScope multicast_scope;
#ifndef CODECS_CHECKSUM_H
#define CODECS_CHECKSUM_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdint.h>
#include <stdlib.h>
#include <cstddef>
--- /dev/null
+All codecs under this directory handle data that would be seen directly
+following or under IP headers.
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)
void Erspan2Codec::get_protocol_ids(std::vector<uint16_t>& 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 =
void Erspan3Codec::get_protocol_ids(std::vector<uint16_t>& 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 =
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.
void PppEncap::get_protocol_ids(std::vector<uint16_t>& 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;
#endif /* WORDS_MUSTALIGN */
- /* do a little validation:
- *
- */
if (raw.len < 2)
return false;
CodecData& codec,
DecodeData&)
{
- /* do a little validation */
if (raw.len < PPPOE_HEADER_LEN)
{
codec_event(codec, DECODE_BAD_PPPOE);
void TransbridgeCodec::get_protocol_ids(std::vector<uint16_t>& 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)
--- /dev/null
+These codecs handle link-layer protocols that would be presented beyond the
+root encapsulation defined by the capture data-link type.
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
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;
const GTPHdr* const hdr = reinterpret_cast<const GTPHdr*>(raw.data);
- /*Check the length*/
if (raw.len < GTP_MIN_LEN)
return false;
/* We only care about PDU*/
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",
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);
/*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);
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",
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);
return false;
}
- const uint16_t hlen = ip4h->hlen(); /* set the IP header length */
+ const uint16_t hlen = ip4h->hlen();
if (raw.len < hlen)
{
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:
/* lay the IP struct over the raw data */
const ip::IP6Hdr* ip6h = reinterpret_cast<const ip::IP6Hdr*>(raw.data);
- /* do a little validation */
if ( raw.len < ip::IP6_HEADER_LEN )
{
codec_event(codec, DECODE_ICMP_ORIG_IP_TRUNCATED);
--- /dev/null
+This directory contains codecs that do not fall under the classifications of
+the other codec directories. These codecs primarily handle IP tunnelling
+protocols.
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);
// 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
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
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;
uint32_t hlen;
uint32_t padlen = PFLOG_PADLEN;
- /* do a little validation */
if (cap_len < PFLOG2_HDRMIN)
return false;
#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;
}
};
} // 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;
};
} // 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;
bool WlanCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
{
- /* do a little validation */
if (raw.len < MINIMAL_IEEE80211_HEADER_LEN)
return false;
--- /dev/null
+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.
--- /dev/null
+This module provides functions for registering and running handlers
+that are called when Snort is not doing anything more important.
#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);
--- /dev/null
+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.
+
#include <string.h>
/* 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 */
#include <lzma.h>
#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,
STATE_COMPLETE /* Decompression completed */
} fd_states_t;
+/* Primary file decompression session state context */
struct fd_session_s
{
uint8_t* Next_In; /* next input byte */
/* 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; \
/* 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) )
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) )
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) )
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) )
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) )
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) &&
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) &&
/* 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
#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,
/* 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
#ifndef FILE_DECOMP_SWF_H
#define FILE_DECOMP_SWF_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <zlib.h>
#ifdef HAVE_LZMA
#include <lzma.h>
#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). */
/* 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
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/* I N C L U D E S ************************************************/
#ifndef DETECT_H
#define DETECT_H
#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;
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
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
-** @file detection_defines.h
-** @author Steven Sturges
-*/
+// detection_defines.h author Steven Sturges <ssturges@cisco.com>
#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
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)
// 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 <ssturges@cisco.com>
#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
typedef int (* eval_func_t)(void* option_data, class Cursor&, Packet*);
+// this is per packet thread
struct dot_node_state_t
{
int result;
dot_node_state_t* state;
};
+// this is per packet thread
#ifdef PPM_MGR
struct dot_root_state_t
{
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
// 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 <assert.h>
+// 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 <assert.h>
#include "main/snort_types.h"
#include "main/snort_config.h"
#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,
HTTP_BUFFER_MAX
};
+// FIXIT-L this is now used only by http_inspect
+// and should be relocated accordingly
struct HttpBuffer
{
const uint8_t* buf;
g_file_data.len = n;
}
+// FIXIT-L event trace should be placed in its own files
void EventTrace_Init(void);
void EventTrace_Term(void);
--- /dev/null
+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 <mnorton@sourcefire.com>
+* Dan Roelker <droelker@sourcefire.com>
+
+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;
+ }
+ }
+
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// fp_config.h is derived from fp_create.h by:
-/*
-** Dan Roelker <droelker@sourcefire.com>
-** Marc Norton <mnorton@sourcefire.com>
-*/
+// fp_config.h is derived from fpcreate.h by:
+//
+// Dan Roelker <droelker@sourcefire.com>
+// Marc Norton <mnorton@sourcefire.com>
#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
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;
if ( is_network_protocol(rtn->proto) )
{
- //do operation
+ // do operation
if ( enabled && !otn->enabled )
continue;
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
-** Dan Roelker <droelker@sourcefire.com>
-** Marc Norton <mnorton@sourcefire.com>
-**
-** 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 <droelker@sourcefire.com>
+// Marc Norton <mnorton@sourcefire.com>
+
#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;
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 */
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
-** Dan Roelker <droelker@sourcefire.com>
-** Marc Norton <mnorton@sourcefire.com>
-**
-** NOTES
-** 5.15.02 - Initial Source Code. Norton/Roelker
-*/
+
+// fp_detect.h is derived from fpdetect.h by:
+//
+// Dan Roelker <droelker@sourcefire.com>
+// Marc Norton <mnorton@sourcefire.com>
#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"
** 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
** the event to log based on the event comparison
** function.
*/
-typedef struct
+struct OTNX_MATCH_DATA
{
PortGroup* pg;
Packet* p;
MATCH_INFO* matchInfo;
int iMatchInfoArraySize;
-} OTNX_MATCH_DATA;
+};
void otnx_match_data_init(int);
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
//--------------------------------------------------------------------------
/*
+** --------------------------------------------------------------------------
** Marc Norton <mnorton@sourcefire.com>
** Dan Roelker <droelker@sourcefire.com>
**
**
** 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"
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
-** Marc Norton <mnorton@sourcefire.com>
-** Dan Roelker <droelker@sourcefire.com>
-**
-** Packet Classification-Rule Manager
-*/
+
+// pcrm.h is a heavily refactored version of work by:
+//
+// Marc Norton <mnorton@sourcefire.com>
+// Dan Roelker <droelker@sourcefire.com>
+
#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"
#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
};
#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"
struct RuleListNode* ruleListNode;
};
+// for top-level rule lists by type (alert, drop, etc.)
struct RuleListNode
{
ListHead* RuleList; /* The rule list associated with this node */
RuleListNode* next; /* the next RuleListNode */
};
+// for separately overriding rule type
struct RuleState
{
uint32_t sid;
//--------------------------------------------------------------------------
// service_map.h based fp_create.h by:
-/*
-** Dan Roelker <droelker@sourcefire.com>
-** Marc Norton <mnorton@sourcefire.com>
-**
-** NOTES
-** 5.7.02 - Initial Sourcecode. Norton/Roelker
-** 6/13/05 - marc norton
-** Added plugin support for fast pattern match data
-*/
+//
+// Dan Roelker <droelker@sourcefire.com>
+// Marc Norton <mnorton@sourcefire.com>
+
#ifndef SERVICE_MAP_H
#define SERVICE_MAP_H
+// for managing rule groups by service
+// direction to client and to server are separate
+
#include <vector>
#include "detection/pcrm.h"
// 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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
-/*
- * Return Sid associated with index
- * author: marc norton
- */
-unsigned RuleIndexMapSid(rule_index_map_t* map, int index)
+#include <vector>
+
+#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<rule_number_t> 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; i<rim->map.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; i<p->num_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");
}
// 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
// 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 <andrewb@sourcefire.com>
+
+// signature.h author Andrew R. Baker <andrewb@sourcefire.com>
+
#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 <sys/types.h>
#include <stdio.h>
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);
void OtnDeleteData(void* data);
void OtnFree(void* data);
-#endif /* SIGNATURE */
+#endif
#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 <cstdint>
#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"
uint64_t ppm_disable_cnt;
};
+// one of these for each rule
+// represents body part of rule
struct OptTreeNode
{
/* plugin/detection functions go here */
OptTreeNode* next;
- /* ptr to list of RTNs (head part) */
+ // ptr to list of RTNs (head part); indexed by policyId
RuleTreeNode** proto_nodes;
OtnState* state;
};
/* 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 */
RuleFpList* next;
};
+// one of these per rule per policy
+// represents head part of rule
struct RuleTreeNode
{
RuleFpList* rule_func; /* match functions.. (Bidirectional etc.. ) */
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;
};
--- /dev/null
+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.
+
--- /dev/null
+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.
+
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/* D E F I N E S ************************************************************/
#ifndef EVENT_H
#define EVENT_H
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
// 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 <huica@cisco.com>
- **
- ** NOTES
- ** 5.25.13 - Initial Source Code. Hui Cao
- */
+
+// circular_buffer.h author Hui Cao <huica@cisco.com>
#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*/
--- /dev/null
+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
+
// 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 <hcao@huica.com>
- *
- * NOTES
- * 5.25.12 - Initial Source Code. Hui Cao
- */
+// file_api.h author Hui Cao <hcao@huica.com>
+// 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 <sys/types.h>
#include "stream/stream_api.h"
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);
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);
// 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 <huica@cisco.com>
- **
- ** NOTES
- ** 5.05.2013 - Initial Source Code. Hui Cao
- */
+
+// file_capture.h author Hui Cao <huica@cisco.com>
#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"
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
// 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 <huica@cisco.com>
- **
- ** 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 <huica@cisco.com>
#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
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
// 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 <huica@cisco.com>
-**
-** NOTES
-** 9.25.2012 - Initial Source Code. Hui Cao
-*/
+
+// file_mime_config.h author Hui Cao <huica@cisco.com>
#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*);
// 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 <huica@cisco.com>
-**
-** NOTES
-** 9.25.2012 - Initial Source Code. Hui Cao
-*/
+
+// file_mime_process.h author Hui Cao <huica@cisco.com>
#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 <pcre.h>
-#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
// 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 <huica@cisco.com>
-**
-** NOTES
-** 9.25.2012 - Initial Source Code. Hui Cao
-*/
+
+// file_resume_block.h author Hui Cao <huica@cisco.com>
#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);
// 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 <huica@cisco.com>
-**
-** NOTES
-** 5.25.12 - Initial Source Code. Hui Cao
-*/
+
+// file_service.h author author Hui Cao <huica@cisco.com>
#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 */
// 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 <huica@cisco.com>
-**
-** NOTES
-** 5.25.2012 - Initial Source Code. Hui Cao
-*/
+
+// file_service_config.h author Hui Cao <huica@cisco.com>
+
#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
// 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 <huica@cisco.com>
- **
- ** NOTES
- ** 5.25.13 - Initial Source Code. Hui Cao
- */
+
+// file_stats.h author Hui Cao <huica@cisco.com>
#ifndef FILE_STATS_H
#define FILE_STATS_H
+#include <stdio.h>
+#include <stdlib.h>
+
+// 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 <stdio.h>
-#include <stdlib.h>
+#include "file_api/file_api.h"
#define MAX_PROTOCOL_ORDINAL 8192 // FIXIT-L use std::vector and get_protocol_count()
// 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 <huica@cisco.com>
-**
-** NOTES
-** 5.25.2012 - Initial Source Code. Hui Cao
-*/
+
+// file_config.h author Hui Cao <huica@cisco.com>
+
#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
// 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 <huica@cisco.com>
-**
-** NOTES
-** 5.25.2012 - Initial Source Code. Hui Cao
-*/
+
+// file_identifier.h author Hui Cao <huica@cisco.com>
#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 <list>
+#include "file_lib.h"
+#include "hash/sfghash.h"
#define FILE_ID_MAX 1024
// 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 <huica@cisco.com>
-**
-** NOTES
-** 5.25.12 - Initial Source Code. Hui Cao
-*/
+
+// file_lib.h author Hui Cao <huica@cisco.com>
#ifndef FILE_LIB_H
#define FILE_LIB_H
+// This will be basis of file class
+// FIXIT-L This will be refactored soon
#include <stdint.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include "file_api/file_api.h"
#include "flow/flow.h"
--- /dev/null
+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.
+
// 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 <dchahal@sourcefire.com>
+
#include "rate_filter.h"
+// rate filter interface for Snort
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
return rf_config;
}
-/* Free threshold context
- * @param pContext pointer to global threshold context.
- */
+/* Free threshold context */
void RateFilter_ConfigFree(RateFilterConfig* config)
{
int i;
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// rate_filter.h author Dilbagh Chahal <dchahal@sourcefire.com>
+
#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;
int RateFilter_Test(OptTreeNode*, Packet*);
void RateFilter_ResetActive(void);
-/*@}*/
#endif
// 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 <dchahal@sourcefire.com>
+// rate filter implementation for Snort
#include "sfrf.h"
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// sfrf.h author Dilbagh Chahal <dchahal@sourcefire.com>
+
#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"
#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"
--- /dev/null
+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.
+
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// expect_cache.h author Russ Combs <rucombs@cisco.com>
+
#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"
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// flow.h author Russ Combs <rucombs@cisco.com>
+
#ifndef FLOW_H
#define FLOW_H
-#include <assert.h>
+// 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 <assert.h>
#include "utils/bitop.h"
#include "sfip/sfip_t.h"
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// flow_cache.h author Russ Combs <rucombs@cisco.com>
+
#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"
#ifndef FLOW_CONFIG_H
#define FLOW_CONFIG_H
+// configured by the stream module for each cache instance
+
struct FlowConfig
{
unsigned max_sessions = 0;
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// flow_control.h author Russ Combs <rucombs@cisco.com>
+
#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"
FlowCache* user_cache;
FlowCache* file_cache;
+ // preallocated arrays
Flow* ip_mem;
Flow* icmp_mem;
Flow* tcp_mem;
// 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 <ssturges@sourcefire.com>
+// flow_key.cc author Steven Sturges <ssturges@sourcefire.com>
#include "flow/flow_key.h"
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 */
}
uint32_t* x, * y;
x = (uint32_t*)a;
y = (uint32_t*)b;
- //x++;
- //y++;
+ // x++;
+ // y++;
if (*x - *y)
return 1; /* Compares mpls label */
}
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 */
}
#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"
#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 <stdint.h>
class Memcap
#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"
#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
#ifndef BITS_H
#define BITS_H
+// common types used throughout the code
+
#include <bitset>
typedef std::bitset<65536> PortBitSet;
#ifndef FRAMEWORK_CODEC_H
#define FRAMEWORK_CODEC_H
+// Codec is a type of plugin that provides protocol-specific encoding and
+// decoding.
+
#include <vector>
#include <cstdint>
#include <cstddef>
#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;
#ifndef CURSOR_H
#define CURSOR_H
+// Cursor provides a formal way of using buffers when doing detection with
+// IpsOptions.
+
#include <ctype.h>
#include <stdint.h>
#include <string.h>
#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 <map>
#include <string>
#include <vector>
#ifndef FRAMEWORK_DECODE_DATA_H
#define FRAMEWORK_DECODE_DATA_H
+// Captures decode information from Codecs.
+
#include <type_traits>
#include "protocols/mpls.h"
--- /dev/null
+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.
+
#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"
#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"
#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"
#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"
#ifndef LUA_API_H
#define LUA_API_H
+// LuaApi makes Lua scripts standard plugins
+
#include <string>
-#include "base_api.h"
+#include "framework/base_api.h"
class LuaApi
{
#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 <vector>
#include <luajit-2.0/lua.hpp>
}
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;
}
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()
#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 <string>
#ifdef HAVE_CONFIG_H
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
{
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) { }
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:
#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
// # | #: | :# | #:#
#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:
#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"
#ifndef VALUE_H
#define VALUE_H
+// Value is used to represent Lua bool, number, and string.
+
#include <string.h>
#include <algorithm>
--- /dev/null
+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.
+
* -- 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
/* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
unsigned char *digest);*/
-#endif /* !MD5_H */
+#endif
// 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 <stdlib.h>
#include <string.h>
#include <time.h>
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;
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
// 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.
*
#include "sfprimetable.h"
#include "hash/sfhashfcn.h"
-/**@defgroup sfxhash sourcefire.container.sfxhash
+/*
* Implements SFXHASH as specialized hash container
- * @{
*/
/*
// 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:
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)
/*!
* 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)
* 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)
{
*
* 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)
/*!
* 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)
{
*
* 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)
{
*
* 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)
{
/*!
* 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)
/*!
* 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)
/**
* 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)
{
/**
* 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)
{
/**
* 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)
{
/**
* 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)
{
/*!
* 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)
/*!
* 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)
/*!
* 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)
/*!
* 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)
* 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)
/*!
* 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)
/*!
* 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)
/*!
* 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)
/**
* 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,
}
#endif
-/**@}*/
// 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 <stdlib.h>
#include <string.h>
#include <time.h>
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,
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);
* 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
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
)
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@
#ifndef CHUNK_H
#define CHUNK_H
+// Lua chunk support
+
#include <string>
void init_chunk(struct lua_State*&, std::string& chunk, const char* name, std::string& args);
--- /dev/null
+This directory contains new utility classes and methods for use by the
+framework.
+
#ifndef DIRECTORY_H
#define DIRECTORY_H
+// simple directory traversal
+
#include <dirent.h>
#include <string>
#ifndef LUA_H
#define LUA_H
+// methods and templates for the C++ / LuaJIT interface
+
#include <luajit-2.0/lua.hpp>
namespace Lua
#ifndef MARKUP_H
#define MARKUP_H
+// used to format help and list output for inclusion into user manual
+
#include <string>
class Markup
#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
#ifndef PROCESS_H
#define PROCESS_H
-#include <signal.h>
+// process oriented services like signal handling, heap info, etc.
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <signal.h>
#include <stdint.h>
enum PigSignal
//--------------------------------------------------------------------------
// ring.h author Russ Combs <rucombs@cisco.com>
-//-------------------------------------------------------------------
-// simple ring
-//-------------------------------------------------------------------
-
#ifndef RING_H
#define RING_H
+// Simple ring implementation
+
#include "ring_logic.h"
template <typename T>
//--------------------------------------------------------------------------
// ring_logic.h author Russ Combs <rucombs@cisco.com>
-//-------------------------------------------------------------------
-// simple ring logic
-//-------------------------------------------------------------------
-
#ifndef RING_LOGIC_H
#define RING_LOGIC_H
+// Logic for simple ring implementation
+
class RingLogic
{
public:
#ifndef SWAPPER_H
#define SWAPPER_H
+// used to make thread local, pointer-based config swaps by packet threads
+
struct SnortConfig;
struct tTargetBasedConfig;
--- /dev/null
+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.
+
#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"
//--------------------------------------------------------------------------
// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved.
// Copyright (C) 2010-2013 Sourcefire, Inc.
-// Author: Ryan Jordan <ryan.jordan@sourcefire.com>
//
// 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
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// ips_byte_extract.h author Ryan Jordan <ryan.jordan@sourcefire.com>
+
#ifndef IPS_BYTE_EXTRACT_H
#define IPS_BYTE_EXTRACT_H
#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
#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
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);
--- /dev/null
+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.
+
#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*);
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/**
- * @file log_text.h
- * @author Russ Combs <rcombs@sourcefire.com>
- * @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 <rcombs@sourcefire.com>
#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 <stdint.h>
#include "log/text_log.h"
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);
* None
*/
- void (* resetObfuscationEntries)(void);
+ void (* resetObfuscationEntries)();
/*
* Adds an obfuscation entry to the queue
/* For access when including header */
extern ObfuscationApi* obApi;
-#endif /* OBFUSCATION_H */
+#endif
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/**
- * @file text_log.h
- * @author Russ Combs <rcombs@sourcefire.com>
- * @date Fri Jun 27 10:34:37 2003
- *
- * @brief declares buffered text stream for logging
- *
+// text_log.h Russ Combs <rcombs@sourcefire.com>
+
+#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
* name plus a timestamp.
*/
-#ifndef TEXT_LOG_H
-#define TEXT_LOG_H
-
#include <stdio.h>
#include <string.h>
#include <time.h>
const char* msg;
const char* svc;
- const char* os;
};
struct SnortPacket
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;
}
--- /dev/null
+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.
+
#endif
#include <netinet/in.h>
-/*! \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
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;
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;
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;
uint32_t event_length;
}Unified2ExtraDataHdr;
-//UNIFIED2_EXTRA_DATA - type 110
+// UNIFIED2_EXTRA_DATA - type 110
typedef struct _SerialUnified2ExtraData
{
uint32_t sensor_id;
const uint8_t* data;
} Data_Blob;
-//UNIFIED2_EXTRA_DATA - type 110
+// UNIFIED2_EXTRA_DATA - type 110
typedef struct _Serial_Unified2ExtraData
{
uint32_t sensor_id;
#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;
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;
////////////////////-->LEGACY
-/*@}*/
#endif
// 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 <rucombs@cisco.com>
#ifndef MAIN_H
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);
#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
{
+#ifndef BUILD_H
+#define BUILD_H
+
//-----------------------------------------------//
// ____ _ //
// / ___| _ __ ___ _ __| |_ _ _ //
// //
//-----------------------------------------------//
-#define BUILD "160"
+#define BUILD "161"
+
+#endif
--- /dev/null
+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.
+
#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*);
// 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",
{ "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",
#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
#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 <string>
#include <vector>
#ifndef SHELL_H
#define SHELL_H
+// Shell encapsulates a Lua state. There is one for each policy file.
+
#include <string>
struct lua_State;
#ifndef SNORT_H
#define SNORT_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+// Snort is the top-level application class.
#include <assert.h>
#include <sys/types.h>
// 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);
#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
#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
#include <wchar.h>
#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"
#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
#ifndef SNORT_TYPES_H
#define SNORT_TYPES_H
+// defines common types if not already defined
+
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
#endif
-#endif /* __SF_TYPES_H__ */
+#endif
#ifndef THREAD_H
#define THREAD_H
+// basic thread management utilities
+
#include <string>
#include "main/snort_types.h"
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();
#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
#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 <array>
#include <string>
#include <vector>
--- /dev/null
+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.
+
#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
#ifndef INSPECTOR_MANAGER_H
#define INSPECTOR_MANAGER_H
+// Factory for Inspectors.
+// Also provides packet evaluation.
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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 <string>
-#include "snort_types.h"
+#include "main/snort_types.h"
#include "detection/detection_options.h"
#include "framework/base_api.h"
#include "framework/ips_option.h"
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
};
// 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
//-------------------------------------------------------------------------
#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 <string>
//-------------------------------------------------------------------------
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);
#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
#ifndef PLUGIN_MANAGER_H
#define PLUGIN_MANAGER_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string>
-
-#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.
// based on configuration.
//-------------------------------------------------------------------------
+#include <string>
+
+#include "main/snort_types.h"
+#include "framework/base_api.h"
+
class Module;
struct SnortConfig;
#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 <string>
-#include "snort_types.h"
+#include "main/snort_types.h"
#include "framework/base_api.h"
//-------------------------------------------------------------------------
#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"
--- /dev/null
+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.
#ifndef BIND_MODULE_H
#define BIND_MODULE_H
+// binder management interface
+
#include <vector>
#include "framework/module.h"
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);
--- /dev/null
+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.
+
--- /dev/null
+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
+
--- /dev/null
+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.
+
#include <cstdint>
#include <stdint.h>
+
#include "main/policy.h"
#include "framework/counts.h"
--- /dev/null
+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.
+
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;
void SetSampleTime(SFPERF*, Packet*);
void InitPerfStats(SFPERF* sfPerf);
+/* functions to set & get the RotatePerfFileFlag */
static inline void SetRotatePerfFileFlag(void)
{
perfmon_rotate_perf_file = 1;
# 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 <time.h>
#include <stdio.h>
+/* 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,
PERF_COUNT_MAX
};
+/* The base set of raw counters */
struct SFBASE
{
uint64_t total_wire_packets;
uint64_t total_iAlerts;
};
+/* Common structure for time indication */
struct SYSTIMES
{
double usertime;
double realtime;
};
+/* The 'processed' performance statistics */
struct SFBASE_STATS
{
uint64_t total_packets;
#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;
uint64_t TotalEvents;
} SFEVENT;
+/* Processed event counters */
typedef struct _SFEVENT_STATS
{
uint64_t NQEvents;
#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"
int display[256];
} ICMPFLOW;
+/* Raw flow statistics */
typedef struct _sfflow
{
time_t time;
SFXHASH* ipMap;
} SFFLOW;
+/* Processed flow statistics */
typedef struct _sfflow_stats
{
time_t time;
extern THREAD_LOCAL SimpleStats pmstats;
extern THREAD_LOCAL ProfileStats perfmonStats;
+/* The Module Class for incorporation into Snort++ */
class PerfMonModule : public Module
{
public:
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
--- /dev/null
+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.
+
#include <stdio.h>
#include <string.h>
-#include "sflsq.h"
+#include "utils/sflsq.h"
#include "sfip/sfip_t.h"
struct PORTRANGE
** - 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"
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// @file active.h
-// @author Russ Combs <rcombs@sourcefire.com>
+// active.h author Russ Combs <rcombs@sourcefire.com>
#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;
--- /dev/null
+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.
+
#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")
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);
//--------------------------------------------------------------------
return -1;
#endif
}
-}
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// @file sfdaq.h
-// @author Russ Combs <rcombs@sourcefire.com>
+// sfdaq.h author Russ Combs <rcombs@sourcefire.com>
#ifndef SFDAQ_H
#define SFDAQ_H
#define PKT_TIMEOUT 1000 // ms, worst daq resolution is 1 sec
struct SnortConfig;
-namespace snort
-{
+
void DAQ_Load(const SnortConfig*);
void DAQ_Unload(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);
{
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
#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);
cmd_line.h
config_file.cc
config_file.h
- keywords.h
mstring.cc
mstring.h
vars.cc
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
#include <grp.h>
#include <pwd.h>
#include <syslog.h>
-#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"
#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;
--- /dev/null
+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.
+
+++ /dev/null
-//--------------------------------------------------------------------------
-// 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
-
// 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
#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
#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"
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)
#ifndef PARSE_CONF_H
#define PARSE_CONF_H
-#include <string>
#include "detection/rules.h"
void parse_conf_init();
#define PARSE_IP_H
#include <sys/types.h>
-#include "snort_types.h"
+#include "main/snort_types.h"
struct sfip_var_t;
#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
{
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; i<plist->pl_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
*
* 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;
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
*
***************************************************************************/
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);
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));
}
void parse_rule_term()
-{
- port_list_free(&port_list);
-}
+{ }
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)
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));
*
* 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;
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(
#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"
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;
{
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.");
}
{
parse_rule_term();
- if (ruleIndexMap != NULL)
+ if (ruleIndexMap )
{
- RuleIndexMapFree(&ruleIndexMap);
- ruleIndexMap = NULL;
+ RuleIndexMapFree(ruleIndexMap);
+ ruleIndexMap = nullptr;
}
}
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);
}
#include <stdio.h>
-#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();
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(
#include "file_api/libs/file_config.h"
#include "framework/ips_option.h"
#include "config_file.h"
-#include "keywords.h"
//-------------------------------------------------------------------------
// var node stuff
--- /dev/null
+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.
#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
#ifndef PIGLET_API_H
#define PIGLET_API_H
+// Piglet plugin API
+
#include <string>
#include "framework/base_api.h"
#ifndef PIGLET_MANAGER_H
#define PIGLET_MANAGER_H
+// Factory for instantiating piglet plugins
+
#include <string>
#include <vector>
#include "helpers/lua.h"
-
#include "piglet_api.h"
#include "piglet_utils.h"
#ifndef PIGLET_RUNNER_H
#define PIGLET_RUNNER_H
+// Test runner
+
#include "piglet_utils.h"
namespace Piglet
#ifndef PIGLET_UTILS_H
#define PIGLET_UTILS_H
+// Miscellaneous data objects used for the piglet test harness
+
#include <chrono>
#include <string>
#include <vector>
--- /dev/null
+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<char>.
#ifndef PIGLET_PLUGIN_COMMON_H
#define PIGLET_PLUGIN_COMMON_H
-#include <limits>
-#include <vector>
+// Utils for working with the Lua C API and
+// interfaces for exposing some common structs to Lua.
#include <daq.h>
#include <luajit-2.0/lua.hpp>
+#include <limits>
+#include <vector>
+
#include "events/event.h"
#include "detection/signature.h"
#include "framework/codec.h"
-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
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
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.
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
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.
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
* 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
rule groups with rules that are unneccessary, this causes rule group sizes
to bloat and performance to slow.
-== Hierarchy:
+*Hierarchy*
PortTable -> PortObject's
//--------------------------------------------------------------------------
// port_group.h derived from pcrm.h by
-/*
-** Marc Norton <mnorton@sourcefire.com>
-** Dan Roelker <droelker@sourcefire.com>
-*/
+//
+// Marc Norton <mnorton@sourcefire.com>
+// Dan Roelker <droelker@sourcefire.com>
+
#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,
//-------------------------------------------------------------------------
// 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
#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*);
#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"
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 */
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*);
};
// 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)
{
#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"
#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"
--- /dev/null
+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.
+
#include <arpa/inet.h>
#define ETHERNET_HEADER_LEN 14
-#define ETHERNET_MTU 1500
+#define ETHERNET_MTU 1500
namespace eth
{
#ifndef PROTOCOLS_IP_H
#define PROTOCOLS_IP_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifndef WIN32
+
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
-#else /* !WIN32 */
+
+#else
+
#include <netinet/in_systm.h>
#ifndef IFNAMSIZ
#define IFNAMESIZ MAX_ADAPTER_NAME
-#endif /* !IFNAMSIZ */
-#endif /* !WIN32 */
+#endif
+
+#endif
#include <cstring>
#ifndef PROTOCOLS_IPV4_H
#define PROTOCOLS_IPV4_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <cstdint>
#include <arpa/inet.h>
#ifndef WIN32
+
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
-#else /* !WIN32 */
+
+#else
+
#include <netinet/in_systm.h>
#ifndef IFNAMSIZ
#define IFNAMESIZ MAX_ADAPTER_NAME
-#endif /* !IFNAMSIZ */
-#endif /* !WIN32 */
+#endif
+
+#endif
#include "protocols/protocol_ids.h" // include ipv4 protocol numbers
#ifndef PROTOCOLS_IPV6_H
#define PROTOCOLS_IPV6_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <cstdint>
#include <arpa/inet.h>
#include "sfip/sfip_t.h"
#include "protocols/protocol_ids.h"
#ifndef WIN32
+
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
-#else /* !WIN32 */
+
+#else
+
#include <netinet/in_systm.h>
#ifndef IFNAMSIZ
#define IFNAMESIZ MAX_ADAPTER_NAME
-#endif /* !IFNAMSIZ */
-#endif /* !WIN32 */
+#endif
+
+#endif
namespace ip
{
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.
#ifndef PROTOCOLS_PACKET_H
#define PROTOCOLS_PACKET_H
-/* I N C L U D E S **********************************************************/
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#ifndef WIN32
+
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
+
#else
+
#include <netinet/in_systm.h>
#ifndef IFNAMSIZ
#define IFNAMESIZ MAX_ADAPTER_NAME
#endif
+
#endif
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 */
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
//--------------------------------------------------------------------------
// packet_manager.cc author Josh Rosenbaum <jrosenba@cisco.com>
+#include "protocols/packet_manager.h"
+
#include <vector>
#include <cstring>
#include <mutex>
#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"
#ifndef PROTOCOLS_PACKET_MANAGER_H
#define PROTOCOLS_PACKET_MANAGER_H
+// PacketManager provides decode and encode services by leveraging Codecs.
+
#include <array>
#include <list>
-// 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;
static std::array<PegCount, s_stats.size()> g_stats;
static const std::array<const char*, stat_offset> stat_names;
};
+
#endif
/*****************************************************************
***** 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. ****
****************************************************************/
#ifndef SSL_H
#define SSL_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <ctype.h>
#include <stdlib.h>
#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;
uint8_t certtype;
uint8_t major;
uint8_t minor;
-} SSLv2_shello_t;
+};
#define SSL_V2_MIN_LEN 5
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;
};
} // namespace tcp
-#endif /* TCP_H */
+#endif
};
} // namespace tcp
-#endif /* PROTOCOLS_TCP_OPTIONS_H */
+#endif
}
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
}
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
}
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);
}
}
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
}
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
}
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
}
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
}
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
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 =
#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)
}
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;
/* 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;
* 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;
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;
return acsm->numPatterns;
}
-/*
- *
- */
-/*
static void Print_DFA( ACSM_STRUCT * acsm )
{
int k;
}
}
-*/
-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;
}
// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
-#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
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);
{
switch ( m )
{
- case FSA_TRIE:
case FSA_NFA:
case FSA_DFA:
acsm->acsmFSA = m;
}
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;
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 */
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 */
}
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;
* 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;
{
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;
}
static inline unsigned _process_queue(
- PMQ* q, MpseCallback Match, void* data)
+ PMQ* q, MpseMatch match, void* data)
{
ACSM_PATTERN2* mlist;
unsigned int i;
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;
{ \
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; \
}
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;
if (MatchList[state])
_add_queue(&acsm->q,MatchList[state]);
- _process_queue(&acsm->q,Match,data);
+ _process_queue(&acsm->q, match, data);
return 0;
}
{ \
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; \
}
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;
{
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;
}
}
- _process_queue(&acsm->q,Match,data);
+ _process_queue(&acsm->q, match, data);
return 0;
}
{ \
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; \
}
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
)
{
{
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;
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; \
}
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;
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;
* 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;
{
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;
{
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;
* 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;
{
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;
{
const char* sf[]=
{
- "Full",
- "Sparse",
- "Banded",
- "Sparse-Bands",
- "Full-Q"
+ "full",
+ "sparse",
+ "banded",
+ "sparse-bands",
+ "full-queue"
};
const char* fsa[]=
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)
#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 )
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 )
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;
}
{
acsm->acsmFSA = FSA_DFA;
}
- if (strcmp (argv[i], "-trie") == 0)
- {
- acsm->acsmFSA = FSA_TRIE;
- }
}
for (i = 2; i < argc; i++)
// 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 <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#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
*/
#endif
-/*
-*
-*/
-typedef
- struct _acsm_pattern2
+typedef struct _acsm_pattern2
{
struct _acsm_pattern2* next;
/*
* 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;
/*
* User specified machine types
*
-* TRIE : Keyword trie
* NFA :
* DFA :
*/
enum
{
- FSA_TRIE,
FSA_NFA,
FSA_DFA
};
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);
}
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;
}
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;
* 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;
* 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 )
{
* 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;
* 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 )
{
* 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;
* 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 )
{
}
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;
{
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 )
{
#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;
{
if ( _add_queue(bnfa,mlist) )
{
- if ( _process_queue(bnfa, Match, data) )
+ if ( _process_queue(bnfa, match, data) )
{
return 1;
}
#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;
{
if ( _add_queue(bnfa,mlist) )
{
- if ( _process_queue(bnfa, Match, data) )
+ if ( _process_queue(bnfa, match, data) )
{
*current_state = sindex;
return 1;
}
*current_state = sindex;
- return _process_queue(bnfa, Match, data);
+ return _process_queue(bnfa, match, data);
}
/*
* 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;
* 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 )
{
* 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;
* 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 )
{
* 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;
* 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 )
{
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)
* 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;
_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);
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 )
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
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;
// 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 <mnorton@sourcefire.com>
+
+#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
*/
#include <stdlib.h>
#include <string.h>
-#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 */
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);
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);
*
*/
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);
--- /dev/null
+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
+
}
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
}
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;
#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 <cpa.h>
+#include <pm/cpa_pm.h>
+#include <cpa_types.h>
+
+#include "main/snort_debug.h"
+#include "search_common.h"
-/* DATA TYPES *****************************************************************/
typedef struct _IntelPmPattern
{
void* user_data;
} IntelPmPattern;
struct SnortConfig;
-struct _IntelPmHandles;
+
typedef struct _IntelPm
{
Cpa16U patternGroupId;
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**);
struct _IntelPmHandles* handles;
} IntelPm;
-/* PROTOTYPES *****************************************************************/
void IntelPmStartInstance(void);
void IntelPmStopInstance(void);
void (* option_tree_free)(void** p),
void (* neg_list_free)(void** p));
-void IntelPmDelete(IntelPm* ipm);
+void IntelPmDelete(IntelPm*);
int IntelPmAddPattern(
SnortConfig* sc,
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
#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
#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[] =
{
#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
int SearchTool::find(
const char* str,
unsigned len,
- mpse_action_f mf,
+ MpseMatch mf,
int& state,
bool confine,
void* user_data)
int SearchTool::find(
const char* str,
unsigned len,
- mpse_action_f mf,
+ MpseMatch mf,
bool confine,
void* user_data)
{
int SearchTool::find_all(
const char* str,
unsigned len,
- mpse_action_f mf,
+ MpseMatch mf,
bool confine,
void* user_data)
{
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:
--- /dev/null
+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
+
--- /dev/null
+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++.
+
--- /dev/null
+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.
// 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
// 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;
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
#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;
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;
DNSData session;
};
-#endif /* DNS_H */
+#endif
#ifndef DNS_MODULE_H
#define DNS_MODULE_H
+//Interface to the DNS service inspector
#include "framework/module.h"
#include "framework/bits.h"
};
#endif
-
--- /dev/null
+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.
+
#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"
// 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 <ssturges@sourcefire.com>
+
+// contributors:
+// Daniel J. Roelker <droelker@sourcefire.com>
+// Marc A. Norton <mnorton@sourcefire.com>
+
+#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 <ssturges@sourcefire.com>
- * Daniel J. Roelker <droelker@sourcefire.com>
- * Marc A. Norton <mnorton@sourcefire.com>
*/
-#ifndef FTP_CLIENT_H
-#define FTP_CLIENT_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include <sys/types.h>
-
#include "ftpp_include.h"
struct FTP_CLIENT_REQ
// 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 <ssturges@sourcefire.com>
+
+// contributors:
+// Daniel J. Roelker <droelker@sourcefire.com>
+// Marc A. Norton <mnorton@sourcefire.com>
+
+#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 <ssturges@sourcefire.com>
- * Daniel J. Roelker <droelker@sourcefire.com>
- * Marc A. Norton <mnorton@sourcefire.com>
*/
-#ifndef FTP_SERVER_H
-#define FTP_SERVER_H
#include "ftpp_include.h"
#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
#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
// 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
// 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
// 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
#ifndef HI_UTIL_XMALLOC_H
#define HI_UTIL_XMALLOC_H
+
// FIXIT-L this is a dup of the file in http_inspect
#include <sys/types.h>
// 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 <ssturges@sourcefire.com>
- */
+
+// pp_ftp.h author Steven A. Sturges <ssturges@sourcefire.com>
+
#ifndef PP_FTP_H
#define PP_FTP_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+// declares the ftp checking functions
#include <sys/types.h>
-//#include "protocols/packet.h"
#include "ftpp_ui_config.h"
#include "ftpp_si.h"
// 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 <ssturges@sourcefire.com>
- */
+
+// pp_telnet.h author Steven A. Sturges <ssturges@sourcefire.com>
+
#ifndef PP_TELNET_H
#define PP_TELNET_H
+// declares the telnet checking functions
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 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"
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
)
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 \
--- /dev/null
+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.
+
{
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;
}
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))
{
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))
#ifndef HI_CLIENT_H
#define HI_CLIENT_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <sys/types.h>
#include "hi_main.h"
#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)
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
{
#define GID_HTTP_CLIENT 119
#define GID_HTTP_SERVER 120
-/*
-** Client Events
-*/
+// Client Events
typedef enum _HI_CLI_EVENTS
{
HI_CLIENT_ASCII = 1,
HI_CLIENT_EVENT_NUM
} HI_CLI_EVENTS;
+// Server Events
typedef enum _HI_EVENTS
{
HI_ANOM_SERVER = 1,
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 \
#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 \
#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"
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;
#include <zlib.h>
+#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
int data_extracted;
uint32_t max_seq;
bool flow_depth_excd;
-}HTTP_RESP_STATE;
+} HTTP_RESP_STATE;
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
{
#include <sys/types.h>
#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*);
//--------------------------------------------------------------------------
/*
- * 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
#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;
extern int ReqMethodCheckInit(char*, char*, void**);
extern int ReqMethodCheckEval(void*, uint8_t**, void*);
-#endif /* HI_REQMETHOD_CHECK */
+#endif
#include <string.h>
#include <zlib.h>
-#include "hi_paf.h"
+#include "hi_stream_splitter.h"
#include "main/thread.h"
static THREAD_LOCAL bool headers = false;
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/**
-** @file hi_server.h
-**
-** @author Daniel Roelker <droelker@sourcefire.com>
-**
-** @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 <droelker@sourcefire.com>
+
#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"
#include "hi_client.h"
#include "hi_server.h"
#include "hi_ad.h"
-
#include "sfip/sfip_t.h"
+
struct Packet;
/*
+++ /dev/null
-//--------------------------------------------------------------------------
-// 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 */
-
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// hi_stream_splitter.c author Russ Combs <rcombs@sourcefire.com>
+
//--------------------------------------------------------------------
// hi stuff
//
-// @file hi_paf.c
-// @author Russ Combs <rcombs@sourcefire.com>
-
// the goal is to perform the minimal http paf parsing required for
// correctness while maintaining loose coupling with hi proper:
// * Range, Content-Range, and multipart
//--------------------------------------------------------------------
-#include "hi_paf.h"
+#include "hi_stream_splitter.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
//--------------------------------------------------------------------
// hi stuff
//
-// @file hi_paf.h
+// @file hi_stream_splitter.h
// @author Russ Combs <rcombs@sourcefire.com>
//--------------------------------------------------------------------
-#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"
#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
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,
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;
//--------------------------------------------------------------------------
/**
-** @file hi_ui_iis_unicode_map.h
-**
** @author Daniel Roelker <droelker@sourcefire.com>
-**
-** @brief Header file for hi_ui_iis_unicode_map functions.
*/
#ifndef HI_UI_IIS_UNICODE_MAP_H
#define HI_UI_IIS_UNICODE_MAP_H
#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);
#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
** 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
*/
// 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
// 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;
void* userdata; /* data associated with this pattern */
} KEYNODE;
-/*
-*
-*/
typedef struct _kmapnode
{
int nodechar; /* node character */
KEYNODE* knode;
} KMAPNODE;
-/*
-*
-*/
typedef void (* KMapUserFreeFunc)(void* p);
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);
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
-** util.c
-*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <time.h>
#include <sys/types.h>
#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;
#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;
-}
-
#include <sys/types.h>
void* xmalloc(size_t byteSize);
-char* xstrdup(const char* str);
-
-void xshowmem(void);
void xfree(void*);
#endif
#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"
--- /dev/null
+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.
// 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 <bbantwal@cisco.com>
- *
- *
- */
+// imap.cc author Bhagyashree Bantwal <bbantwal@cisco.com>
+
#include "imap.h"
#ifdef HAVE_CONFIG_H
// 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 <bbantwal@cisco.com>
- */
+// imap.h author Bhagyashree Bantwal <bbantwal@cisco.com>
#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,
HDR_CONT_DISP,
HDR_LAST
} IMAPHdrEnum;
+
struct IMAPSearch
{
const char* name;
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;
// 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
-
#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"
};
#endif
-
-/****************************************************************************
- * 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 <huica@cisco.com>
#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
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;
};
ImapPafData state;
};
+// Function: Check if IMAP data end is reached
bool imap_is_data_end(void* ssn);
#endif
--- /dev/null
+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.
+
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,
{
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
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
--- /dev/null
+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.
// 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
// 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 <bbantwal@cisco.com>
- */
+// pop.h author Bhagyashree Bantwal <bbantwal@cisco.com>
#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,
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;
};
#endif
-
#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;
};
#include "framework/bits.h"
#include "main/thread.h"
#include "pop_config.h"
+// Interface to the IMAP service inspector
#define GID_POP 142
};
#endif
-
-/****************************************************************************
- * 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 <huica@cisco.com>
#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;
};
PopPafData state;
};
+// Function: Callback to check if POP data end is reached
bool pop_is_data_end(void* ssn);
#endif
--- /dev/null
+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.
#ifndef RPC_MODULE_H
#define RPC_MODULE_H
+// Interface to the RPC decode service inspector
#include "framework/module.h"
#include "framework/bits.h"
};
#endif
-
--- /dev/null
+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.
+
//--------------------------------------------------------------------------
//
-/*
- * 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"
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
// 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 <huica@cisco.com>
+
+// sip_common.h author Hui Cao <huica@cisco.com>
#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;
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
// 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 <huica@cisco.com>
- *
- *
- */
+// sip_config.cc author Hui Cao <huica@cisco.com>
#include "sip_config.h"
#include "util.h"
// 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 <huica@cisco.com>
+// sip_config.h author Hui Cao <huica@cisco.com>
#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
extern THREAD_LOCAL SIP_Stats sip_stats;
-/*
- * Header fields and processing functions
- */
+
+// Header fields and processing functions
struct SIPMethod
{
const char* name;
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
// 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 <huica@cisco.com>
+// sip_dialog.cc author Hui Cao <huica@cisco.com>
#include "sip_dialog.h"
// 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 <huica@cisco.com>
+// sip_dialog.h author Hui Cao <huica@cisco.com>
#ifndef SIP_DIALOG_H
#define SIP_DIALOG_H
+// Dialog management for SIP call flow analysis
+
#include "sip_config.h"
#include "sip_parser.h"
#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
#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"
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-//Author: Hui Cao <huica@cisco.com>
+// sip_parser.cc author Hui Cao <huica@cisco.com>
#ifdef HAVE_CONFIG_H
#include "config.h"
#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*/
// 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 <huica@cisco.com>
+// sip_parser.h author Hui Cao <huica@cisco.com>
#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;
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;
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;
const char* userAgent;
const char* userName;
const char* server;
-} SIPMsg;
+};
#define SIPMSG_ZERO_LEN offsetof(SIPMsg, isTcp)
// 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 <huica@cisco.com>
+// sip_roptions.h author Hui Cao <huica@cisco.com>
#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
// 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 <huica@cisco.com>
+// sip_utils.cc author: Hui Cao <huica@cisco.com>
#include "sip_utils.h"
// 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 <huica@cisco.com>
+// sip_utils.h author Hui Cao <huica@cisco.com>
#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
--- /dev/null
+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.
#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"
// 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 <bbantwal@cisco.com>
- */
+// smtp.h author Bhagyashree Bantwal <bbantwal@cisco.com>
#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
#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
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
{
extern THREAD_LOCAL bool smtp_normalizing;
#endif
-
// 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,
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
};
#endif
-
#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"
#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
};
#endif
-
//--------------------------------------------------------------------------
-// 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
#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
-
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// smtp_paf.h author Hui Cao <huica@ciso.com>
+
#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,
const char* search_state;
};
-/* State tracker for SMTP PAF */
+// State tracker for SMTP PAF
struct SmtpPafData
{
DataEndState data_end_state;
SmtpPafData state;
};
+// Function: Check if IMAP data end is reached
bool smtp_is_data_end(void* ssn);
#endif
-
// 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"
//--------------------------------------------------------------------------
-// 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
// 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"
void SMTP_ResetAltBuffer();
#endif
-
//--------------------------------------------------------------------------
-// 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
// 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"
//--------------------------------------------------------------------------
-// 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
// 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"
int ParseXLink2State(SMTP_PROTO_CONF*, Packet*, SMTPData*, const uint8_t*);
#endif
-
--- /dev/null
+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.
// 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"
// 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
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)
#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 )
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
#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
// 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;
#define SSH_DEFAULT_MAX_CLIENT_BYTES 19600
#define SSH_DEFAULT_MAX_SERVER_VERSION_LEN 80
-
#endif
-
#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"
};
#endif
-
--- /dev/null
+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.
// 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;
};
#endif
-
// 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 \
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
#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"
};
#endif
-
hexes.cc
spells.cc
wizard.cc
- wizard.h
wiz_module.cc
wiz_module.h
)
magic.cc magic.h \
hexes.cc \
spells.cc \
-wizard.cc wizard.h \
+wizard.cc \
wiz_module.cc wiz_module.h
if STATIC_INSPECTORS
--- /dev/null
+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.
+
typedef std::vector<uint16_t> HexVector;
+// MagicBook is a set of MagicPages implementing a trie
+
class MagicBook
{
public:
#include <string>
using namespace std;
-#include "wizard.h"
#include "magic.h"
//-------------------------------------------------------------------------
#ifndef WIZ_MODULE_H
#define WIZ_MODULE_H
+// wizard management interface
+
#include <string>
#include <vector>
+
#include "framework/module.h"
#include "main/thread.h"
//--------------------------------------------------------------------------
// wizard.cc author Russ Combs <rucombs@cisco.com>
-#include "wizard.h"
-
#include <vector>
using namespace std;
+++ /dev/null
-//--------------------------------------------------------------------------
-// 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 <rucombs@cisco.com>
-
-#ifndef WIZARD_H
-#define WIZARD_H
-
-#include <string>
-
-#endif
-
--- /dev/null
+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
+
#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
#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
* 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 <cstdio>
#include "sfip/sf_returns.h"
#ifndef SFIP_SFIP_T_H
#define SFIP_SFIP_T_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <cstddef>
#include <stdint.h>
#include <arpa/inet.h>
--- /dev/null
+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.
+
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;
}
{
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)
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
- * @file sfrt.h
- * @author Adam Keeton <akeeton@sourcefire.com>
- * @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 <akeeton@sourcefire.com>
+// Thu July 20 10:16:26 EDT 2006
#ifndef SFRT_H
#define SFRT_H
#include <stdlib.h>
#include <sys/types.h>
+
#include "main/snort_debug.h"
#include "sfrt/sfrt_trie.h"
#include "sfip/sfip_t.h"
* @author Adam Keeton <akeeton@sourcefire.com>
* @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 <stdint.h>
/*******************************************************************/
/*
** 9/7/2011 - Initial implementation ... Hui Cao <hcao@sourcefire.com>
**
-** 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 */
#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"
--- /dev/null
+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.
+
#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;
#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[];
#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);
#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;
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
- * @file stream_ip.h
- * @author Russ Combs <rcombs@sourcefire.com>
- *
- */
+// file stream_ip.h author Russ Combs <rcombs@sourcefire.com>
#ifndef STREAM_IP_H
#define STREAM_IP_H
#define PAF_H
#include <stdint.h>
-#include "snort_types.h"
+
+#include "main/snort_types.h"
#include "stream/stream_api.h"
#include "stream/stream_splitter.h"
#ifndef STREAM_H
#define STREAM_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <sys/types.h>
#include <netinet/in.h>
-#include "snort_types.h"
+#include "main/snort_types.h"
#include "stream/stream_api.h"
#include "network_inspectors/normalize/norm.h"
// 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 <sys/types.h>
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
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);
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);
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*);
#include <string>
#include <vector>
-#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
//--------------------------------------------------------------------------
/*
- * @file stream_tcp.c
- * @author Martin Roesch <roesch@sourcefire.com>
- * @author Steven Sturges <ssturges@sourcefire.com>
+ * stream_tcp.c authors:
+ * Martin Roesch <roesch@sourcefire.com>
+ * Steven Sturges <ssturges@sourcefire.com>
+ * Russ Combs <rcombs@sourcefire.com>
*/
/*
{
unsigned int flushSize = ss->size;
- //copy only till flush buffer gets full
+ // copy only till flush buffer gets full
if ( flushSize > flushBufSize )
flushSize = flushBufSize;
#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"
#include <string>
#include <vector>
-#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;
#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;
--- /dev/null
+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.
+
// 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
// 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);
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
// 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
#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
--- /dev/null
+=== 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/.
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;
}
#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();
#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 <unistd.h>
-/* INTEL LINUX/BSD/.. */
+// INTEL LINUX/BSD/..
#if (defined(__i386) || defined(__amd64) || defined(__x86_64__))
#define get_clockticks(val) \
{ \
val = _Asm_mov_from_ar (_AREG_ITC); \
}
#else
-/* POWER PC */
+// POWER PC
#if (defined(__GNUC__) && (defined(__powerpc__) || (defined(__ppc__))))
#define get_clockticks(val) \
{ \
val = ((uint64_t)tbl) | (((uint64_t)tbu0) << 32); \
}
#else
-/* SPARC */
+// SPARC
#ifdef SPARCV9
#ifdef _LP64
#define get_clockticks(val) \
: "=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)
{
return (double)(end-start)/1e6;
}
-#endif /* CPUCLOCK_H */
+#endif
--- /dev/null
+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.
#ifndef PACKET_TIME_H
#define PACKET_TIME_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <sys/time.h>
-#include <cstdint>
+#include <stdint.h>
void packet_time_update(const struct timeval* cur_tv);
time_t packet_time(void);
#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();
// 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 <mnorton@sourcefire.com>
- */
+// ppm.h author Marc Norton <mnorton@sourcefire.com>
#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
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;
};
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];
#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
#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
{ \
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() \
} \
}
-/* 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 ) \
#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 ) \
{ \
#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
// 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 <rucombs@cisco.com>
#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
{ return GID_PPM; }
};
-#endif
+#endif // PPM_MGR
#endif
#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;
double pct_of_total;
} Preproc_WorstPerformer;
-/* Globals ********************************************************************/
static THREAD_LOCAL double ticks_per_microsec = 0.0;
static OTN_WorstPerformer* worstPerformers = NULL;
//--------------------------------------------------------------------------
// Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved.
// Copyright (C) 2005-2013 Sourcefire, Inc.
-// Author: Steven Sturges <ssturges@sourcefire.com>
//
// 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
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
+// profiler.h author Steven Sturges <ssturges@sourcefire.com>
+
#ifndef PROFILER_H
#define PROFILER_H
+// Facilities for performance profiling
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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
#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)
}
#define MODULE_PROFILE_TMPEND(ppstat) MODULE_PROFILE_TMPEND_NAMED(snort, ppstat)
-/************** Profiling API ******************/
+
+// -----------------------------------------------------------------------------
+// Profiling API
+// -----------------------------------------------------------------------------
+
struct ProfileConfig
{
int num;
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*);
#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()
{
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
+
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
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 \
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-/*
-** Dan Roelker <droelker@sourcefire.com>
-** Marc Norton <mnorton@sourcefire.com>
-**
-** 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 <droelker@sourcefire.com>
+// and Marc Norton <mnorton@sourcefire.com>
#ifndef BITOP_H
#define BITOP_H
+// A poor man's bit vector implementation
+
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
// 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
#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*);
--- /dev/null
+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.
+
#ifndef UTILS_DNET_HEADER_H
#define UTILS_DNET_HEADER_H
+// Provide the correct dnet interface
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
-// Encoder FOO
#ifdef HAVE_DUMBNET_H
#include <dumbnet.h>
#else
#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);
// 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 <hcao@sourcefire.com>
+// segment_mem.h author Hui Cao <huica@cisco.com>
#ifndef SEGMENT_MEM_H
#define SEGMENT_MEM_H
-#include <stdlib.h>
+// 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);
// 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 <pmullen@sourcefire.com>
+// sf_base64decode.h author Patrick Mullen <pmullen@sourcefire.com>
#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
#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)
// 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 <bbantwal@sourcefire.com>
+// sf_email_attach_decode.h author Bhagyashree Bantwal <bbantwal@cisco.com>
#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 <stdlib.h>
+
+#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,
int depth;
};
+// Should be a C++ OOP struct with constructor, etc
struct Email_DecodeState
{
DecodeType decode_type;
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)
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;
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)
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))
}
}
+// 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;
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;
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;
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;
// 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 <mnorton@sourcefire.com>
-//---------------------------------------------------------------
-// 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;
}
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;
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;
unsigned n;
};
-/*
-* Simple Structure for Queue's, stacks, lists
-*/
+// Simple Structure for Queue's, stacks, lists
struct sf_list
{
SF_LNODE* head, * tail;
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);
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*);
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*);
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);
// 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;
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);
// 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 <ststurge@cisco.com>
-/*
-*
-* 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
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// Chris Green <cmg@sourcefire.com>
+// snort_bounds.h author Chris Green <cmg@sourcefire.com>
#ifndef SNORT_BOUNDS_H
#define SNORT_BOUNDS_H
+// Bounds checking for pointers to buffers
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif
#include <unistd.h>
+// FIXIT-L: Change dependent return types to bool and git rid of these
#define SAFEMEM_ERROR 0
#define SAFEMEM_SUCCESS 1
#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;
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)
{
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;
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;
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)
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;
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))
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))
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;
return (size_t)ret;
}
-#endif /* SNORT_BOUNDS_H */
+#endif
}
}
+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 )
#ifndef STATS_H
#define STATS_H
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+// Provides facilities for displaying Snort exit stats
#include <sys/time.h>
#include <sys/types.h>
#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;
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);
#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*);
#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 <sys/time.h>
#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
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);
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);
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);
{
void* ret_val = calloc(num, size);
if (ret_val == nullptr)
- {
throw std::bad_alloc();
- }
+
return ret_val;
}
// 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
// reentrant.
char* get_tok(char* s, const char* delim);
-#endif /*__UTIL_H__*/
+#endif
// Writen by Bhagyashree Bantwal <bbantwal@sourcefire.com>
#include "util_jsnorm.h"
+
+#include <string.h>
#include "main/thread.h"
#define INVALID_HEX_VAL -1
// 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 <bbantwal@sourcefire.com>
+// util_jsnorm.h author Bhagyashree Bantwal <bbantwal@sourcefire.com>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <ctype.h>
+#ifndef UTIL_JSNORM_H
+#define UTIL_JSNORM_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+// Javascript Normalization
+
+#include <stdint.h>
#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
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
+
*/
#include "util_math.h"
-#include "snort_types.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
/**
* Calculate the percentage of something.
// 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 <cmg@sourcefire.com>
- * @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 <cmg@sourcefire.com>
#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
// 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 <cmg@sourcefire.com>
- * @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 <cmg@sourcefire.com>
#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
// 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 <bbantwal@sourcefire.com>
+// util_unfold.h author Bhagyashree Bantwal <bbantwal@sourcefire.com>
#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*);
#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
#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