From: Michael Altizer (mialtize) Date: Mon, 19 Nov 2018 22:16:33 +0000 (-0500) Subject: Merge pull request #1436 in SNORT/snort3 from ~CWAXMAN/snort3:_offload_context_active... X-Git-Tag: 3.0.0-250~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=94bc9804dfc0d2133f6c18d5af687d22b14d2773;p=thirdparty%2Fsnort3.git Merge pull request #1436 in SNORT/snort3 from ~CWAXMAN/snort3:_offload_context_active to master Squashed commit of the following: commit e8de483008ea240e3bc7095c11d552aee1fcd467 Author: Carter Waxman Date: Mon Nov 12 11:01:38 2018 -0500 active: added peg count for injects commit 489561ea2fa79a178ea26cf696377741bf7895b0 Author: Carter Waxman Date: Fri Oct 26 09:02:16 2018 -0400 active, detection: active state is tied to specific packet, not thread --- diff --git a/src/actions/act_react.cc b/src/actions/act_react.cc index 392c31116..23b9cb01c 100644 --- a/src/actions/act_react.cc +++ b/src/actions/act_react.cc @@ -133,7 +133,7 @@ void ReactAction::exec(Packet* p) { Profile profile(reactPerfStats); - if ( Active::is_reset_candidate(p) ) + if ( p->active->is_reset_candidate(p) ) send(p); } @@ -142,16 +142,18 @@ void ReactAction::send(Packet* p) EncodeFlags df = (p->is_from_server()) ? ENC_FLAG_FWD : 0; EncodeFlags sent = config->buf_len; + Active* act = p->active; + if ( p->packet_flags & PKT_STREAM_EST ) { - Active::send_data(p, df, (uint8_t*)config->resp_buf, config->buf_len); - // Active::send_data() sends a FIN, so need to bump seq by 1. + act->send_data(p, df, (uint8_t*)config->resp_buf, config->buf_len); + // act->send_data() sends a FIN, so need to bump seq by 1. sent++; } EncodeFlags rf = ENC_FLAG_SEQ | (ENC_FLAG_VAL & sent); - Active::send_reset(p, rf); - Active::send_reset(p, ENC_FLAG_FWD); + act->send_reset(p, rf); + act->send_reset(p, ENC_FLAG_FWD); } //------------------------------------------------------------------------- diff --git a/src/actions/act_reject.cc b/src/actions/act_reject.cc index 1ea4ef958..5e58437c8 100644 --- a/src/actions/act_reject.cc +++ b/src/actions/act_reject.cc @@ -98,17 +98,19 @@ void RejectAction::exec(Packet* p) if ( !p->ptrs.ip_api.is_ip() ) return; + Active* act = p->active; + switch ( p->type() ) { case PktType::TCP: - if ( !Active::is_reset_candidate(p) ) + if ( !act->is_reset_candidate(p) ) return; break; case PktType::UDP: case PktType::ICMP: case PktType::IP: - if ( !Active::is_unreachable_candidate(p) ) + if ( !act->is_unreachable_candidate(p) ) return; break; @@ -121,31 +123,32 @@ void RejectAction::exec(Packet* p) void RejectAction::send(Packet* p) { + Active* act = p->active; uint32_t flags = 0; - if ( Active::is_reset_candidate(p) ) + if ( act->is_reset_candidate(p) ) flags |= (mask & REJ_RST_BOTH); - if ( Active::is_unreachable_candidate(p) ) + if ( act->is_unreachable_candidate(p) ) flags |= (mask & REJ_UNR_ALL); if ( flags & REJ_RST_SRC ) - Active::send_reset(p, 0); + act->send_reset(p, 0); if ( flags & REJ_RST_DST ) - Active::send_reset(p, ENC_FLAG_FWD); + act->send_reset(p, ENC_FLAG_FWD); if ( flags & REJ_UNR_FWD ) Active::send_unreach(p, snort::UnreachResponse::FWD); if ( flags & REJ_UNR_NET ) - Active::send_unreach(p, snort::UnreachResponse::NET); + act->send_unreach(p, snort::UnreachResponse::NET); if ( flags & REJ_UNR_HOST ) - Active::send_unreach(p, snort::UnreachResponse::HOST); + act->send_unreach(p, snort::UnreachResponse::HOST); if ( flags & REJ_UNR_PORT ) - Active::send_unreach(p, snort::UnreachResponse::PORT); + act->send_unreach(p, snort::UnreachResponse::PORT); } //------------------------------------------------------------------------- diff --git a/src/actions/actions.cc b/src/actions/actions.cc index 96fb7e786..b00fabdcf 100644 --- a/src/actions/actions.cc +++ b/src/actions/actions.cc @@ -119,19 +119,19 @@ void Actions::execute(Actions::Type action, Packet* p, const OptTreeNode* otn, break; case Actions::DROP: - Active::drop_packet(p); + p->active->drop_packet(p); alert(p, otn); SetTags(p, otn, event_id); break; case Actions::BLOCK: - Active::block_session(p); + p->active->block_session(p); alert(p, otn); SetTags(p, otn, event_id); break; case Actions::RESET: - Active::reset_session(p); + p->active->reset_session(p); alert(p, otn); SetTags(p, otn, event_id); break; @@ -146,15 +146,15 @@ void Actions::apply(Actions::Type action, Packet* p) switch ( action ) { case Actions::DROP: - Active::drop_packet(p); + p->active->drop_packet(p); break; case Actions::BLOCK: - Active::block_session(p); + p->active->block_session(p); break; case Actions::RESET: - Active::reset_session(p); + p->active->reset_session(p); break; default: diff --git a/src/codecs/ip/cd_gre.cc b/src/codecs/ip/cd_gre.cc index c7d04b039..c072212f0 100644 --- a/src/codecs/ip/cd_gre.cc +++ b/src/codecs/ip/cd_gre.cc @@ -26,7 +26,6 @@ #include "framework/codec.h" #include "log/text_log.h" #include "main/snort_config.h" -#include "packet_io/active.h" #include "protocols/gre.h" using namespace snort; @@ -206,7 +205,7 @@ bool GreCodec::decode(const RawData& raw, CodecData& codec, DecodeData&) } if (SnortConfig::tunnel_bypass_enabled(TUNNEL_GRE)) - Active::set_tunnel_bypass(); + codec.tunnel_bypass = true; codec.lyr_len = len; codec.next_prot_id = greh->proto(); diff --git a/src/codecs/ip/cd_ipv4.cc b/src/codecs/ip/cd_ipv4.cc index 3817fd624..22ddf8bf3 100644 --- a/src/codecs/ip/cd_ipv4.cc +++ b/src/codecs/ip/cd_ipv4.cc @@ -27,10 +27,10 @@ #include #include "codecs/codec_module.h" +#include "framework/codec.h" #include "log/log_text.h" #include "log/messages.h" #include "main/snort_config.h" -#include "packet_io/active.h" #include "parser/parse_ip.h" #include "protocols/ip.h" #include "protocols/ipv4.h" @@ -206,7 +206,7 @@ bool Ipv4Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) if ( codec.codec_flags & CODEC_NON_IP_TUNNEL ) codec.codec_flags &= ~CODEC_NON_IP_TUNNEL; else if ( snort::SnortConfig::tunnel_bypass_enabled(TUNNEL_4IN6) ) - Active::set_tunnel_bypass(); + codec.tunnel_bypass = true; } else if (snort.ip_api.is_ip4()) { @@ -214,7 +214,7 @@ bool Ipv4Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) if ( codec.codec_flags & CODEC_NON_IP_TUNNEL ) codec.codec_flags &= ~CODEC_NON_IP_TUNNEL; else if (snort::SnortConfig::tunnel_bypass_enabled(TUNNEL_4IN4)) - Active::set_tunnel_bypass(); + codec.tunnel_bypass = true; } // set the api now since this layer has been verified as valid diff --git a/src/codecs/ip/cd_ipv6.cc b/src/codecs/ip/cd_ipv6.cc index d05cd5557..785e943dd 100644 --- a/src/codecs/ip/cd_ipv6.cc +++ b/src/codecs/ip/cd_ipv6.cc @@ -28,7 +28,6 @@ #include "framework/codec.h" #include "log/text_log.h" #include "main/snort_config.h" -#include "packet_io/active.h" using namespace snort; @@ -188,7 +187,7 @@ bool Ipv6Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) if ( codec.codec_flags & CODEC_NON_IP_TUNNEL ) codec.codec_flags &= ~CODEC_NON_IP_TUNNEL; else if ( SnortConfig::tunnel_bypass_enabled(TUNNEL_6IN4) ) - Active::set_tunnel_bypass(); + codec.tunnel_bypass = true; } else if (snort.ip_api.is_ip6()) { @@ -196,7 +195,7 @@ bool Ipv6Codec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) if ( codec.codec_flags & CODEC_NON_IP_TUNNEL ) codec.codec_flags &= ~CODEC_NON_IP_TUNNEL; else if (SnortConfig::tunnel_bypass_enabled(TUNNEL_6IN6)) - Active::set_tunnel_bypass(); + codec.tunnel_bypass = true; } IPV6CheckIsatap(ip6h, snort, codec); // check for isatap before overwriting the ip_api. diff --git a/src/codecs/link/cd_mpls.cc b/src/codecs/link/cd_mpls.cc index 13ae1ca21..3e04f6692 100644 --- a/src/codecs/link/cd_mpls.cc +++ b/src/codecs/link/cd_mpls.cc @@ -26,7 +26,6 @@ #include "flow/flow.h" #include "framework/codec.h" #include "main/snort_config.h" -#include "packet_io/active.h" #include "utils/safec.h" using namespace snort; @@ -209,7 +208,7 @@ bool MplsCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort) } /* while bos not 1, peel off more labels */ if (SnortConfig::tunnel_bypass_enabled(TUNNEL_MPLS)) - Active::set_tunnel_bypass(); + codec.tunnel_bypass = true; codec.lyr_len = (const uint8_t*)tmpMplsHdr - raw.data; diff --git a/src/codecs/misc/cd_gtp.cc b/src/codecs/misc/cd_gtp.cc index 5bf7100e5..eddd1273a 100644 --- a/src/codecs/misc/cd_gtp.cc +++ b/src/codecs/misc/cd_gtp.cc @@ -25,7 +25,6 @@ #include "codecs/codec_module.h" #include "framework/codec.h" #include "main/snort_config.h" -#include "packet_io/active.h" using namespace snort; @@ -176,7 +175,7 @@ bool GtpCodec::decode(const RawData& raw, CodecData& codec, DecodeData& dd) } if ( SnortConfig::tunnel_bypass_enabled(TUNNEL_GTP) ) - Active::set_tunnel_bypass(); + codec.tunnel_bypass = true; codec.lyr_len = len; codec.proto_bits |= PROTO_BIT__GTP; diff --git a/src/codecs/misc/cd_teredo.cc b/src/codecs/misc/cd_teredo.cc index d1d9a5820..ac7bc215c 100644 --- a/src/codecs/misc/cd_teredo.cc +++ b/src/codecs/misc/cd_teredo.cc @@ -24,7 +24,6 @@ #include "framework/codec.h" #include "main/snort_config.h" -#include "packet_io/active.h" #include "protocols/teredo.h" using namespace snort; @@ -89,7 +88,7 @@ bool TeredoCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort codec.codec_flags |= CODEC_TEREDO_SEEN; // for ipv6 codec if ( SnortConfig::tunnel_bypass_enabled(TUNNEL_TEREDO) ) - Active::set_tunnel_bypass(); + codec.tunnel_bypass = true; if ( (!teredo::is_teredo_port(snort.sp)) && (!teredo::is_teredo_port(snort.dp)) ) codec.codec_flags |= CODEC_ENCAP_LAYER; diff --git a/src/detection/context_switcher.cc b/src/detection/context_switcher.cc index 6c2bf9f65..756e2a3eb 100644 --- a/src/detection/context_switcher.cc +++ b/src/detection/context_switcher.cc @@ -28,6 +28,7 @@ #include "main/modules.h" #include "main/snort_debug.h" +#include "packet_io/active.h" #include "utils/stats.h" #include "detect_trace.h" @@ -81,6 +82,9 @@ void ContextSwitcher::start() get_packet_number(), idle.back()->get_slot(), idle.size(), busy.size()); busy.emplace_back(idle.back()); idle.pop_back(); + + busy.back()->packet->active = busy.back()->packet->active_inst; + busy.back()->packet->active->reset(); } void ContextSwitcher::stop() @@ -92,6 +96,7 @@ void ContextSwitcher::stop() IpsContext* c = busy.back(); c->clear_context_data(); idle.emplace_back(c); + busy.back()->packet->active = nullptr; busy.pop_back(); } @@ -125,6 +130,7 @@ IpsContext* ContextSwitcher::interrupt() assert(!idle.empty()); trace_logf(detection, TRACE_DETECTION_ENGINE, "%" PRIu64 " cs::interrupt %u (i=%zu, b=%zu)\n", idle.back()->packet_number, idle.back()->get_slot(), idle.size(), busy.size()); + busy.emplace_back(idle.back()); idle.pop_back(); return busy.back(); @@ -139,6 +145,7 @@ IpsContext* ContextSwitcher::complete() c->packet_number, busy.back()->get_slot(), idle.size(), busy.size()); c->clear_context_data(); + idle.emplace_back(c); busy.pop_back(); return busy.empty() ? nullptr : busy.back(); @@ -170,7 +177,9 @@ void ContextSwitcher::resume(unsigned slot) IpsContext* ContextSwitcher::get_context() const { - assert(!busy.empty()); + if ( busy.empty() ) + return nullptr; + return busy.back(); } diff --git a/src/detection/detection_engine.cc b/src/detection/detection_engine.cc index 35a025f61..814e777ac 100644 --- a/src/detection/detection_engine.cc +++ b/src/detection/detection_engine.cc @@ -111,6 +111,8 @@ Packet* DetectionEngine::get_encode_packet() // however, rebuild is always in the next context, not current. Packet* DetectionEngine::set_next_packet(Packet* parent) { + static THREAD_LOCAL Active shutdown_active; + IpsContext* c = Snort::get_switcher()->get_next(); if ( parent ) { @@ -126,6 +128,21 @@ Packet* DetectionEngine::set_next_packet(Packet* parent) p->data = c->buf; p->pkt = c->buf; + // normal rebuild + if ( parent ) + p->active = parent->active; + + // processing but parent is already gone (flow cache flush etc..) + else if ( Snort::get_switcher()->get_context() ) + p->active = get_current_packet()->active; + + // shutdown, so use a dummy so nullchecking is needed everywhere + else + { + p->active = &shutdown_active; + shutdown_active.reset(); + } + p->reset(); return p; } @@ -147,7 +164,9 @@ void DetectionEngine::finish_inspect(Packet* p, bool inspected) { log_events(p); - Active::apply_delayed_action(p); + if ( p->active ) + p->active->apply_delayed_action(p); + p->context->post_detection(); // clear closed sessions here after inspection since non-stream @@ -428,7 +447,7 @@ void DetectionEngine::inspect(Packet* p) if ( SnortConfig::inline_mode() and SnortConfig::checksum_drop(p->ptrs.decode_flags & DECODE_ERR_CKSUM_ALL) ) { - Active::drop_packet(p); + p->active->drop_packet(p); } } else diff --git a/src/detection/ips_context.h b/src/detection/ips_context.h index f898598fe..97a4bcbf8 100644 --- a/src/detection/ips_context.h +++ b/src/detection/ips_context.h @@ -94,6 +94,8 @@ public: void post_detection(); public: + std::vector rpl; + Packet* packet; Packet* encode_packet; DAQ_PktHdr_t* pkth; @@ -112,8 +114,6 @@ public: ActiveRules active_rules; bool check_tags; - std::vector rpl; - static const unsigned buf_size = Codec::PKT_MAX; // Only 5 inspectors currently use the ips context data. // FIXIT-L This limit should to be updated if any more inspectors/modules use it. diff --git a/src/file_api/file_api.h b/src/file_api/file_api.h index e74cb0f06..3b0439faa 100644 --- a/src/file_api/file_api.h +++ b/src/file_api/file_api.h @@ -135,11 +135,11 @@ public: virtual void policy_check(Flow*, FileInfo* ) { } // This is called after file type is known - virtual FileVerdict type_lookup(Flow*, FileInfo*) + virtual FileVerdict type_lookup(Packet*, FileInfo*) { return FILE_VERDICT_UNKNOWN; } // This is called after file signature is complete - virtual FileVerdict signature_lookup(Flow*, FileInfo*) + virtual FileVerdict signature_lookup(Packet*, FileInfo*) { return FILE_VERDICT_UNKNOWN; } virtual void log_file_action(Flow*, FileInfo*, FileAction) { } diff --git a/src/file_api/file_cache.cc b/src/file_api/file_cache.cc index 4880b511a..583207d33 100644 --- a/src/file_api/file_cache.cc +++ b/src/file_api/file_cache.cc @@ -193,18 +193,19 @@ FileContext* FileCache::get_file(Flow* flow, uint64_t file_id, bool to_create) return get_file(flow, file_id, to_create, lookup_timeout); } -FileVerdict FileCache::check_verdict(Flow* flow, FileInfo* file, +FileVerdict FileCache::check_verdict(Packet* p, FileInfo* file, FilePolicyBase* policy) { assert(file); + Flow* flow = p->flow; - FileVerdict verdict = policy->type_lookup(flow, file); + FileVerdict verdict = policy->type_lookup(p, file); if ( file->get_file_sig_sha256() and ((verdict == FILE_VERDICT_UNKNOWN) || (verdict == FILE_VERDICT_STOP_CAPTURE))) { - verdict = policy->signature_lookup(flow, file); + verdict = policy->signature_lookup(p, file); } if ((verdict == FILE_VERDICT_UNKNOWN) || @@ -232,11 +233,13 @@ int FileCache::store_verdict(Flow* flow, FileInfo* file, int64_t timeout) return 0; } -bool FileCache::apply_verdict(Flow* flow, FileInfo* file, FileVerdict verdict, +bool FileCache::apply_verdict(Packet* p, FileInfo* file, FileVerdict verdict, bool resume, FilePolicyBase* policy) { - file->verdict = verdict; + Flow* flow = p->flow; + Active* act = p->active; + file->verdict = verdict; switch (verdict) { @@ -248,15 +251,15 @@ bool FileCache::apply_verdict(Flow* flow, FileInfo* file, FileVerdict verdict, return false; case FILE_VERDICT_BLOCK: // can't block session inside a session - Active::set_delayed_action(Active::ACT_BLOCK, true); + act->set_delayed_action(Active::ACT_BLOCK, true); break; case FILE_VERDICT_REJECT: // can't reset session inside a session - Active::set_delayed_action(Active::ACT_RESET, true); + act->set_delayed_action(Active::ACT_RESET, true); break; case FILE_VERDICT_PENDING: - Active::set_delayed_action(Active::ACT_DROP, true); + act->set_delayed_action(Active::ACT_DROP, true); if (resume) policy->log_file_action(flow, file, FILE_RESUME_BLOCK); else @@ -279,9 +282,10 @@ bool FileCache::apply_verdict(Flow* flow, FileInfo* file, FileVerdict verdict, } -FileVerdict FileCache::cached_verdict_lookup(Flow* flow, FileInfo* file, +FileVerdict FileCache::cached_verdict_lookup(Packet* p, FileInfo* file, FilePolicyBase* policy) { + Flow* flow = p->flow; FileVerdict verdict = FILE_VERDICT_UNKNOWN; assert(file); @@ -294,8 +298,8 @@ FileVerdict FileCache::cached_verdict_lookup(Flow* flow, FileInfo* file, if (file_found) { /*Query the file policy in case verdict has been changed*/ - verdict = check_verdict(flow, file_found, policy); - apply_verdict(flow, file_found, verdict, true, policy); + verdict = check_verdict(p, file_found, policy); + apply_verdict(p, file_found, verdict, true, policy); } return verdict; diff --git a/src/file_api/file_cache.h b/src/file_api/file_cache.h index a7cbc7b3f..f9942ede2 100644 --- a/src/file_api/file_cache.h +++ b/src/file_api/file_cache.h @@ -62,16 +62,16 @@ PADDING_GUARD_END void set_max_files(int64_t); snort::FileContext* get_file(snort::Flow*, uint64_t file_id, bool to_create); - FileVerdict cached_verdict_lookup(snort::Flow*, snort::FileInfo*, + FileVerdict cached_verdict_lookup(snort::Packet*, snort::FileInfo*, snort::FilePolicyBase*); - bool apply_verdict(snort::Flow*, snort::FileInfo*, FileVerdict, bool resume, + bool apply_verdict(snort::Packet*, snort::FileInfo*, FileVerdict, bool resume, snort::FilePolicyBase*); private: snort::FileContext* add(const FileHashKey&, int64_t timeout); snort::FileContext* find(const FileHashKey&, int64_t); snort::FileContext* get_file(snort::Flow*, uint64_t file_id, bool to_create, int64_t timeout); - FileVerdict check_verdict(snort::Flow*, snort::FileInfo*, snort::FilePolicyBase*); + FileVerdict check_verdict(snort::Packet*, snort::FileInfo*, snort::FilePolicyBase*); int store_verdict(snort::Flow*, snort::FileInfo*, int64_t timeout); /* The hash table of expected files */ diff --git a/src/file_api/file_flows.cc b/src/file_api/file_flows.cc index ef7817ac2..a380e15ce 100644 --- a/src/file_api/file_flows.cc +++ b/src/file_api/file_flows.cc @@ -63,7 +63,7 @@ namespace snort } } -void FileFlows::handle_retransmit (Packet*) +void FileFlows::handle_retransmit(Packet* p) { if (file_policy == nullptr) return; @@ -72,10 +72,10 @@ void FileFlows::handle_retransmit (Packet*) if ((file == nullptr) or (file->verdict != FILE_VERDICT_PENDING)) return; - FileVerdict verdict = file_policy->signature_lookup(flow, file); + FileVerdict verdict = file_policy->signature_lookup(p, file); FileCache* file_cache = FileService::get_file_cache(); if (file_cache) - file_cache->apply_verdict(flow, file, verdict, false, file_policy); + file_cache->apply_verdict(p, file, verdict, false, file_policy); file->log_file_event(flow, file_policy); } @@ -183,7 +183,7 @@ FileContext* FileFlows::get_file_context(uint64_t file_id, bool to_create) * true: continue processing/log/block this file * false: ignore this file */ -bool FileFlows::file_process(uint64_t file_id, const uint8_t* file_data, +bool FileFlows::file_process(Packet* p, uint64_t file_id, const uint8_t* file_data, int data_size, uint64_t offset, FileDirection dir) { int64_t file_depth = FileService::get_max_file_depth(); @@ -214,11 +214,11 @@ bool FileFlows::file_process(uint64_t file_id, const uint8_t* file_data, { /* Just check file type and signature */ FilePosition position = SNORT_FILE_FULL; - return context->process(flow, file_data, data_size, position, file_policy); + return context->process(p, file_data, data_size, position, file_policy); } } - return context->process(flow, file_data, data_size, offset, file_policy); + return context->process(p, file_data, data_size, offset, file_policy); } /* @@ -226,7 +226,7 @@ bool FileFlows::file_process(uint64_t file_id, const uint8_t* file_data, * true: continue processing/log/block this file * false: ignore this file */ -bool FileFlows::file_process(const uint8_t* file_data, int data_size, +bool FileFlows::file_process(Packet* p, const uint8_t* file_data, int data_size, FilePosition position, bool upload, size_t file_index) { FileContext* context; @@ -243,7 +243,7 @@ bool FileFlows::file_process(const uint8_t* file_data, int data_size, set_current_file_context(context); context->set_signature_state(gen_signature); - return context->process(flow, file_data, data_size, position, file_policy); + return context->process(p, file_data, data_size, position, file_policy); } void FileFlows::set_file_name(const uint8_t* fname, uint32_t name_size) diff --git a/src/file_api/file_flows.h b/src/file_api/file_flows.h index 4f794f02c..fa3ba1214 100644 --- a/src/file_api/file_flows.h +++ b/src/file_api/file_flows.h @@ -80,11 +80,11 @@ public: void add_pending_file(uint64_t file_id); // This is used when there is only one file per session - bool file_process(const uint8_t* file_data, int data_size, FilePosition, + bool file_process(Packet* p, const uint8_t* file_data, int data_size, FilePosition, bool upload, size_t file_index = 0); // This is used for each file context. Support multiple files per session - bool file_process(uint64_t file_id, const uint8_t* file_data, + bool file_process(Packet* p, uint64_t file_id, const uint8_t* file_data, int data_size, uint64_t offset, FileDirection); static unsigned file_flow_data_id; diff --git a/src/file_api/file_lib.cc b/src/file_api/file_lib.cc index 9e0f1f085..b31c327bf 100644 --- a/src/file_api/file_lib.cc +++ b/src/file_api/file_lib.cc @@ -38,6 +38,7 @@ #include "framework/data_bus.h" #include "main/snort_config.h" #include "managers/inspector_manager.h" +#include "protocols/packet.h" #include "utils/util.h" #include "utils/util_utf.h" @@ -314,29 +315,33 @@ void FileContext::log_file_event(Flow* flow, FilePolicyBase* policy) } } -FileVerdict FileContext::file_signature_lookup(Flow* flow) +FileVerdict FileContext::file_signature_lookup(Packet* p) { + Flow* flow = p->flow; + if (get_file_sig_sha256()) { FilePolicyBase* policy = FileFlows::get_file_policy(flow); if (policy) - return policy->signature_lookup(flow, this); + return policy->signature_lookup(p, this); } return FILE_VERDICT_UNKNOWN; } -void FileContext::finish_signature_lookup(Flow* flow, bool final_lookup, FilePolicyBase* policy) +void FileContext::finish_signature_lookup(Packet* p, bool final_lookup, FilePolicyBase* policy) { + Flow* flow = p->flow; + if (get_file_sig_sha256()) { - verdict = policy->signature_lookup(flow, this); + verdict = policy->signature_lookup(p, this); if ( verdict != FILE_VERDICT_UNKNOWN || final_lookup ) { FileCache* file_cache = FileService::get_file_cache(); if (file_cache) - file_cache->apply_verdict(flow, this, verdict, false, policy); + file_cache->apply_verdict(p, this, verdict, false, policy); log_file_event(flow, policy); config_file_signature(false); file_stats->signatures_processed[get_file_type()][get_file_direction()]++; @@ -379,9 +384,10 @@ void FileContext::check_policy(Flow* flow, FileDirection dir, FilePolicyBase* po * true: continue processing/log/block this file * false: ignore this file */ -bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size, +bool FileContext::process(Packet* p, const uint8_t* file_data, int data_size, FilePosition position, FilePolicyBase* policy) { + Flow* flow = p->flow; if ( config->trace_stream ) { @@ -397,7 +403,7 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size, return false; } - if ((FileService::get_file_cache()->cached_verdict_lookup(flow, this, + if ((FileService::get_file_cache()->cached_verdict_lookup(p, this, policy) != FILE_VERDICT_UNKNOWN)) return true; @@ -421,12 +427,12 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size, config_file_type(false); file_stats->files_processed[get_file_type()][get_file_direction()]++; //Check file type based on file policy - FileVerdict v = policy->type_lookup(flow, this); + FileVerdict v = policy->type_lookup(p, this); if ( v != FILE_VERDICT_UNKNOWN ) { FileCache* file_cache = FileService::get_file_cache(); if (file_cache) - file_cache->apply_verdict(flow, this, v, false, policy); + file_cache->apply_verdict(p, this, v, false, policy); } log_file_event(flow, policy); @@ -453,7 +459,7 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size, process_file_capture(file_data, data_size, position); } - finish_signature_lookup(flow, ( file_state.sig_state != FILE_SIG_FLUSH ), policy); + finish_signature_lookup(p, ( file_state.sig_state != FILE_SIG_FLUSH ), policy); } else { @@ -463,12 +469,12 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size, return true; } -bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size, +bool FileContext::process(Packet* p, const uint8_t* file_data, int data_size, uint64_t offset, FilePolicyBase* policy) { if (!file_segments) file_segments = new FileSegments(this); - return file_segments->process(flow, file_data, data_size, offset, policy); + return file_segments->process(p, file_data, data_size, offset, policy); } /* diff --git a/src/file_api/file_lib.h b/src/file_api/file_lib.h index e6016035e..4517ccded 100644 --- a/src/file_api/file_lib.h +++ b/src/file_api/file_lib.h @@ -110,15 +110,15 @@ public: // Return: // true: continue processing/log/block this file // false: ignore this file - bool process(Flow*, const uint8_t* file_data, int data_size, FilePosition, FilePolicyBase*); - bool process(Flow*, const uint8_t* file_data, int data_size, uint64_t offset, FilePolicyBase*); + bool process(Packet*, const uint8_t* file_data, int data_size, FilePosition, FilePolicyBase*); + bool process(Packet*, const uint8_t* file_data, int data_size, uint64_t offset, FilePolicyBase*); void process_file_type(const uint8_t* file_data, int data_size, FilePosition); void process_file_signature_sha256(const uint8_t* file_data, int data_size, FilePosition); void update_file_size(int data_size, FilePosition position); void stop_file_capture(); FileCaptureState process_file_capture(const uint8_t* file_data, int data_size, FilePosition); void log_file_event(Flow*, FilePolicyBase*); - FileVerdict file_signature_lookup(Flow*); + FileVerdict file_signature_lookup(Packet*); void set_signature_state(bool gen_sig); @@ -140,7 +140,7 @@ private: FileConfig* config; inline void finalize_file_type(); - inline void finish_signature_lookup(Flow*, bool, FilePolicyBase*); + inline void finish_signature_lookup(Packet*, bool, FilePolicyBase*); }; } #endif diff --git a/src/file_api/file_policy.cc b/src/file_api/file_policy.cc index e1b672022..888cd57b0 100644 --- a/src/file_api/file_policy.cc +++ b/src/file_api/file_policy.cc @@ -159,7 +159,7 @@ void FilePolicy::policy_check(Flow*, FileInfo* file) file->config_file_capture(capture_enabled); } -FileVerdict FilePolicy::type_lookup(Flow*, FileInfo* file) +FileVerdict FilePolicy::type_lookup(Packet*, FileInfo* file) { FileRule rule = match_file_rule(nullptr, file); file->config_file_signature(rule.use.signature_enabled); @@ -167,7 +167,7 @@ FileVerdict FilePolicy::type_lookup(Flow*, FileInfo* file) return rule.use.verdict; } -FileVerdict FilePolicy::signature_lookup(Flow*, FileInfo* file) +FileVerdict FilePolicy::signature_lookup(Packet*, FileInfo* file) { FileRule& rule = match_file_rule(nullptr, file); diff --git a/src/file_api/file_policy.h b/src/file_api/file_policy.h index 71ace2bb6..de91f2527 100644 --- a/src/file_api/file_policy.h +++ b/src/file_api/file_policy.h @@ -64,10 +64,10 @@ public: void policy_check(snort::Flow*, snort::FileInfo*) override; // This is called after file type is known - FileVerdict type_lookup(snort::Flow*, snort::FileInfo*) override; + FileVerdict type_lookup(snort::Packet*, snort::FileInfo*) override; // This is called after file signature is complete - FileVerdict signature_lookup(snort::Flow*, snort::FileInfo*) override; + FileVerdict signature_lookup(snort::Packet*, snort::FileInfo*) override; void insert_file_rule(FileRule&); void set_file_type(bool enabled); diff --git a/src/file_api/file_segment.cc b/src/file_api/file_segment.cc index 027189f2e..1af9b31a1 100644 --- a/src/file_api/file_segment.cc +++ b/src/file_api/file_segment.cc @@ -150,22 +150,22 @@ FilePosition FileSegments::get_file_position(uint64_t data_size, uint64_t file_s return SNORT_FILE_MIDDLE; } -int FileSegments::process_one(snort::Flow* flow, const uint8_t* file_data, int data_size, +int FileSegments::process_one(snort::Packet* p, const uint8_t* file_data, int data_size, snort::FilePolicyBase* policy) { FilePosition position = get_file_position(data_size, context->get_file_size()); - return context->process(flow, file_data, data_size, position, policy); + return context->process(p, file_data, data_size, position, policy); } -int FileSegments::process_all(snort::Flow* flow, snort::FilePolicyBase* policy) +int FileSegments::process_all(snort::Packet* p, snort::FilePolicyBase* policy) { int ret = 1; FileSegment* current_segment = head; while (current_segment && (current_offset == current_segment->offset)) { - ret = process_one(flow, (const uint8_t*)current_segment->data->data(), + ret = process_one(p, (const uint8_t*)current_segment->data->data(), current_segment->data->size(), policy); if (!ret) @@ -190,7 +190,7 @@ int FileSegments::process_all(snort::Flow* flow, snort::FilePolicyBase* policy) * 1: continue processing/log/block this file * 0: ignore this file */ -int FileSegments::process(snort::Flow* flow, const uint8_t* file_data, uint64_t data_size, +int FileSegments::process(snort::Packet* p, const uint8_t* file_data, uint64_t data_size, uint64_t offset, snort::FilePolicyBase* policy) { int ret = 0; @@ -203,7 +203,7 @@ int FileSegments::process(snort::Flow* flow, const uint8_t* file_data, uint64_t // Walk through the segments that can be flushed if (current_offset == offset) { - ret = process_one(flow, file_data, data_size, policy); + ret = process_one(p, file_data, data_size, policy); current_offset += data_size; if (!ret) { @@ -211,7 +211,7 @@ int FileSegments::process(snort::Flow* flow, const uint8_t* file_data, uint64_t return 0; } - ret = process_all(flow, policy); + ret = process_all(p, policy); } else if ((current_offset < context->get_file_size()) && (current_offset < offset)) { diff --git a/src/file_api/file_segment.h b/src/file_api/file_segment.h index c06ba4e91..978125b5d 100644 --- a/src/file_api/file_segment.h +++ b/src/file_api/file_segment.h @@ -54,7 +54,7 @@ public: // Process file segments with current_offset specified. If file segment is out of order, // it will be put into the file segments queue. - int process(snort::Flow*, const uint8_t* file_data, uint64_t data_size, uint64_t offset, + int process(snort::Packet*, const uint8_t* file_data, uint64_t data_size, uint64_t offset, snort::FilePolicyBase*); private: @@ -64,8 +64,8 @@ private: void add(const uint8_t* file_data, uint64_t data_size, uint64_t offset); FilePosition get_file_position(uint64_t data_size, uint64_t file_size); - int process_one(snort::Flow*, const uint8_t* file_data, int data_size, snort::FilePolicyBase*); - int process_all(snort::Flow*, snort::FilePolicyBase*); + int process_one(snort::Packet*, const uint8_t* file_data, int data_size, snort::FilePolicyBase*); + int process_all(snort::Packet*, snort::FilePolicyBase*); }; #endif diff --git a/src/flow/flow_cache.cc b/src/flow/flow_cache.cc index 99860506c..a3ec40223 100644 --- a/src/flow/flow_cache.cc +++ b/src/flow/flow_cache.cc @@ -294,7 +294,7 @@ bool FlowCache::prune_one(PruneReason reason, bool do_cleanup) unsigned FlowCache::timeout(unsigned num_flows, time_t thetime) { - // FIXIT-H should Active be suspended here too? + ActiveSuspendContext act_susp; unsigned retired = 0; auto flow = static_cast(hash_table->current()); diff --git a/src/flow/flow_control.cc b/src/flow/flow_control.cc index 868f2a36d..0cd821e85 100644 --- a/src/flow/flow_control.cc +++ b/src/flow/flow_control.cc @@ -138,7 +138,7 @@ void FlowControl::timeout_flows(time_t cur_time) if ( types.empty() ) return; - Active::suspend(); + ActiveSuspendContext act_susp; FlowCache* fc = get_cache(types[next]); if ( ++next >= types.size() ) @@ -146,8 +146,6 @@ void FlowControl::timeout_flows(time_t cur_time) if ( fc ) fc->timeout(1, cur_time); - - Active::resume(); } void FlowControl::preemptive_cleanup() @@ -452,20 +450,20 @@ unsigned FlowControl::process(Flow* flow, Packet* p) case Flow::FlowState::BLOCK: if ( news ) - Stream::drop_traffic(flow, SSN_DIR_BOTH); + Stream::drop_traffic(p, SSN_DIR_BOTH); else - Active::block_again(); + p->active->block_again(); DetectionEngine::disable_all(p); break; case Flow::FlowState::RESET: if ( news ) - Stream::drop_traffic(flow, SSN_DIR_BOTH); + Stream::drop_traffic(p, SSN_DIR_BOTH); else - Active::reset_again(); + p->active->reset_again(); - Stream::blocked_flow(flow, p); + Stream::blocked_flow(p); DetectionEngine::disable_all(p); break; } diff --git a/src/framework/codec.h b/src/framework/codec.h index 4a89ace1f..c8dd4e387 100644 --- a/src/framework/codec.h +++ b/src/framework/codec.h @@ -56,7 +56,6 @@ struct ICMPHdr; class Flow; struct Layer; -struct Packet; // Used by root codecs to add their DLT to their HELP string #define ADD_DLT(help, x) help " (DLT " STRINGIFY_MX(x) ")" @@ -135,9 +134,10 @@ struct CodecData uint8_t ip6_extension_count; /* initialized in cd_ipv6.cc */ uint8_t curr_ip6_extension; /* initialized in cd_ipv6.cc */ IpProtocol ip6_csum_proto; /* initialized in cd_ipv6.cc. Used for IPv6 checksums */ + bool tunnel_bypass; CodecData(ProtocolId init_prot) : next_prot_id(init_prot), lyr_len(0), - invalid_bytes(0), proto_bits(0), codec_flags(0), ip_layer_cnt(0) + invalid_bytes(0), proto_bits(0), codec_flags(0), ip_layer_cnt(0), tunnel_bypass(false) { } bool inline is_cooked() const @@ -368,7 +368,7 @@ private: //------------------------------------------------------------------------- // this is the current version of the api -#define CDAPI_VERSION ((BASE_API_VERSION << 16) | 0) +#define CDAPI_VERSION ((BASE_API_VERSION << 16) | 1) typedef Codec* (* CdNewFunc)(Module*); typedef void (* CdDelFunc)(Codec*); diff --git a/src/loggers/alert_csv.cc b/src/loggers/alert_csv.cc index dca96e18f..f3a3d3970 100644 --- a/src/loggers/alert_csv.cc +++ b/src/loggers/alert_csv.cc @@ -69,9 +69,9 @@ struct Args const Event& event; }; -static void ff_action(Args&) +static void ff_action(Args& a) { - TextLog_Puts(csv_log, Active::get_action_string()); + TextLog_Puts(csv_log, a.pkt->active->get_action_string()); } static void ff_class(Args& a) diff --git a/src/loggers/alert_fast.cc b/src/loggers/alert_fast.cc index 2f44b76b6..1990bd7b8 100644 --- a/src/loggers/alert_fast.cc +++ b/src/loggers/alert_fast.cc @@ -214,8 +214,8 @@ void FastLogger::alert(Packet* p, const char* msg, const Event& event) { LogTimeStamp(fast_log, p); - if ( Active::get_action() > Active::ACT_PASS ) - TextLog_Print(fast_log, " [%s]", Active::get_action_string()); + if ( p->active->packet_was_dropped() ) + TextLog_Print(fast_log, " [%s]", p->active->get_action_string()); TextLog_Puts(fast_log, " [**] "); diff --git a/src/loggers/alert_json.cc b/src/loggers/alert_json.cc index 20b15a50a..073cadb9a 100644 --- a/src/loggers/alert_json.cc +++ b/src/loggers/alert_json.cc @@ -82,7 +82,7 @@ static void print_label(Args& a, const char* label) static bool ff_action(Args& a) { print_label(a, "action"); - TextLog_Quote(json_log, Active::get_action_string()); + TextLog_Quote(json_log, a.pkt->active->get_action_string()); return true; } diff --git a/src/loggers/unified2.cc b/src/loggers/unified2.cc index d521490af..74b950afa 100644 --- a/src/loggers/unified2.cc +++ b/src/loggers/unified2.cc @@ -221,10 +221,10 @@ static void alert_event(Packet* p, const char*, Unified2Config* config, const Ev if ( app_name ) memcpy_s(u2_event.app_name, sizeof(u2_event.app_name), app_name, strlen(app_name) + 1); - } - u2_event.snort_status = Active::get_status(); - u2_event.snort_action = Active::get_action(); + u2_event.snort_status = p->active->get_status(); + u2_event.snort_action = p->active->get_action(); + } Serial_Unified2_Header hdr; uint32_t write_len = sizeof(hdr) + sizeof(u2_event); @@ -599,9 +599,9 @@ static int s_blocked_flag[] = U2_BLOCKED_FLAG_BLOCK, }; -static int GetU2Flags(const Packet*, uint8_t* pimpact) +static int GetU2Flags(const Packet* p, uint8_t* pimpact) { - Active::ActiveStatus dispos = Active::get_status(); + Active::ActiveStatus dispos = p->active->get_status(); if ( dispos > Active::AST_ALLOW ) *pimpact = U2_FLAG_BLOCKED; diff --git a/src/main/modules.cc b/src/main/modules.cc index 3cbb7bd12..253700510 100755 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -40,6 +40,7 @@ #include "managers/module_manager.h" #include "managers/plugin_manager.h" #include "memory/memory_module.h" +#include "packet_io/active.h" #include "packet_io/sfdaq_module.h" #include "packet_tracer/packet_tracer_module.h" #include "parser/config_file.h" @@ -869,12 +870,24 @@ static const Parameter active_params[] = #define active_help \ "configure responses" +static PegInfo active_pegs[] +{ + { CountType::SUM, "injects", "total crafted packets injected" }, + { CountType::END, nullptr, nullptr } +}; + class ActiveModule : public Module { public: ActiveModule() : Module("active", active_help, active_params) { } bool set(const char*, Value&, SnortConfig*) override; + const PegInfo* get_pegs() const override + { return active_pegs; } + + PegCount* get_counts() const override + { return (PegCount*) &active_counts; } + Usage get_usage() const override { return GLOBAL; } }; diff --git a/src/main/snort.cc b/src/main/snort.cc index b845e1129..31445bb4d 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -352,6 +352,8 @@ void Snort::init(int argc, char** argv) LogMessage("Snort BPF option: %s\n", SnortConfig::get_conf()->bpf_filter.c_str()); parser_term(SnortConfig::get_conf()); + + Active::init(sc); } // this function should only include initialization that must be done as a @@ -809,7 +811,7 @@ void Snort::thread_init_unprivileged() // this depends on instantiated daq capabilities // so it is done here instead of init() - Active::init(SnortConfig::get_conf()); + Active::thread_init(SnortConfig::get_conf()); InitTag(); EventTrace_Init(); @@ -870,7 +872,7 @@ void Snort::thread_term() PacketTracer::thread_term(); PacketManager::thread_term(); - Active::term(); + Active::thread_term(); delete s_switcher; delete[] s_data; } @@ -913,23 +915,24 @@ DAQ_Verdict Snort::process_packet( DetectionEngine::onload(p->flow); } + Active* act = p->active; // process flow verdicts here - if ( Active::packet_retry_requested() ) + if ( act->packet_retry_requested() ) { return DAQ_VERDICT_RETRY; } - else if ( Active::session_was_blocked() ) + else if ( act->session_was_blocked() ) { - if ( !Active::can_block() ) + if ( !act->can_block() ) return DAQ_VERDICT_PASS; - if ( Active::get_tunnel_bypass() ) + if ( act->get_tunnel_bypass() ) { aux_counts.internal_blacklist++; return DAQ_VERDICT_PASS; } - if ( SnortConfig::inline_mode() || Active::packet_force_dropped() ) + if ( SnortConfig::inline_mode() or act->packet_force_dropped() ) return DAQ_VERDICT_BLACKLIST; else return DAQ_VERDICT_IGNORE; @@ -941,7 +944,7 @@ DAQ_Verdict Snort::process_packet( // process (wire-only) packet verdicts here static DAQ_Verdict update_verdict(Packet* p, DAQ_Verdict verdict, int& inject) { - if ( Active::packet_was_dropped() and Active::can_block() ) + if ( p->active->packet_was_dropped() and p->active->can_block() ) { if ( verdict == DAQ_VERDICT_PASS ) verdict = DAQ_VERDICT_BLOCK; @@ -966,7 +969,7 @@ static DAQ_Verdict update_verdict(Packet* p, DAQ_Verdict verdict, int& inject) else if ( (p->packet_flags & PKT_IGNORE) || (p->flow && p->flow->get_ignore_direction( ) == SSN_DIR_BOTH) ) { - if ( !Active::get_tunnel_bypass() ) + if ( !p->active->get_tunnel_bypass() ) { verdict = DAQ_VERDICT_WHITELIST; } @@ -1028,7 +1031,6 @@ DAQ_Verdict Snort::packet_callback( HighAvailabilityManager::process_update(s_packet->flow, pkthdr); - Active::reset(); Stream::timeout_flows(pkthdr->ts.tv_sec); HighAvailabilityManager::process_receive(); diff --git a/src/mime/file_mime_process.cc b/src/mime/file_mime_process.cc index 6eec1b185..2157e2741 100644 --- a/src/mime/file_mime_process.cc +++ b/src/mime/file_mime_process.cc @@ -481,8 +481,9 @@ void MimeSession::reset_mime_state() } const uint8_t* MimeSession::process_mime_data_paf( - Flow* flow, const uint8_t* start, const uint8_t* end, bool upload, FilePosition position) + Packet* p, const uint8_t* start, const uint8_t* end, bool upload, FilePosition position) { + Flow* flow = p->flow; bool done_data = is_end_of_data(flow); /* if we've just entered the data state, check for a dot + end of line @@ -575,7 +576,7 @@ const uint8_t* MimeSession::process_mime_data_paf( /*Process file type/file signature*/ FileFlows* file_flows = FileFlows::get_file_flows(flow); - if (file_flows && file_flows->file_process(buffer, buf_size, position, upload) + if (file_flows && file_flows->file_process(p, buffer, buf_size, position, upload) && (isFileStart(position)) && log_state) { log_state->set_file_name_from_log(flow); @@ -617,9 +618,10 @@ const uint8_t* MimeSession::process_mime_data_paf( // Main function for mime processing // This should be called when mime data is available -const uint8_t* MimeSession::process_mime_data(Flow* flow, const uint8_t* start, +const uint8_t* MimeSession::process_mime_data(Packet* p, const uint8_t* start, int data_size, bool upload, FilePosition position) { + Flow* flow = p->flow; const uint8_t* attach_start = start; const uint8_t* attach_end; @@ -627,7 +629,7 @@ const uint8_t* MimeSession::process_mime_data(Flow* flow, const uint8_t* start, if (position != SNORT_FILE_POSITION_UNKNOWN) { - process_mime_data_paf(flow, attach_start, data_end_marker, + process_mime_data_paf(p, attach_start, data_end_marker, upload, position); return data_end_marker; } @@ -641,7 +643,7 @@ const uint8_t* MimeSession::process_mime_data(Flow* flow, const uint8_t* start, { attach_end = start; finalFilePosition(&position); - process_mime_data_paf(flow, attach_start, attach_end, + process_mime_data_paf(p, attach_start, attach_end, upload, position); data_state = STATE_MIME_HEADER; position = SNORT_FILE_START; @@ -654,7 +656,7 @@ const uint8_t* MimeSession::process_mime_data(Flow* flow, const uint8_t* start, if ((start == data_end_marker) && (attach_start < data_end_marker)) { updateFilePosition(&position, get_file_processed_size(flow)); - process_mime_data_paf(flow, attach_start, data_end_marker, + process_mime_data_paf(p, attach_start, data_end_marker, upload, position); } diff --git a/src/mime/file_mime_process.h b/src/mime/file_mime_process.h index 0a70cf09e..b2b5d694c 100644 --- a/src/mime/file_mime_process.h +++ b/src/mime/file_mime_process.h @@ -64,7 +64,7 @@ public: static void init(); static void exit(); - const uint8_t* process_mime_data(Flow*, const uint8_t *data, int data_size, + const uint8_t* process_mime_data(Packet*, const uint8_t *data, int data_size, bool upload, FilePosition); int get_data_state(); @@ -95,7 +95,7 @@ private: void setup_decode(const char* data, int size, bool cnt_xf); const uint8_t* process_mime_header(const uint8_t* ptr, const uint8_t* data_end_marker); const uint8_t* process_mime_body(const uint8_t* ptr, const uint8_t* data_end,bool is_data_end); - const uint8_t* process_mime_data_paf(Flow*, const uint8_t* start, const uint8_t* end, + const uint8_t* process_mime_data_paf(Packet*, const uint8_t* start, const uint8_t* end, bool upload, FilePosition); }; } diff --git a/src/network_inspectors/appid/test/log_message_mock.h b/src/network_inspectors/appid/test/log_message_mock.h index a1327b656..e869af5b5 100644 --- a/src/network_inspectors/appid/test/log_message_mock.h +++ b/src/network_inspectors/appid/test/log_message_mock.h @@ -1,4 +1,4 @@ -#ifndef LOG_MESSGE_MOCK +#ifndef LOG_MESSAGE_MOCK #define LOG_MESSAGE_MOCK #ifdef HAVE_CONFIG_H @@ -21,7 +21,7 @@ SO_PUBLIC void ErrorMessage(const char* format,...) va_end(ap); } -SO_PUBLIC [[noreturn]] void FatalError(const char* format,...) +[[noreturn]] SO_PUBLIC void FatalError(const char* format,...) { ErrorMessage(format); exit(1); diff --git a/src/network_inspectors/normalize/normalize.cc b/src/network_inspectors/normalize/normalize.cc index 76cdf62fd..b416bf1a2 100644 --- a/src/network_inspectors/normalize/normalize.cc +++ b/src/network_inspectors/normalize/normalize.cc @@ -244,7 +244,7 @@ void Normalizer::eval(snort::Packet* p) { Profile profile(norm_perf_stats); - if ( !p->is_rebuilt() && !Active::packet_was_dropped() ) + if ( !p->is_rebuilt() && !p->active->packet_was_dropped() ) Norm_Packet(&config, p); } diff --git a/src/network_inspectors/reputation/reputation_inspect.cc b/src/network_inspectors/reputation/reputation_inspect.cc index 6ecceddd3..2f33334df 100644 --- a/src/network_inspectors/reputation/reputation_inspect.cc +++ b/src/network_inspectors/reputation/reputation_inspect.cc @@ -265,6 +265,7 @@ static void snort_reputation(ReputationConfig* config, Packet* p) return; decision = reputation_decision(config, p); + Active* act = p->active; if (DECISION_NULL == decision) return; @@ -272,10 +273,10 @@ static void snort_reputation(ReputationConfig* config, Packet* p) else if (BLACKLISTED == decision) { DetectionEngine::queue_event(GID_REPUTATION, REPUTATION_EVENT_BLACKLIST); - Active::drop_packet(p, true); + act->drop_packet(p, true); // disable all preproc analysis and detection for this packet DetectionEngine::disable_all(p); - Active::block_session(p, true); + act->block_session(p, true); reputationstats.blacklisted++; if (PacketTracer::is_active()) { @@ -293,7 +294,7 @@ static void snort_reputation(ReputationConfig* config, Packet* p) DetectionEngine::queue_event(GID_REPUTATION, REPUTATION_EVENT_WHITELIST); p->packet_flags |= PKT_IGNORE; DetectionEngine::disable_all(p); - Active::allow_session(p); + act->allow_session(p); reputationstats.whitelisted++; } } diff --git a/src/packet_io/active.cc b/src/packet_io/active.cc index e40637d92..27e34874f 100644 --- a/src/packet_io/active.cc +++ b/src/packet_io/active.cc @@ -38,20 +38,18 @@ using namespace snort; #define MAX_ATTEMPTS 20 -// these can't be pkt flags because we do the handling -// of these flags following all processing and the drop -// or response may have been produced by a pseudopacket. -THREAD_LOCAL Active::ActiveStatus Active::active_status = Active::AST_ALLOW; -THREAD_LOCAL Active::ActiveAction Active::active_action = Active::ACT_PASS; -THREAD_LOCAL Active::ActiveAction Active::delayed_active_action = Active::ACT_PASS; - -THREAD_LOCAL int Active::active_tunnel_bypass = 0; -THREAD_LOCAL bool Active::active_suspend = false; +const char* Active::act_str[Active::ACT_MAX][Active::AST_MAX] = +{ + { "allow", "error", "error", "error" }, + { "drop", "cant_drop", "would_drop", "force_drop" }, + { "block", "cant_block", "would_block", "force_block" }, + { "reset", "cant_reset", "would_reset", "force_reset" }, +}; +bool Active::enabled = false; THREAD_LOCAL uint8_t Active::s_attempts = 0; -THREAD_LOCAL uint64_t Active::s_injects = 0; - -bool Active::s_enabled = false; +THREAD_LOCAL bool Active::s_suspend = false; +THREAD_LOCAL Active::Counts snort::active_counts; typedef int (* send_t) ( const DAQ_PktHdr_t* h, int rev, const uint8_t* buf, uint32_t len); @@ -60,9 +58,6 @@ static THREAD_LOCAL eth_t* s_link = nullptr; static THREAD_LOCAL ip_t* s_ipnet = nullptr; static THREAD_LOCAL send_t s_send = SFDAQ::inject; -Active::ActiveStatus Active::get_status() -{ return active_status; } - //-------------------------------------------------------------------- // helpers @@ -70,7 +65,7 @@ int Active::send_eth( const DAQ_PktHdr_t*, int, const uint8_t* buf, uint32_t len) { ssize_t sent = eth_send(s_link, buf, len); - s_injects++; + active_counts.injects++; return ( (uint32_t)sent != len ); } @@ -78,7 +73,7 @@ int Active::send_ip( const DAQ_PktHdr_t*, int, const uint8_t* buf, uint32_t len) { ssize_t sent = ip_send(s_ipnet, buf, len); - s_injects++; + active_counts.injects++; return ( (uint32_t)sent != len ); } @@ -142,33 +137,39 @@ void Active::kill_session(Packet* p, EncodeFlags flags) return; case PktType::TCP: - Active::send_reset(p, 0); + send_reset(p, 0); if ( flags & ENC_FLAG_FWD ) - Active::send_reset(p, ENC_FLAG_FWD); + send_reset(p, ENC_FLAG_FWD); break; default: - if ( Active::packet_force_dropped() ) - Active::send_unreach(p, snort::UnreachResponse::FWD); + if ( packet_force_dropped() ) + send_unreach(p, snort::UnreachResponse::FWD); else - Active::send_unreach(p, snort::UnreachResponse::PORT); + send_unreach(p, snort::UnreachResponse::PORT); break; } } //-------------------------------------------------------------------- -bool Active::init(SnortConfig* sc) +void Active::init(SnortConfig* sc) +{ + if (sc->max_responses > 0) + Active::set_enabled(); +} + +bool Active::thread_init(SnortConfig* sc) { s_attempts = sc->respond_attempts; if ( s_attempts > MAX_ATTEMPTS ) s_attempts = MAX_ATTEMPTS; - if ( s_enabled && !s_attempts ) + if ( enabled && !s_attempts ) s_attempts = 1; - if ( s_enabled && (!SFDAQ::can_inject() || !sc->respond_device.empty()) ) + if ( enabled && (!SFDAQ::can_inject() || !sc->respond_device.empty()) ) { if ( SnortConfig::read_mode() || !open(sc->respond_device.c_str()) ) { @@ -180,25 +181,14 @@ bool Active::init(SnortConfig* sc) } } - if (sc->max_responses > 0) - Active::set_enabled(); - return true; } -void Active::term() +void Active::thread_term() { Active::close(); } -bool Active::is_enabled() -{ return s_enabled and s_attempts; } - -void Active::set_enabled(bool on_off) -{ - s_enabled = on_off; -} - //-------------------------------------------------------------------- void Active::send_reset(Packet* p, EncodeFlags ef) @@ -254,7 +244,10 @@ bool Active::send_data( seg = PacketManager::encode_response(TcpResponse::RST, tmp_flags, p, plen); if ( seg ) + { s_send(p->pkth, !(tmp_flags & ENC_FLAG_FWD), seg, plen); + active_counts.injects++; + } } flags |= ENC_FLAG_SEQ; @@ -275,6 +268,7 @@ bool Active::send_data( return false; s_send(p->pkth, !(flags & ENC_FLAG_FWD), seg, plen); + active_counts.injects++; buf += toSend; sent += toSend; @@ -290,6 +284,7 @@ bool Active::send_data( return false; s_send(p->pkth, !(flags & ENC_FLAG_FWD), seg, plen); + active_counts.injects++; if (flags & ENC_FLAG_RST_CLNT) { @@ -299,7 +294,10 @@ bool Active::send_data( seg = PacketManager::encode_response(TcpResponse::RST, flags, p, plen); if ( seg ) + { s_send(p->pkth, !(flags & ENC_FLAG_FWD), seg, plen); + active_counts.injects++; + } } return true; @@ -370,7 +368,7 @@ void Active::cant_drop() void Active::update_status(const Packet* p, bool force) { - if ( suspended() ) + if ( s_suspend ) cant_drop(); else if ( force ) @@ -392,7 +390,7 @@ void Active::update_status(const Packet* p, bool force) void Active::daq_update_status(const Packet* p) { - if ( suspended() ) + if ( s_suspend ) { cant_drop(); } @@ -419,12 +417,14 @@ void Active::daq_drop_packet(const Packet* p) daq_update_status(p); } -bool Active::daq_retry_packet(const Packet *p) +bool Active::daq_retry_packet(const Packet* p) { bool retry_queued = false; // FIXIT-M may need to confirm this packet is not a retransmit...2.9.x has a check for that - if ( !p->is_rebuilt() && ( active_action == ACT_PASS ) && SFDAQ::can_retry() ) + if ( !p->is_rebuilt() and + ( active_action == ACT_PASS ) and + SFDAQ::can_retry() ) { if ( SFDAQ::forwarding_packet(p->pkth) ) { @@ -451,8 +451,8 @@ void Active::allow_session(Packet* p) void Active::block_session(Packet* p, bool force) { - update_status(p, force); active_action = ACT_BLOCK; + update_status(p, force); if ( force or SnortConfig::inline_mode() or SnortConfig::treat_drop_as_ignore() ) Stream::block_flow(p); @@ -468,7 +468,7 @@ void Active::reset_session(Packet* p, bool force) if ( force or SnortConfig::inline_mode() or SnortConfig::treat_drop_as_ignore() ) Stream::drop_flow(p); - if ( s_enabled ) + if ( enabled ) { ActionManager::queue_reject(); @@ -486,7 +486,7 @@ void Active::set_delayed_action(ActiveAction action, bool force) { delayed_active_action = action; - if (force) + if ( force ) active_status = AST_FORCE; } @@ -494,7 +494,7 @@ void Active::apply_delayed_action(Packet* p) { bool force = (active_status == AST_FORCE); - switch (delayed_active_action) + switch ( delayed_active_action ) { case ACT_PASS: break; @@ -551,63 +551,10 @@ void Active::close() s_ipnet = nullptr; } -static const char* act_str[Active::ACT_MAX][Active::AST_MAX] = +void Active::reset() { - { "allow", "error", "error", "error" }, - { "drop", "cant_drop", "would_drop", "force_drop" }, - { "block", "cant_block", "would_block", "force_block" }, - { "reset", "cant_reset", "would_reset", "force_reset" }, -}; - -const char* Active::get_action_string() -{ - return act_str[active_action][active_status]; + active_tunnel_bypass = 0; + active_status = AST_ALLOW; + active_action = ACT_PASS; + delayed_active_action = ACT_PASS; } - -void Active::suspend() -{ active_suspend = true; } - -void Active::resume() -{ active_suspend = false; } - -bool Active::suspended() -{ return active_suspend; } - -Active::ActiveAction Active::get_action() -{ return active_action; } - -bool Active::can_block() -{ return active_status == AST_ALLOW or active_status == AST_FORCE; } - -void Active::block_again() -{ active_action = ACT_BLOCK; } - -void Active::reset_again() -{ active_action = ACT_RESET; } - -bool Active::packet_was_dropped() -{ return ( active_action >= ACT_DROP ); } - -bool Active::packet_retry_requested() -{ return ( active_action == ACT_RETRY ); } - -bool Active::session_was_blocked() -{ return ( active_action >= ACT_BLOCK); } - -bool Active::packet_would_be_dropped() -{ return (active_status == AST_WOULD ); } - -bool Active::packet_force_dropped() -{ return (active_status == AST_FORCE ); } - -void Active::set_tunnel_bypass() -{ active_tunnel_bypass++; } - -void Active::clear_tunnel_bypass() -{ active_tunnel_bypass--; } - -bool Active::get_tunnel_bypass() -{ return ( active_tunnel_bypass > 0 ); } - -uint64_t Active::get_injects() -{ return s_injects; } diff --git a/src/packet_io/active.h b/src/packet_io/active.h index 4ebd4be81..f39214802 100644 --- a/src/packet_io/active.h +++ b/src/packet_io/active.h @@ -35,111 +35,137 @@ struct SnortConfig; class SO_PUBLIC Active { public: - enum ActiveStatus + + struct Counts + { + PegCount injects; + }; + + enum ActiveStatus : uint8_t { AST_ALLOW, AST_CANT, AST_WOULD, AST_FORCE, AST_MAX }; - enum ActiveAction + enum ActiveAction : uint8_t { ACT_PASS, ACT_DROP, ACT_BLOCK, ACT_RESET, ACT_RETRY, ACT_MAX }; public: - static bool init(SnortConfig*); - static void term(); + static void init(SnortConfig*); + static bool thread_init(SnortConfig*); + static void thread_term(); - static void reset() - { - active_status = AST_ALLOW; - active_action = ACT_PASS; - active_tunnel_bypass = 0; - delayed_active_action = ACT_PASS; - } + static void set_enabled(bool on_off = true) + { enabled = on_off; } - static void kill_session(Packet*, EncodeFlags = ENC_FLAG_FWD); + static void suspend() + { s_suspend = true; } - static void send_reset(Packet*, EncodeFlags); - static void send_unreach(Packet*, snort::UnreachResponse); - static bool send_data(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len); - static void inject_data(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len); + static void resume() + { s_suspend = false; } - static bool is_reset_candidate(const Packet*); - static bool is_unreachable_candidate(const Packet*); + void send_reset(Packet*, EncodeFlags); + void send_unreach(Packet*, snort::UnreachResponse); + bool send_data(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len); + void inject_data(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len); - static bool is_enabled(); - static void set_enabled(bool = true); + bool is_reset_candidate(const Packet*); + bool is_unreachable_candidate(const Packet*); - static void suspend(); - static void resume(); - static bool suspended(); + ActiveAction get_action() + { return active_action; } - static ActiveAction get_action(); - static ActiveStatus get_status(); + ActiveStatus get_status() + { return active_status; } - static bool can_block(); + void kill_session(Packet*, EncodeFlags = ENC_FLAG_FWD); - static const char* get_action_string(); + bool can_block() + { return active_status == AST_ALLOW or active_status == AST_FORCE; } - static void drop_packet(const Packet*, bool force = false); - static void daq_drop_packet(const Packet*); - static bool daq_retry_packet(const Packet*); + const char* get_action_string() + { return act_str[active_action][active_status]; } - static void allow_session(Packet*); + void drop_packet(const Packet*, bool force = false); + void daq_drop_packet(const Packet*); + bool daq_retry_packet(const Packet*); - static void block_session(Packet*, bool force = false); - static void reset_session(Packet*, bool force = false); + void allow_session(Packet*); + void block_session(Packet*, bool force = false); + void reset_session(Packet*, bool force = false); - static void block_again(); - static void reset_again(); + void block_again() + { active_action = ACT_BLOCK; } - static bool packet_was_dropped(); - static bool packet_retry_requested(); - static bool session_was_blocked(); - static bool packet_would_be_dropped(); - static bool packet_force_dropped(); + void reset_again() + { active_action = ACT_RESET; } - static void set_tunnel_bypass(); - static void clear_tunnel_bypass(); - static bool get_tunnel_bypass(); + bool packet_was_dropped() + { return active_action >= ACT_DROP; } - static uint64_t get_injects(); + bool packet_would_be_dropped() + { return active_status == AST_WOULD; } - static void set_delayed_action(ActiveAction, bool force = false); - static void apply_delayed_action(Packet*); + bool packet_retry_requested() + { return active_action == ACT_RETRY; } -private: - static bool open(const char*); - static void close(); + bool session_was_blocked() + { return active_action >= ACT_BLOCK; } - static int send_eth( - const DAQ_PktHdr_t*, int, const uint8_t* buf, uint32_t len); + bool packet_force_dropped() + { return active_status == AST_FORCE; } - static int send_ip( - const DAQ_PktHdr_t*, int, const uint8_t* buf, uint32_t len); + void set_tunnel_bypass() + { active_tunnel_bypass++; } - static void update_status(const Packet*, bool force = false); - static void daq_update_status(const Packet*); + void clear_tunnel_bypass() + { active_tunnel_bypass--; } - static void block_session(const Packet*, ActiveAction, bool force = false); + bool get_tunnel_bypass() + { return active_tunnel_bypass > 0; } - static void cant_drop(); + void set_delayed_action(ActiveAction, bool force = false); + void apply_delayed_action(Packet*); + + void reset(); private: - static THREAD_LOCAL ActiveStatus active_status; - static THREAD_LOCAL ActiveAction active_action; - static THREAD_LOCAL ActiveAction delayed_active_action; + static bool open(const char*); + static void close(); + static int send_eth(const DAQ_PktHdr_t*, int, const uint8_t* buf, uint32_t len); + static int send_ip(const DAQ_PktHdr_t*, int, const uint8_t* buf, uint32_t len); + + void update_status(const Packet*, bool force = false); + void daq_update_status(const Packet*); + + void block_session(const Packet*, ActiveAction, bool force = false); + + void cant_drop(); - static THREAD_LOCAL int active_tunnel_bypass; - static THREAD_LOCAL bool active_suspend; +private: + static const char* act_str[ACT_MAX][AST_MAX]; + static bool enabled; static THREAD_LOCAL uint8_t s_attempts; - static THREAD_LOCAL uint64_t s_injects; + static THREAD_LOCAL bool s_suspend; + + int active_tunnel_bypass; - static bool s_enabled; + // these can't be pkt flags because we do the handling + // of these flags following all processing and the drop + // or response may have been produced by a pseudopacket. + ActiveStatus active_status; + ActiveAction active_action; + ActiveAction delayed_active_action; }; struct ActiveSuspendContext { - ActiveSuspendContext() { Active::suspend(); } - ~ActiveSuspendContext() { Active::resume(); } + ActiveSuspendContext() + { Active::suspend(); } + + ~ActiveSuspendContext() + { Active::resume(); } }; + +extern THREAD_LOCAL Active::Counts active_counts; } #endif diff --git a/src/protocols/packet.cc b/src/protocols/packet.cc index d14da71ed..164c0c7b2 100644 --- a/src/protocols/packet.cc +++ b/src/protocols/packet.cc @@ -27,6 +27,7 @@ #include "flow/expect_cache.h" #include "framework/endianness.h" #include "log/obfuscator.h" +#include "packet_io/active.h" #include "managers/codec_manager.h" #include "packet_manager.h" @@ -51,7 +52,7 @@ Packet::Packet(bool packet_data) obfuscator = nullptr; endianness = nullptr; - + active_inst = new Active; reset(); } @@ -64,7 +65,7 @@ Packet::~Packet() delete pkth; delete[] pkt; } - + delete active_inst; delete[] layers; } diff --git a/src/protocols/packet.h b/src/protocols/packet.h index b28fd053e..5ef29dc3b 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -30,6 +30,7 @@ namespace snort { +class Active; class Endianness; class Flow; class IpsContext; @@ -129,6 +130,8 @@ struct SO_PUBLIC Packet // Everything beyond this point is set by PacketManager::decode() IpsContext* context; // set by control + Active* active; + Active* active_inst; const DAQ_PktHdr_t* pkth; // packet meta data const uint8_t* pkt; // raw packet data diff --git a/src/protocols/packet_manager.cc b/src/protocols/packet_manager.cc index 79282c9f1..fcfd90255 100644 --- a/src/protocols/packet_manager.cc +++ b/src/protocols/packet_manager.cc @@ -100,7 +100,7 @@ void PacketManager::pop_teredo(Packet* p, RawData& raw) { p->proto_bits &= ~PROTO_BIT__TEREDO; if ( SnortConfig::tunnel_bypass_enabled(TUNNEL_TEREDO) ) - Active::clear_tunnel_bypass(); + p->active->clear_tunnel_bypass(); const ProtocolIndex mapped_prot = CodecManager::s_proto_map[to_utype(ProtocolId::TEREDO)]; s_stats[mapped_prot + stat_offset]--; @@ -165,6 +165,12 @@ void PacketManager::decode( CodecManager::s_protocols[mapped_prot]->get_name(), static_cast(codec_data.next_prot_id), pkt, codec_data.lyr_len); + if ( codec_data.tunnel_bypass ) + { + p->active->set_tunnel_bypass(); + codec_data.tunnel_bypass = false; + } + if ( codec_data.codec_flags & CODEC_ETHER_NEXT ) { if ( codec_data.next_prot_id < ProtocolId::ETHERTYPE_MINIMUM ) diff --git a/src/service_inspectors/dce_rpc/dce_smb2.cc b/src/service_inspectors/dce_rpc/dce_smb2.cc index c36988d35..abb1f4fa9 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2.cc +++ b/src/service_inspectors/dce_rpc/dce_smb2.cc @@ -235,11 +235,12 @@ static inline void DCE2_Smb2ProcessFileData(DCE2_SmbSsnData* ssd, const uint8_t* DCE2_FileDetect(); } - FileFlows* file_flows = FileFlows::get_file_flows(DetectionEngine::get_current_packet()->flow); + Packet* p = DetectionEngine::get_current_packet(); + FileFlows* file_flows = FileFlows::get_file_flows(p->flow); if ( !file_flows ) return; - file_flows->file_process(ssd->ftracker.fid_v2, file_data, data_size, + file_flows->file_process(p, ssd->ftracker.fid_v2, file_data, data_size, ssd->ftracker.tracker.file.file_offset, dir); } diff --git a/src/service_inspectors/dce_rpc/dce_smb_utils.cc b/src/service_inspectors/dce_rpc/dce_smb_utils.cc index f2a8c527c..7374fc3ad 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_utils.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_utils.cc @@ -1460,7 +1460,7 @@ static void DCE2_SmbInjectDeletePdu(DCE2_SmbFileTracker* ftracker) del_req->smb_bcc = 1 + file_name_len; memcpy(del_filename, ftracker->file_name + UTF_16_LE_BOM_LEN, file_name_len); - Active::inject_data(inject_pkt, 0, (uint8_t*)nb_hdr, len); + p->active->inject_data(inject_pkt, 0, (uint8_t*)nb_hdr, len); } static FileVerdict DCE2_SmbLookupFileVerdict() @@ -1475,7 +1475,7 @@ static FileVerdict DCE2_SmbLookupFileVerdict() FileVerdict verdict = file->verdict; if (verdict == FILE_VERDICT_PENDING) - verdict = file->file_signature_lookup(DetectionEngine::get_current_packet()->flow); + verdict = file->file_signature_lookup(DetectionEngine::get_current_packet()); return verdict; } @@ -1514,7 +1514,7 @@ static void DCE2_SmbFinishFileAPI(DCE2_SmbSsnData* ssd) && (ftracker->ff_bytes_processed != 0)) { Profile profile(dce2_smb_pstat_smb_file_api); - if (file_flows->file_process(nullptr, 0, SNORT_FILE_END, upload)) + if (file_flows->file_process(p, nullptr, 0, SNORT_FILE_END, upload)) { if (upload) { @@ -1576,8 +1576,10 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd, } Profile profile(dce2_smb_pstat_smb_file_api); - FileFlows* file_flows = FileFlows::get_file_flows(DetectionEngine::get_current_packet()->flow); - if (!file_flows->file_process(data_ptr, (int)data_len, position, upload, + Packet* p = DetectionEngine::get_current_packet(); + DetectionEngine::get_current_packet(); + FileFlows* file_flows = FileFlows::get_file_flows(p->flow); + if (!file_flows->file_process(p, data_ptr, (int)data_len, position, upload, DCE2_SmbIsVerdictSuspend(upload, position))) { trace_logf(dce_smb, "File API returned FAILURE " diff --git a/src/service_inspectors/dce_rpc/smb_message.cc b/src/service_inspectors/dce_rpc/smb_message.cc index 98ac4f6ef..08a28432f 100644 --- a/src/service_inspectors/dce_rpc/smb_message.cc +++ b/src/service_inspectors/dce_rpc/smb_message.cc @@ -769,7 +769,8 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr { if (ssd->block_pdus && (DCE2_SmbType() == SMB_TYPE__REQUEST)) { - Active::drop_packet(DetectionEngine::get_current_packet()); + Packet* p = DetectionEngine::get_current_packet(); + p->active->drop_packet(p); status = DCE2_RET__IGNORE; break; } diff --git a/src/service_inspectors/ftp_telnet/ftp_data.cc b/src/service_inspectors/ftp_telnet/ftp_data.cc index b8aeeb744..b94d12a0d 100644 --- a/src/service_inspectors/ftp_telnet/ftp_data.cc +++ b/src/service_inspectors/ftp_telnet/ftp_data.cc @@ -59,7 +59,7 @@ static void FTPDataProcess( if (data_ssn->packet_flags & FTPDATA_FLG_REST) { - Active::block_again(); + p->active->block_again(); return; } @@ -75,10 +75,10 @@ static void FTPDataProcess( else file_flows->set_sig_gen_state( false ); - status = file_flows->file_process(file_data, data_length, + status = file_flows->file_process(p, file_data, data_length, data_ssn->position, data_ssn->direction); - if (Active::packet_force_dropped()) + if ( p->active->packet_force_dropped() ) { FtpFlowData* fd = (FtpFlowData*)Stream::get_flow_data( &data_ssn->ftp_key, FtpFlowData::inspector_id); diff --git a/src/service_inspectors/ftp_telnet/ftpdata_splitter.cc b/src/service_inspectors/ftp_telnet/ftpdata_splitter.cc index 71c66f3b5..4f23f9f46 100644 --- a/src/service_inspectors/ftp_telnet/ftpdata_splitter.cc +++ b/src/service_inspectors/ftp_telnet/ftpdata_splitter.cc @@ -23,6 +23,7 @@ #include "ftpdata_splitter.h" +#include "detection/detection_engine.h" #include "file_api/file_flows.h" #include "flow/session.h" #include "stream/stream.h" @@ -109,7 +110,10 @@ bool FtpDataSplitter::finish(Flow* flow) FileFlows* file_flows = FileFlows::get_file_flows(flow); if ( file_flows ) - file_flows->file_process(nullptr, 0, SNORT_FILE_END, to_server(), 0); + { + file_flows->file_process(DetectionEngine::get_current_packet(), + nullptr, 0, SNORT_FILE_END, to_server(), 0); + } } } diff --git a/src/service_inspectors/http_inspect/http_msg_body.cc b/src/service_inspectors/http_inspect/http_msg_body.cc index 8bc383e64..146d51071 100644 --- a/src/service_inspectors/http_inspect/http_msg_body.cc +++ b/src/service_inspectors/http_inspect/http_msg_body.cc @@ -201,6 +201,7 @@ void HttpMsgBody::do_js_normalization(const Field& input, Field& output) void HttpMsgBody::do_file_processing(Field& file_data) { // Using the trick that cutter is deleted when regular or chunked body is complete + Packet* p = DetectionEngine::get_current_packet(); const bool front = (body_octets == 0); const bool back = (session_data->cutter[source_id] == nullptr) || tcp_close; @@ -231,7 +232,7 @@ void HttpMsgBody::do_file_processing(Field& file_data) file_index = request->get_http_uri()->get_file_proc_hash(); } - if (file_flows->file_process(file_data.start(), fp_length, + if (file_flows->file_process(p, file_data.start(), fp_length, file_position, !download, file_index)) { session_data->file_depth_remaining[source_id] -= fp_length; @@ -258,7 +259,7 @@ void HttpMsgBody::do_file_processing(Field& file_data) } else { - session_data->mime_state[source_id]->process_mime_data(flow, file_data.start(), + session_data->mime_state[source_id]->process_mime_data(p, file_data.start(), fp_length, true, SNORT_FILE_POSITION_UNKNOWN); session_data->file_depth_remaining[source_id] -= fp_length; diff --git a/src/service_inspectors/http_inspect/http_msg_header.cc b/src/service_inspectors/http_inspect/http_msg_header.cc index e2ee8aa53..f9bfa345c 100644 --- a/src/service_inspectors/http_inspect/http_msg_header.cc +++ b/src/service_inspectors/http_inspect/http_msg_header.cc @@ -339,10 +339,11 @@ void HttpMsgHeader::setup_file_processing() // FIXIT-L develop a proper interface for passing the boundary string. // This interface is a leftover from when OHI pushed whole messages through // this interface. - session_data->mime_state[source_id]->process_mime_data(flow, + Packet* p = DetectionEngine::get_current_packet(); + session_data->mime_state[source_id]->process_mime_data(p, content_type.start(), content_type.length(), true, SNORT_FILE_POSITION_UNKNOWN); - session_data->mime_state[source_id]->process_mime_data(flow, + session_data->mime_state[source_id]->process_mime_data(p, (const uint8_t*)"\r\n", 2, true, SNORT_FILE_POSITION_UNKNOWN); } } diff --git a/src/service_inspectors/http_inspect/http_stream_splitter_finish.cc b/src/service_inspectors/http_inspect/http_stream_splitter_finish.cc index 4c8f82abf..d3b845bbe 100644 --- a/src/service_inspectors/http_inspect/http_stream_splitter_finish.cc +++ b/src/service_inspectors/http_inspect/http_stream_splitter_finish.cc @@ -33,6 +33,7 @@ using namespace HttpEnums; bool HttpStreamSplitter::finish(snort::Flow* flow) { snort::Profile profile(HttpModule::get_profile_stats()); + snort::Packet* p = snort::DetectionEngine::get_current_packet(); HttpFlowData* session_data = (HttpFlowData*)flow->get_flow_data(HttpFlowData::inspector_id); // FIXIT-M - this assert has been changed to check for null session data and return false if so @@ -136,11 +137,11 @@ bool HttpStreamSplitter::finish(snort::Flow* flow) } } - file_flows->file_process(nullptr, 0, SNORT_FILE_END, !download, file_index); + file_flows->file_process(p, nullptr, 0, SNORT_FILE_END, !download, file_index); } else { - session_data->mime_state[source_id]->process_mime_data(flow, nullptr, 0, true, + session_data->mime_state[source_id]->process_mime_data(p, nullptr, 0, true, SNORT_FILE_POSITION_UNKNOWN); delete session_data->mime_state[source_id]; session_data->mime_state[source_id] = nullptr; diff --git a/src/service_inspectors/imap/imap.cc b/src/service_inspectors/imap/imap.cc index 412a5c068..a99903f0e 100644 --- a/src/service_inspectors/imap/imap.cc +++ b/src/service_inspectors/imap/imap.cc @@ -460,7 +460,7 @@ static void IMAP_ProcessServerPacket(Packet* p, IMAPData* imap_ssn) FilePosition position = get_file_position(p); int data_len = end - ptr; - ptr = imap_ssn->mime_ssn->process_mime_data(p->flow, ptr, data_len, false, + ptr = imap_ssn->mime_ssn->process_mime_data(p, ptr, data_len, false, position); if ( ptr < data_end) len = len - (data_end - ptr); diff --git a/src/service_inspectors/pop/pop.cc b/src/service_inspectors/pop/pop.cc index d76b6cffb..869aaccc0 100644 --- a/src/service_inspectors/pop/pop.cc +++ b/src/service_inspectors/pop/pop.cc @@ -432,7 +432,7 @@ static void POP_ProcessServerPacket(Packet* p, POPData* pop_ssn) //ptr = POP_HandleData(p, ptr, end); FilePosition position = get_file_position(p); int len = end - ptr; - ptr = pop_ssn->mime_ssn->process_mime_data(p->flow, ptr, len, false, position); + ptr = pop_ssn->mime_ssn->process_mime_data(p, ptr, len, false, position); continue; } POP_GetEOL(ptr, end, &eol, &eolm); diff --git a/src/service_inspectors/smtp/smtp.cc b/src/service_inspectors/smtp/smtp.cc index c7bd45386..399f54fe0 100644 --- a/src/service_inspectors/smtp/smtp.cc +++ b/src/service_inspectors/smtp/smtp.cc @@ -1003,7 +1003,7 @@ static void SMTP_ProcessClientPacket(SMTP_PROTO_CONF* config, Packet* p, SMTPDat case STATE_DATA: case STATE_BDATA: position = get_file_position(p); - ptr = smtp_ssn->mime_ssn->process_mime_data(p->flow, ptr, len, true, position); + ptr = smtp_ssn->mime_ssn->process_mime_data(p, ptr, len, true, position); //ptr = SMTP_HandleData(p, ptr, end, &(smtp_ssn->mime_ssn)); break; case STATE_XEXCH50: diff --git a/src/service_inspectors/smtp/smtp_xlink2state.cc b/src/service_inspectors/smtp/smtp_xlink2state.cc index 77e2e856e..66780fd74 100644 --- a/src/service_inspectors/smtp/smtp_xlink2state.cc +++ b/src/service_inspectors/smtp/smtp_xlink2state.cc @@ -243,7 +243,7 @@ int ParseXLink2State(SMTP_PROTO_CONF* config, snort::Packet* p, SMTPData* smtp_s /* Need to drop the packet if we're told to * (outside of whether its thresholded). */ if (config->xlink2state == DROP_XLINK2STATE) - snort::Active::reset_session(p); + p->active->reset_session(p); snort::DetectionEngine::queue_event(GID_SMTP, SMTP_XLINK2STATE_OVERFLOW); smtp_ssn->session_flags |= SMTP_FLAG_XLINK2STATE_ALERTED; diff --git a/src/stream/file/file_session.cc b/src/stream/file/file_session.cc index 039c3d724..4ce6b1686 100644 --- a/src/stream/file/file_session.cc +++ b/src/stream/file/file_session.cc @@ -79,7 +79,7 @@ int FileSession::process(Packet* p) FileFlows* file_flows = FileFlows::get_file_flows(p->flow); if (file_flows && - file_flows->file_process(p->data, p->dsize, position(p), c->upload)) + file_flows->file_process(p, p->data, p->dsize, position(p), c->upload)) { const char* file_name = SFDAQ::get_interface_spec(); if (file_name) diff --git a/src/stream/ip/ip_defrag.cc b/src/stream/ip/ip_defrag.cc index 4fc48cb58..422436858 100644 --- a/src/stream/ip/ip_defrag.cc +++ b/src/stream/ip/ip_defrag.cc @@ -974,7 +974,7 @@ void Defrag::process(Packet* p, FragTracker* ft) if ( ft->frag_flags & FRAG_DROP_FRAGMENTS ) { DetectionEngine::disable_content(p); - Active::daq_drop_packet(p); + p->active->daq_drop_packet(p); ip_stats.drops++; } @@ -1050,7 +1050,7 @@ void Defrag::process(Packet* p, FragTracker* ft) if (!(ft->frag_flags & FRAG_BAD)) FragRebuild(ft, p); - if (Active::packet_was_dropped()) + if ( p->active->packet_was_dropped() ) { ft->frag_flags |= FRAG_DROP_FRAGMENTS; delete_tracker(ft); diff --git a/src/stream/ip/ip_session.cc b/src/stream/ip/ip_session.cc index 9a80d5ab7..50cc505b9 100644 --- a/src/stream/ip/ip_session.cc +++ b/src/stream/ip/ip_session.cc @@ -168,7 +168,7 @@ int IpSession::process(Packet* p) IpHAManager::process_deletion(flow); } - if ( Stream::blocked_flow(flow, p) || Stream::ignored_flow(flow, p) ) + if ( Stream::blocked_flow(p) || Stream::ignored_flow(flow, p) ) return 0; if ( p->ptrs.decode_flags & DECODE_FRAG ) diff --git a/src/stream/stream.cc b/src/stream/stream.cc index 63c9862c3..efdda8c41 100644 --- a/src/stream/stream.cc +++ b/src/stream/stream.cc @@ -177,7 +177,7 @@ void Stream::check_flow_closed(Packet* p) flow->set_state(Flow::FlowState::BLOCK); if ( !(p->packet_flags & PKT_STATELESS) ) - drop_traffic(flow, SSN_DIR_BOTH); + drop_traffic(p, SSN_DIR_BOTH); flow->session_state &= ~STREAM_STATE_BLOCK_PENDING; } } @@ -288,22 +288,24 @@ uint32_t Stream::get_packet_direction(Packet* p) return (p->packet_flags & (PKT_FROM_SERVER|PKT_FROM_CLIENT)); } -void Stream::drop_traffic(Flow* flow, char dir) +void Stream::drop_traffic(const Packet* p, char dir) { - if (!flow) + Flow* flow = p->flow; + + if ( !flow ) return; if ((dir & SSN_DIR_FROM_CLIENT) && !(flow->ssn_state.session_flags & SSNFLAG_DROP_CLIENT)) { flow->ssn_state.session_flags |= SSNFLAG_DROP_CLIENT; - if ( Active::packet_force_dropped() ) + if ( p->active->packet_force_dropped() ) flow->ssn_state.session_flags |= SSNFLAG_FORCE_BLOCK; } if ((dir & SSN_DIR_FROM_SERVER) && !(flow->ssn_state.session_flags & SSNFLAG_DROP_SERVER)) { flow->ssn_state.session_flags |= SSNFLAG_DROP_SERVER; - if ( Active::packet_force_dropped() ) + if ( p->active->packet_force_dropped() ) flow->ssn_state.session_flags |= SSNFLAG_FORCE_BLOCK; } } @@ -332,7 +334,7 @@ void Stream::drop_flow(const Packet* p) flow->set_state(Flow::FlowState::BLOCK); if ( !(p->packet_flags & PKT_STATELESS) ) - drop_traffic(flow, SSN_DIR_BOTH); + drop_traffic(p, SSN_DIR_BOTH); } //------------------------------------------------------------------------- @@ -600,7 +602,7 @@ static void active_response(Packet* p, Flow* lwssn) (lwssn->session_state & STREAM_STATE_DROP_SERVER) ) ? ENC_FLAG_FWD : 0; // reverse dir is always true - Active::kill_session(p, flags); + p->active->kill_session(p, flags); ++lwssn->response_count; lwssn->set_expire(p, delay); @@ -608,8 +610,10 @@ static void active_response(Packet* p, Flow* lwssn) } } -bool Stream::blocked_flow(Flow* flow, Packet* p) +bool Stream::blocked_flow(Packet* p) { + Flow* flow = p->flow; + if ( !(flow->ssn_state.session_flags & (SSNFLAG_DROP_CLIENT|SSNFLAG_DROP_SERVER)) ) return false; @@ -621,7 +625,7 @@ bool Stream::blocked_flow(Flow* flow, Packet* p) (flow->ssn_state.session_flags & SSNFLAG_DROP_CLIENT)) ) { DetectionEngine::disable_content(p); - Active::drop_packet(p); + p->active->drop_packet(p); active_response(p, flow); return true; } diff --git a/src/stream/stream.h b/src/stream/stream.h index b408d008f..f1316eb05 100644 --- a/src/stream/stream.h +++ b/src/stream/stream.h @@ -119,7 +119,7 @@ public: // 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); + static void drop_traffic(const Packet*, char dir); // Mark a flow as dropped, release allocated resources, and set flow state such that any // subsequent packets received on this flow are dropped. @@ -218,7 +218,7 @@ public: static bool expired_flow(Flow*, Packet*); static bool ignored_flow(Flow*, Packet*); - static bool blocked_flow(Flow*, Packet*); + static bool blocked_flow(Packet*); // extra data methods static void set_extra_data(Flow*, Packet*, uint32_t); diff --git a/src/stream/tcp/tcp_normalizer.cc b/src/stream/tcp/tcp_normalizer.cc index d4744b8ba..de4311fde 100644 --- a/src/stream/tcp/tcp_normalizer.cc +++ b/src/stream/tcp/tcp_normalizer.cc @@ -99,7 +99,8 @@ bool TcpNormalizer::packet_dropper( if (mode == NORM_MODE_ON) { - Active::drop_packet(tsd.get_pkt()); + Packet* p = tsd.get_pkt(); + p->active->drop_packet(p); return true; } diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index 7f8f72440..2a85e4a57 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -911,7 +911,7 @@ bool TcpSession::is_flow_handling_packets(Packet* p) flow_ready = false; } else - flow_ready = !Stream::blocked_flow(flow, p); + flow_ready = !Stream::blocked_flow(p); // FIXIT-L expected flow should be checked by Stream before we get here // harmonize this with that and the checks above diff --git a/src/stream/tcp/test/tcp_normalizer_test.cc b/src/stream/tcp/test/tcp_normalizer_test.cc index 9fc4aba9a..0ecf0de53 100644 --- a/src/stream/tcp/test/tcp_normalizer_test.cc +++ b/src/stream/tcp/test/tcp_normalizer_test.cc @@ -84,12 +84,9 @@ public: class Active { public: - static void drop_packet(const Packet*, bool force = false); - + void drop_packet(const Packet*, bool force = false) { } }; -void Active::drop_packet(const Packet* , bool ) { } - bool Normalize_IsEnabled(NormFlags ) { return norm_enabled; diff --git a/src/stream/udp/udp_session.cc b/src/stream/udp/udp_session.cc index e9dc9337c..a5dd70b5f 100644 --- a/src/stream/udp/udp_session.cc +++ b/src/stream/udp/udp_session.cc @@ -61,7 +61,7 @@ static int ProcessUdp( { assert(lwssn->pkt_type == PktType::UDP); - if ( Stream::blocked_flow(lwssn, p) ) + if ( Stream::blocked_flow(p) ) return 0; if ( Stream::ignored_flow(lwssn, p) ) diff --git a/src/stream/user/user_session.cc b/src/stream/user/user_session.cc index 5fb877845..6cad140c1 100644 --- a/src/stream/user/user_session.cc +++ b/src/stream/user/user_session.cc @@ -482,7 +482,7 @@ int UserSession::process(Packet* p) flow->set_direction(p); - if ( Stream::blocked_flow(flow, p) || Stream::ignored_flow(flow, p) ) + if ( Stream::blocked_flow(p) || Stream::ignored_flow(flow, p) ) return 0; update(p, flow);