struct
{
- bool client_initiated : 1;
+ bool client_initiated : 1; // Set if the first packet on the flow was from the side that is currently
+ // considered to be the client
bool disable_inspect : 1;
bool reputation_src_dest : 1;
bool reputation_blacklist : 1;
last_pkt_type = p->type();
preemptive_cleanup();
- flow->set_direction(p);
- flow->session->precheck(p);
+ // If this code is executed on a flow in SETUP state, it will result in a packet from both
+ // client and server on packets from 0.0.0.0 or ::
+ if ( flow->flow_state != Flow::FlowState::SETUP )
+ {
+ flow->set_direction(p);
+ // This call can reset the flow state to SETUP in lazy flow timeout cases
+ flow->session->precheck(p);
+ }
if ( flow->flow_state != Flow::FlowState::SETUP )
{
++news;
flow->flowstats.start_time = p->pkth->ts;
- flow->flags.client_initiated = p->is_from_client();
+ // Set the flag if the flow direction matches the DAQ direction
+ flow->flags.client_initiated =
+ (p->is_from_server() ==
+ (DAQ_PKT_FLAG_REV_FLOW == (p->packet_flags & DAQ_PKT_FLAG_REV_FLOW)));
}
// This requires the packet direction to be set
Stream::stop_inspection(flow, p, SSN_DIR_BOTH, -1, 0);
else
DetectionEngine::disable_all(p);
-
- p->ptrs.decode_flags |= DECODE_PKT_TRUST;
break;
case Flow::FlowState::BLOCK:
PacketManager::encode_update(p);
verdict = DAQ_VERDICT_REPLACE;
}
+ else if ( act->session_was_trusted() )
+ {
+ if ( p->flow && !act->get_prevent_trust_action() )
+ p->flow->disable_inspection();
+
+ if ( !(act->get_tunnel_bypass() || act->get_prevent_trust_action()) )
+ {
+ verdict = DAQ_VERDICT_WHITELIST;
+ }
+ else
+ {
+ verdict = DAQ_VERDICT_PASS;
+ daq_stats.internal_whitelist++;
+ }
+ }
else if ( (p->packet_flags & PKT_IGNORE) ||
- (p->flow && p->flow->get_ignore_direction() == SSN_DIR_BOTH) )
+ (p->flow &&
+ (p->flow->get_ignore_direction() == SSN_DIR_BOTH ||
+ p->flow->flow_state == Flow::FlowState::ALLOW)) )
{
- if ( !act->get_tunnel_bypass() )
+ if ( !(act->get_tunnel_bypass() || act->get_prevent_trust_action()) )
{
verdict = DAQ_VERDICT_WHITELIST;
}
SOURCES
../request.cc
)
+
+ add_cpputest(distill_verdict_test
+ SOURCES
+ stubs.h
+ ../analyzer.cc
+ ../../packet_io/active.cc
+ )
endif ( ENABLE_SHELL )
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 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.
+//--------------------------------------------------------------------------
+// distill_verdict.cc author Ron Dempster <rdempste@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+
+#include "stubs.h"
+
+#include "main/analyzer.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
+namespace snort
+{
+int SFDAQInstance::finalize_message(DAQ_Msg_h, DAQ_Verdict verdict)
+{
+ mock().actualCall("finalize_message").onObject(this).withParameter("verdict", verdict);
+ return -1;
+}
+}
+
+using namespace snort;
+
+//--------------------------------------------------------------------------
+// Distill verdict tests
+//--------------------------------------------------------------------------
+TEST_GROUP(distill_verdict_tests)
+{
+ Packet pkt;
+ Flow flow{};
+ Active act;
+ SFDAQInstance* di;
+ Analyzer* analyzer;
+ ActiveAction* active_action;
+
+ void setup() override
+ {
+ pkt.active = &act;
+ active_action = nullptr;
+ pkt.action = &active_action;
+ di = new SFDAQInstance(nullptr, 0, nullptr);
+ pkt.daq_instance = di;
+ analyzer = new Analyzer(di, 0, nullptr);
+ }
+
+ void teardown() override
+ {
+ delete analyzer;
+ mock().clear();
+ }
+};
+
+TEST(distill_verdict_tests, normal_pass)
+{
+ // Normal pass verdict
+ pkt.packet_flags = PKT_FROM_CLIENT;
+ act.reset();
+ mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_PASS);
+ analyzer->post_process_packet(&pkt);
+ mock().checkExpectations();
+}
+
+TEST(distill_verdict_tests, trust_session_whitelist)
+{
+ // Trust session whitelist verdict
+ pkt.flow = &flow;
+ pkt.packet_flags = PKT_FROM_CLIENT;
+ flow.flags.disable_inspect = false;
+ flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+ flow.flow_state = Flow::FlowState::INSPECT;
+ act.reset();
+ act.trust_session(&pkt);
+ mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_WHITELIST);
+ analyzer->post_process_packet(&pkt);
+ mock().checkExpectations();
+ CHECK_TEXT(flow.flags.disable_inspect, "Disable inspection should have been called");
+}
+
+TEST(distill_verdict_tests, prevent_trust_session_whitelist)
+{
+ // Prevent trust_session whitelist verdict
+ pkt.flow = &flow;
+ pkt.packet_flags = PKT_FROM_CLIENT;
+ flow.flags.disable_inspect = false;
+ flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+ flow.flow_state = Flow::FlowState::INSPECT;
+ act.reset();
+ act.trust_session(&pkt);
+ act.set_prevent_trust_action();
+ mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_PASS);
+ analyzer->post_process_packet(&pkt);
+ mock().checkExpectations();
+ CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+TEST(distill_verdict_tests, flow_state_whitelist)
+{
+ // Normal flow state whitelist verdict
+ pkt.flow = &flow;
+ pkt.packet_flags = PKT_FROM_CLIENT;
+ flow.flags.disable_inspect = false;
+ flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+ flow.flow_state = Flow::FlowState::ALLOW;
+ act.reset();
+ mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_WHITELIST);
+ analyzer->post_process_packet(&pkt);
+ mock().checkExpectations();
+ CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+TEST(distill_verdict_tests, prevent_flow_state_whitelist)
+{
+ // Prevent flow state whitelist verdict
+ pkt.flow = &flow;
+ pkt.packet_flags = PKT_FROM_CLIENT;
+ flow.flags.disable_inspect = false;
+ flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+ flow.flow_state = Flow::FlowState::ALLOW;
+ act.reset();
+ act.set_prevent_trust_action();
+ mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_PASS);
+ analyzer->post_process_packet(&pkt);
+ mock().checkExpectations();
+ CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+TEST(distill_verdict_tests, ignore_both_whitelist)
+{
+ // Normal ignore both directions whitelist verdict
+ pkt.flow = &flow;
+ pkt.packet_flags = PKT_FROM_CLIENT;
+ flow.flags.disable_inspect = false;
+ flow.ssn_state.ignore_direction = SSN_DIR_BOTH;
+ flow.flow_state = Flow::FlowState::INSPECT;
+ act.reset();
+ mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_WHITELIST);
+ analyzer->post_process_packet(&pkt);
+ mock().checkExpectations();
+ CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+TEST(distill_verdict_tests, prevent_ignore_both_whitelist)
+{
+ // Prevent ignore both directions whitelist verdict
+ pkt.flow = &flow;
+ pkt.packet_flags = PKT_FROM_CLIENT;
+ flow.flags.disable_inspect = false;
+ flow.ssn_state.ignore_direction = SSN_DIR_BOTH;
+ flow.flow_state = Flow::FlowState::INSPECT;
+ act.reset();
+ act.set_prevent_trust_action();
+ mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_PASS);
+ analyzer->post_process_packet(&pkt);
+ mock().checkExpectations();
+ CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+//-------------------------------------------------------------------------
+// main
+//-------------------------------------------------------------------------
+int main(int argc, char** argv)
+{
+ return CommandLineTestRunner::RunAllTests(argc, argv);
+}
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 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.
+//--------------------------------------------------------------------------
+// stubs.h author Ron Dempster <rdempste@cisco.com>
+
+#include "detection/context_switcher.h"
+#include "detection/detection_engine.h"
+#include "detection/detection_util.h"
+#include "detection/ips_context.h"
+#include "detection/tag.h"
+#include "file_api/file_service.h"
+#include "filters/detection_filter.h"
+#include "filters/rate_filter.h"
+#include "filters/sfrf.h"
+#include "filters/sfthreshold.h"
+#include "flow/ha.h"
+#include "framework/data_bus.h"
+#include "latency/packet_latency.h"
+#include "latency/rule_latency.h"
+#include "log/messages.h"
+#include "managers/action_manager.h"
+#include "managers/codec_manager.h"
+#include "managers/event_manager.h"
+#include "managers/inspector_manager.h"
+#include "managers/ips_manager.h"
+#include "managers/module_manager.h"
+#include "main.h"
+#include "main/analyzer.h"
+#include "main/oops_handler.h"
+#include "main/policy.h"
+#include "main/snort_config.h"
+#include "main/swapper.h"
+#include "main/thread_config.h"
+#include "network_inspectors/packet_tracer/packet_tracer.h"
+#include "packet_io/active.h"
+#include "packet_io/sfdaq.h"
+#include "packet_io/sfdaq_instance.h"
+#include "packet_io/sfdaq_module.h"
+#include "profiler/profiler.h"
+#include "profiler/profiler_defs.h"
+#include "protocols/packet.h"
+#include "protocols/packet_manager.h"
+#include "side_channel/side_channel.h"
+#include "stream/stream.h"
+#include "time/packet_time.h"
+#include "trace/trace_api.h"
+#include "utils/dnet_header.h"
+#include "utils/stats.h"
+
+THREAD_LOCAL DAQStats daq_stats;
+
+void Profiler::start() { }
+void Profiler::stop(uint64_t) { }
+void Profiler::consolidate_stats() { }
+void ThreadConfig::implement_thread_affinity(SThreadType, unsigned) { }
+void Swapper::apply(Analyzer&) { }
+Swapper::~Swapper() { }
+OopsHandler::OopsHandler() { }
+OopsHandler::~OopsHandler() { }
+uint16_t get_run_num() { return 0; }
+void set_run_num(uint16_t) { }
+void set_instance_id(unsigned) { }
+void set_thread_type(SThreadType) { }
+void ContextSwitcher::push(snort::IpsContext*) { }
+void ContextSwitcher::stop() { }
+ContextSwitcher::~ContextSwitcher() { }
+snort::IpsContext* ContextSwitcher::get_context() const { return nullptr; }
+void ContextSwitcher::start() { }
+void InitTag() { }
+void CleanupTag() { }
+void RateFilter_Cleanup() { }
+int sfthreshold_alloc(unsigned int, unsigned int) { return -1; }
+void sfthreshold_reset() { }
+void sfthreshold_free() { }
+void EventTrace_Init() { }
+void EventTrace_Term() { }
+void detection_filter_init(DetectionFilterConfig*) { }
+void detection_filter_term() { }
+void RuleLatency::tterm() { }
+void PacketLatency::tterm() { }
+void SideChannelManager::thread_init() { }
+void SideChannelManager::thread_term() { }
+void CodecManager::thread_init(const snort::SnortConfig*) { }
+void CodecManager::thread_term() { }
+void EventManager::open_outputs() { }
+void EventManager::close_outputs() { }
+void IpsManager::setup_options(const snort::SnortConfig*) { }
+void IpsManager::clear_options(const snort::SnortConfig*) { }
+void ActionManager::thread_init(const snort::SnortConfig*) { }
+void ActionManager::thread_term() { }
+void ActionManager::thread_reinit(const snort::SnortConfig*) { }
+int SFRF_Alloc(unsigned int) { return -1; }
+void packet_time_update(const struct timeval*) { }
+void main_poke(unsigned) { }
+void set_default_policy(const snort::SnortConfig*) { }
+bool snort_ignore(snort::Packet*) { return false; }
+ip_t* ip_open() { return nullptr; }
+ip_t* ip_close(ip_t*) { return nullptr; }
+ssize_t ip_send(ip_t*, const void*, size_t) { return -1; }
+eth_t* eth_open(const char*) { return nullptr; }
+eth_t* eth_close(eth_t*) { return nullptr; }
+ssize_t eth_send(eth_t*, const void*, size_t) { return -1; }
+
+namespace snort
+{
+static struct timeval s_packet_time = { 0, 0 };
+THREAD_LOCAL PacketTracer* s_pkt_trace;
+THREAD_LOCAL TimeContext* ProfileContext::curr_time = nullptr;
+bool TimeProfilerStats::enabled = false;
+THREAD_LOCAL PacketCount pc;
+
+void packet_gettimeofday(struct timeval* tv) { *tv = s_packet_time; }
+MemoryContext::MemoryContext(MemoryTracker&) : saved(nullptr) { }
+MemoryContext::~MemoryContext() { }
+Packet::Packet(bool)
+{
+ memset(this , 0, sizeof(*this));
+ ip_proto_next = IpProtocol::PROTO_NOT_SET;
+ packet_flags = PKT_FROM_CLIENT;
+}
+Packet::~Packet() = default;
+IpsPolicy* get_ips_policy() { return nullptr; }
+void DataBus::publish(const char*, Packet*, Flow*) { }
+void DataBus::publish(const char*, DataEvent&, Flow*) { }
+SFDAQInstance::SFDAQInstance(const char*, unsigned, const SFDAQConfig*) { }
+SFDAQInstance::~SFDAQInstance() { }
+void SFDAQInstance::reload() { }
+bool SFDAQInstance::start() { return false; }
+bool SFDAQInstance::stop() { return false; }
+const char* SFDAQInstance::get_error() { return nullptr; }
+bool SFDAQInstance::interrupt() { return false; }
+int SFDAQInstance::inject(DAQ_Msg_h, int, const uint8_t*, uint32_t) { return -1; }
+DAQ_RecvStatus SFDAQInstance::receive_messages(unsigned) { return DAQ_RSTAT_ERROR; }
+int SFDAQInstance::ioctl(DAQ_IoctlCmd, void*, size_t) { return -4; }
+void SFDAQ::set_local_instance(SFDAQInstance*) { }
+const char* SFDAQ::verdict_to_string(DAQ_Verdict) { return nullptr; }
+bool SFDAQ::forwarding_packet(const DAQ_PktHdr_t*) { return false; }
+int SFDAQ::inject(DAQ_Msg_h, int, const uint8_t*, uint32_t) { return -1; }
+bool SFDAQ::can_inject() { return false; }
+bool SFDAQ::can_inject_raw() { return false; }
+DetectionEngine::DetectionEngine() { }
+DetectionEngine::~DetectionEngine() { }
+void DetectionEngine::onload() { }
+void DetectionEngine::thread_init() { }
+void DetectionEngine::thread_term() { }
+void DetectionEngine::idle() { }
+void DetectionEngine::reset() { }
+void DetectionEngine::wait_for_context() { }
+void DetectionEngine::set_file_data(const DataPointer&) { }
+void DetectionEngine::clear_replacement() { }
+void DetectionEngine::disable_all(Packet*) { }
+unsigned get_instance_id() { return 0; }
+const SnortConfig* SnortConfig::get_conf() { return nullptr; }
+void PacketTracer::thread_init() { }
+void PacketTracer::thread_term() { }
+void PacketTracer::log(const char*, ...) { }
+void PacketTracer::dump(Packet*) { }
+void PacketTracer::activate(const Packet&) { }
+void TraceApi::thread_init(const TraceConfig*) { }
+void TraceApi::thread_term() { }
+void TraceApi::thread_reinit(const TraceConfig*) { }
+void PacketManager::thread_init() { }
+void PacketManager::decode(
+ Packet*, const DAQ_PktHdr_t*, const uint8_t*, uint32_t, bool, bool) { }
+void PacketManager::encode_update(Packet*) { }
+void PacketManager::thread_term() { }
+const uint8_t* PacketManager::encode_response(TcpResponse, EncodeFlags, const Packet*, uint32_t&,
+ const uint8_t* const, uint32_t) { return nullptr; }
+uint16_t PacketManager::encode_get_max_payload(const Packet*) { return 0; }
+const uint8_t* PacketManager::encode_reject(UnreachResponse, EncodeFlags, const Packet*, uint32_t&)
+{ return nullptr; }
+void FileService::thread_init() { }
+void FileService::thread_term() { }
+void ErrorMessage(const char*,...) { }
+void LogMessage(const char*,...) { }
+[[noreturn]] void FatalError(const char*,...) { exit(-1); }
+void ParseWarning(WarningGroup, const char*, ...) { }
+void HighAvailabilityManager::thread_init() { }
+void HighAvailabilityManager::process_receive() { }
+void HighAvailabilityManager::thread_term() { }
+void HighAvailabilityManager::thread_term_beginning() { }
+void HighAvailabilityManager::process_update(Flow*, Packet*) { }
+void InspectorManager::thread_init(const SnortConfig*) { }
+void InspectorManager::thread_term() { }
+void InspectorManager::thread_stop(const SnortConfig*) { }
+void InspectorManager::thread_reinit(const SnortConfig*) { }
+void ModuleManager::accumulate() { }
+void Stream::handle_timeouts(bool) { }
+void Stream::purge_flows() { }
+bool Stream::set_packet_action_to_hold(Packet*) { return false; }
+void Stream::init_active_response(const Packet*, Flow*) { }
+void Stream::drop_flow(const Packet* ) { }
+void Stream::block_flow(const Packet*) { }
+IpsContext::IpsContext(unsigned) { }
+NetworkPolicy* get_network_policy() { return nullptr; }
+InspectionPolicy* get_inspection_policy() { return nullptr; }
+Flow::Flow() { }
+Flow::~Flow() { }
+}
}
DetectionEngine::queue_event(GID_REPUTATION, whitelist_event);
- p->packet_flags |= PKT_IGNORE;
- DetectionEngine::disable_all(p);
- act->allow_session(p);
+ act->trust_session(p, true);
reputationstats.whitelisted++;
}
}
const char* Active::act_str[Active::ACT_MAX][Active::AST_MAX] =
{
+ { "trust", "error", "error", "error" },
{ "allow", "error", "error", "error" },
{ "hold", "error", "error", "error" },
{ "retry", "error", "error", "error" },
bool Active::retry_packet(const Packet* p)
{
- if (active_action != ACT_PASS || !SFDAQ::forwarding_packet(p->pkth))
+ if (ACT_RETRY == active_action)
+ return true;
+
+ if (ACT_RETRY < active_action || !SFDAQ::forwarding_packet(p->pkth))
return false;
// FIXIT-L semi-arbitrary heuristic for preventing retry queue saturation - reevaluate later
{
assert(active_action == ACT_HOLD);
active_counts.holds_canceled++;
- active_action = ACT_PASS;
+ active_action = ACT_ALLOW;
}
-void Active::allow_session(Packet* p)
+void Active::trust_session(Packet* p, bool force)
{
- active_action = ACT_PASS;
+ active_action = ACT_TRUST;
+ p->packet_flags |= PKT_IGNORE;
+ DetectionEngine::disable_all(p);
if ( p->flow )
{
+ p->flow->set_ignore_direction(SSN_DIR_BOTH);
p->flow->set_state(Flow::FlowState::ALLOW);
- p->flow->disable_inspection();
}
- p->disable_inspect = true;
+ if (force)
+ {
+ if ( p->flow )
+ p->flow->disable_inspection();
+
+ p->disable_inspect = true;
+ }
}
void Active::block_session(Packet* p, bool force)
switch ( delayed_active_action )
{
- case ACT_PASS:
+ case ACT_ALLOW:
break;
case ACT_DROP:
drop_packet(p, force);
break;
}
- delayed_active_action = ACT_PASS;
+ delayed_active_action = ACT_ALLOW;
}
void Active::reset()
{
active_tunnel_bypass = 0;
+ prevent_trust_action = false;
active_status = AST_ALLOW;
- active_action = ACT_PASS;
- delayed_active_action = ACT_PASS;
+ active_action = ACT_ALLOW;
+ delayed_active_action = ACT_ALLOW;
delayed_reject = nullptr;
}
// apply_delayed_action, in a big switch(action). Do away with these and
// use the actual (Base)Action objects.
enum ActiveActionType : uint8_t
- { ACT_PASS, ACT_HOLD, ACT_RETRY, ACT_DROP, ACT_BLOCK, ACT_RESET, ACT_MAX };
+ { ACT_TRUST, ACT_ALLOW, ACT_HOLD, ACT_RETRY, ACT_DROP, ACT_BLOCK, ACT_RESET, ACT_MAX };
public:
bool hold_packet(const Packet*);
void cancel_packet_hold();
- void allow_session(Packet*);
+ void trust_session(Packet*, bool force = false);
void block_session(Packet*, bool force = false);
void reset_session(Packet*, bool force = false);
void reset_session(Packet*, snort::ActiveAction* r, bool force = false);
bool packet_retry_requested() const
{ return active_action == ACT_RETRY; }
+ bool session_was_trusted() const
+ { return active_action == ACT_TRUST; }
+
bool session_was_blocked() const
{ return active_action >= ACT_BLOCK; }
bool get_tunnel_bypass() const
{ return active_tunnel_bypass > 0; }
+ void set_prevent_trust_action()
+ { prevent_trust_action = true; }
+
+ bool get_prevent_trust_action() const
+ { return prevent_trust_action; }
+
void set_delayed_action(ActiveActionType, bool force = false);
void set_delayed_action(ActiveActionType, ActiveAction* act, bool force = false);
void apply_delayed_action(Packet*);
int active_tunnel_bypass;
+ bool prevent_trust_action;
+
// 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.
bool is_from_server() const
{ return (packet_flags & PKT_FROM_SERVER) != 0; }
+ bool is_from_client_originally() const
+ { return (!flow || flow->flags.client_initiated) ? is_from_client() : is_from_server(); }
+
+ bool is_from_server_originally() const
+ { return (!flow || flow->flags.client_initiated) ? is_from_server() : is_from_client(); }
+
bool is_full_pdu() const
{ return (packet_flags & PKT_PDU_FULL) == PKT_PDU_FULL; }
static const char* get_action(uint8_t act)
{
- const char* acts[] = { "pass", "hold", "retry", "drop", "block", "reset" };
+ const char* acts[] = { "trust", "pass", "hold", "retry", "drop", "block", "reset" };
return lookup(acts, sizeof(acts)/sizeof(acts[0]), act);
}