SfIpString src_addr, dst_addr;
unsigned src_port = 0, dst_port = 0;
- if ( p->is_from_client() )
+ if ( p->is_from_application_client() )
dir = "C2S";
- else if ( p->is_from_server() )
+ else if ( p->is_from_application_server() )
dir = "S2C";
else
dir = "UNK";
PortGroup* svc = nullptr;
- if (p->is_from_server())
+ if (p->is_from_application_server())
svc = p->context->conf->sopgTable->get_port_group(false, snort_protocol_id);
- else if (p->is_from_client())
+ else if (p->is_from_application_client())
svc = p->context->conf->sopgTable->get_port_group(true, snort_protocol_id);
if ( svc )
time_t expires = 0;
bool reversed_key = false;
int direction = 0;
+ bool swap_app_direction = false;
unsigned count = 0;
SnortProtocolId snort_protocol_id = UNKNOWN_PROTOCOL_ID;
{
ExpectFlow* head;
FlowData* fd;
- int ignoring = false;
+ bool ignoring = false;
assert(node->count && node->head);
if (!node->snort_protocol_id)
ignoring = node->direction != 0;
else
+ {
lws->ssn_state.snort_protocol_id = node->snort_protocol_id;
+ if ( node->swap_app_direction)
+ lws->flags.app_direction_swapped = true;
+ }
if (!node->count)
hash_table->release_node(&key);
*/
int ExpectCache::add_flow(const Packet *ctrlPkt, PktType type, IpProtocol ip_proto,
const SfIp* cliIP, uint16_t cliPort, const SfIp* srvIP, uint16_t srvPort,
- char direction, FlowData* fd, SnortProtocolId snort_protocol_id)
+ char direction, FlowData* fd, SnortProtocolId snort_protocol_id, bool swap_app_direction)
{
/* Just pull the VLAN ID, MPLS ID, and Address Space ID from the
control packet until we have a use case for not doing so. */
node->snort_protocol_id = snort_protocol_id;
node->reversed_key = reversed_key;
node->direction = direction;
+ node->swap_app_direction = swap_app_direction;
node->head = node->tail = nullptr;
node->count = 0;
last = nullptr;
ExpectCache(const ExpectCache&) = delete;
ExpectCache& operator=(const ExpectCache&) = delete;
- int add_flow(const snort::Packet *ctrlPkt, PktType, IpProtocol,
- const snort::SfIp* cliIP, uint16_t cliPort,
- const snort::SfIp* srvIP, uint16_t srvPort,
- char direction, snort::FlowData*, SnortProtocolId snort_protocol_id = UNKNOWN_PROTOCOL_ID);
+ int add_flow(const snort::Packet *ctrlPkt, PktType, IpProtocol, const snort::SfIp* cliIP,
+ uint16_t cliPort, const snort::SfIp* srvIP, uint16_t srvPort, char direction,
+ snort::FlowData*, SnortProtocolId snort_protocol_id = UNKNOWN_PROTOCOL_ID,
+ bool swap_app_direction = false);
bool is_expected(snort::Packet*);
bool check(snort::Packet*, snort::Flow*);
struct
{
- 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 client_initiated : 1; // Set if the first packet on the flow was from the side that is
+ // currently considered to be the client
+ bool app_direction_swapped : 1; // Packet direction swapped from application perspective
bool disable_inspect : 1;
bool reputation_src_dest : 1;
bool reputation_blacklist : 1;
bool trigger_detained_packet_event : 1;
bool trigger_finalize_event : 1;
bool use_direct_inject : 1;
- bool data_decrypted : 1; // indicate data in current flow is decrypted TLS application data
+ bool data_decrypted : 1; // indicate data in current flow is decrypted TLS application
+ //data
} flags;
FlowState flow_state;
default:
break;
}
+ flow->flags.app_direction_swapped = false;
if ( flow->ssn_state.direction == FROM_CLIENT )
p->packet_flags |= PKT_FROM_CLIENT;
else
PacketTracer::log("Session: new snort session\n");
init_roles(p, flow);
+
+ // process expected flows
+ check_expected_flow(flow, p);
+
DataBus::publish(FLOW_STATE_SETUP_EVENT, p);
if ( flow->flow_state == Flow::FlowState::SETUP ||
exp_cache = new ExpectCache(max);
}
-bool FlowControl::expected_flow(Flow* flow, Packet* p)
+void FlowControl::check_expected_flow(Flow* flow, Packet* p)
{
bool ignore = exp_cache->check(p, flow);
flow->ssn_state.ignore_direction = ignore;
DetectionEngine::disable_all(p);
}
-
- return ignore;
}
-int FlowControl::add_expected(
- const Packet* ctrlPkt, PktType type, IpProtocol ip_proto,
- const SfIp *srcIP, uint16_t srcPort,
- const SfIp *dstIP, uint16_t dstPort,
- char direction, FlowData* fd)
+int FlowControl::add_expected_ignore( const Packet* ctrlPkt, PktType type, IpProtocol ip_proto,
+ const SfIp *srcIP, uint16_t srcPort, const SfIp *dstIP, uint16_t dstPort, char direction,
+ FlowData* fd)
{
- return exp_cache->add_flow(
- ctrlPkt, type, ip_proto, srcIP, srcPort, dstIP, dstPort,
- direction, fd);
+ return exp_cache->add_flow( ctrlPkt, type, ip_proto, srcIP, srcPort, dstIP, dstPort, direction,
+ fd);
}
-int FlowControl::add_expected(
- const Packet* ctrlPkt, PktType type, IpProtocol ip_proto,
- const SfIp *srcIP, uint16_t srcPort,
- const SfIp *dstIP, uint16_t dstPort,
- SnortProtocolId snort_protocol_id, FlowData* fd)
+int FlowControl::add_expected( const Packet* ctrlPkt, PktType type, IpProtocol ip_proto,
+ const SfIp *srcIP, uint16_t srcPort, const SfIp *dstIP, uint16_t dstPort,
+ SnortProtocolId snort_protocol_id, FlowData* fd, bool swap_app_direction)
{
- return exp_cache->add_flow(
- ctrlPkt, type, ip_proto, srcIP, srcPort, dstIP, dstPort,
- SSN_DIR_BOTH, fd, snort_protocol_id);
+ return exp_cache->add_flow( ctrlPkt, type, ip_proto, srcIP, srcPort, dstIP, dstPort,
+ SSN_DIR_BOTH, fd, snort_protocol_id, swap_app_direction);
}
bool FlowControl::is_expected(Packet* p)
bool prune_one(PruneReason, bool do_cleanup);
snort::Flow* stale_flow_cleanup(FlowCache*, snort::Flow*, snort::Packet*);
void timeout_flows(time_t cur_time);
- bool expected_flow(snort::Flow*, snort::Packet*);
+ void check_expected_flow(snort::Flow*, snort::Packet*);
bool is_expected(snort::Packet*);
- int add_expected(
+ int add_expected_ignore(
const snort::Packet* ctrlPkt, PktType, IpProtocol,
const snort::SfIp *srcIP, uint16_t srcPort,
const snort::SfIp *dstIP, uint16_t dstPort,
char direction, snort::FlowData*);
- int add_expected(
- const snort::Packet* ctrlPkt, PktType, IpProtocol,
- const snort::SfIp *srcIP, uint16_t srcPort,
- const snort::SfIp *dstIP, uint16_t dstPort,
- SnortProtocolId snort_protocol_id, snort::FlowData*);
+ int add_expected(const snort::Packet* ctrlPkt, PktType, IpProtocol, const snort::SfIp *srcIP,
+ uint16_t srcPort, const snort::SfIp *dstIP, uint16_t dstPort,
+ SnortProtocolId snort_protocol_id, snort::FlowData*, bool swap_app_direction = false);
class ExpectCache* get_exp_cache()
{ return exp_cache; }
int ExpectCache::add_flow(const Packet*, PktType, IpProtocol, const SfIp*, uint16_t,
- const SfIp*, uint16_t, char, FlowData*, SnortProtocolId)
+ const SfIp*, uint16_t, char, FlowData*, SnortProtocolId, bool)
{
return 1;
}
PktType, IpProtocol,
const SfIp*, uint16_t,
const SfIp*, uint16_t,
- char, FlowData*, SnortProtocolId)
+ char, FlowData*, SnortProtocolId, bool)
{
return 1;
}
if (fcd->from_client)
{
{
- if (!p->is_from_client() && p->is_from_server())
+ if (!p->is_from_application_client() && p->is_from_application_server())
{
// No match on from_client
return NO_MATCH;
if (fcd->from_server)
{
{
- if (!p->is_from_server() && p->is_from_client())
+ if (!p->is_from_application_server() && p->is_from_application_client())
{
// No match on from_server
return NO_MATCH;
{
const char* dir;
- if ( a.pkt->is_from_client() )
+ if ( a.pkt->is_from_application_client() )
dir = "C2S";
- else if ( a.pkt->is_from_server() )
+ else if ( a.pkt->is_from_application_server() )
dir = "S2C";
else
dir = "UNK";
{
const char* dir;
- if ( a.pkt->is_from_client() )
+ if ( a.pkt->is_from_application_client() )
dir = "C2S";
- else if ( a.pkt->is_from_server() )
+ else if ( a.pkt->is_from_application_server() )
dir = "S2C";
else
dir = "UNK";
else if (p->flow)
{
- if (p->is_from_client())
+ if (p->is_from_application_client())
copy_addr(p->flow->client_ip, p->flow->server_ip, u2_event);
else
copy_addr(p->flow->server_ip, p->flow->client_ip, u2_event);
}
else if (p->flow)
{
- if (p->is_from_client())
+ if (p->is_from_application_client())
{
alertdata.ip_source = *(p->flow->client_ip.get_ip4_ptr());
alertdata.ip_destination = *(p->flow->server_ip.get_ip4_ptr());
}
else if (p->flow)
{
- if (p->is_from_client())
+ if (p->is_from_application_client())
{
alertdata.ip_source = *(const struct in6_addr*)p->flow->client_ip.get_ip6_ptr();
alertdata.ip_destination = *(const struct in6_addr*)p->flow->server_ip.get_ip6_ptr();
AppIdSession* AppIdSession::create_future_session(const Packet* ctrlPkt, const SfIp* cliIp,
uint16_t cliPort, const SfIp* srvIp, uint16_t srvPort, IpProtocol proto,
- SnortProtocolId snort_protocol_id)
+ SnortProtocolId snort_protocol_id, bool swap_app_direction)
{
char src_ip[INET6_ADDRSTRLEN];
char dst_ip[INET6_ADDRSTRLEN];
inspector->get_ctxt().get_odp_ctxt());
if (Stream::set_snort_protocol_id_expected(ctrlPkt, type, proto, cliIp,
- cliPort, srvIp, srvPort, snort_protocol_id, asd))
+ cliPort, srvIp, srvPort, snort_protocol_id, asd, swap_app_direction))
{
if (appidDebug->is_active())
{
static AppIdSession* allocate_session(const snort::Packet*, IpProtocol,
AppidSessionDirection, AppIdInspector*, OdpContext&);
static AppIdSession* create_future_session(const snort::Packet*, const snort::SfIp*, uint16_t,
- const snort::SfIp*, uint16_t, IpProtocol, SnortProtocolId);
+ const snort::SfIp*, uint16_t, IpProtocol, SnortProtocolId, bool swap_app_direction=false);
void initialize_future_session(AppIdSession&, uint64_t, AppidSessionDirection);
size_t size_of() override
if(ftp_data_snort_protocol_id == UNKNOWN_PROTOCOL_ID)
ftp_data_snort_protocol_id = pkt->context->conf->proto_ref->find("ftp-data");
+ bool swap_flow_app_direction = (dir == APP_ID_FROM_RESPONDER) ? true : false;
+
AppIdSession* fp = AppIdSession::create_future_session(pkt, cliIp, cliPort, srvIp, srvPort,
- protocol, ftp_data_snort_protocol_id);
+ protocol, ftp_data_snort_protocol_id, swap_flow_app_direction);
if (fp) // initialize data session
{
Binding::~Binding()
{
- if ( when.src_nets )
+ if (when.src_nets)
sfvar_free(when.src_nets);
- if ( when.dst_nets )
+ if (when.dst_nets)
sfvar_free(when.dst_nets);
}
inline bool Binding::check_ips_policy(const Flow* flow) const
{
- if ( !when.ips_id )
+ if (!when.ips_id)
return true;
- if ( when.ips_id == flow->ips_policy_id )
+ if (when.ips_id == flow->ips_policy_id)
return true;
return false;
inline bool Binding::check_addr(const Flow* flow) const
{
- if ( when.split_nets )
+ if (when.split_nets)
return true;
- if ( !when.src_nets )
+ if (!when.src_nets)
return true;
- switch ( when.role )
+ switch (when.role)
{
case BindWhen::BR_SERVER:
- if ( sfvar_ip_in(when.src_nets, &flow->server_ip) )
+ if (sfvar_ip_in(when.src_nets, &flow->server_ip))
return true;
break;
case BindWhen::BR_CLIENT:
- if ( sfvar_ip_in(when.src_nets, &flow->client_ip) )
+ if (sfvar_ip_in(when.src_nets, &flow->client_ip))
return true;
break;
case BindWhen::BR_EITHER:
- if ( sfvar_ip_in(when.src_nets, &flow->client_ip) or
- sfvar_ip_in(when.src_nets, &flow->server_ip) )
+ if (sfvar_ip_in(when.src_nets, &flow->client_ip) or
+ sfvar_ip_in(when.src_nets, &flow->server_ip))
return true;
break;
inline bool Binding::check_proto(const Flow* flow) const
{
- if ( when.protos & BIT((unsigned)flow->pkt_type) )
+ if (when.protos & BIT((unsigned)flow->pkt_type))
return true;
return false;
inline bool Binding::check_iface(const Packet* p) const
{
- if ( !p or when.ifaces.none() )
+ if (!p or when.ifaces.none())
return true;
auto in = p->pkth->ingress_index;
auto out = p->pkth->egress_index;
- if ( in > 0 and when.ifaces.test(out) )
+ if (in > 0 and when.ifaces.test(out))
return true;
- if ( out > 0 and when.ifaces.test(in) )
+ if (out > 0 and when.ifaces.test(in))
return true;
return false;
inline bool Binding::check_port(const Flow* flow) const
{
- if ( when.split_ports )
+ if (when.split_ports)
return true;
- switch ( when.role )
+ switch (when.role)
{
case BindWhen::BR_SERVER:
return when.src_ports.test(flow->server_port);
return when.src_ports.test(flow->client_port);
case BindWhen::BR_EITHER:
return (when.src_ports.test(flow->client_port) or
- when.src_ports.test(flow->server_port) );
+ when.src_ports.test(flow->server_port));
default:
break;
}
inline bool Binding::check_service(const Flow* flow) const
{
- if ( !flow->service )
+ if (!flow->service)
return when.svc.empty();
- if ( when.svc == flow->service )
+ if (when.svc == flow->service)
return true;
return false;
inline bool Binding::check_service(const char* service) const
{
- if ( when.svc == service )
+ if (when.svc == service)
return true;
return false;
bool forward_match = false;
bool reverse_match = false;
- switch ( dr )
+ switch (dr)
{
case Binding::DR_ANY_MATCH:
src_in_src = compare(when_src, traffic_src);
forward_match = src_in_src and dst_in_dst;
reverse_match = dst_in_src and src_in_dst;
- if ( forward_match and reverse_match )
+ if (forward_match and reverse_match)
return dr;
- if ( forward_match )
+ if (forward_match)
return Binding::DR_FORWARD;
- if ( reverse_match )
+ if (reverse_match)
return Binding::DR_REVERSE;
return Binding::DR_NO_MATCH;
inline Binding::DirResult Binding::check_split_addr(
const Flow* flow, const Packet* p, const Binding::DirResult dr) const
{
- if ( !when.split_nets )
+ if (!when.split_nets)
return dr;
- if ( !when.src_nets && !when.dst_nets )
+ if (!when.src_nets && !when.dst_nets)
return dr;
const SfIp* src_ip;
const SfIp* dst_ip;
- if ( p && p->ptrs.ip_api.is_ip() )
+ if (p && p->ptrs.ip_api.is_ip())
{
src_ip = p->ptrs.ip_api.get_src();
dst_ip = p->ptrs.ip_api.get_dst();
inline Binding::DirResult Binding::check_split_port(
const Flow* flow, const Packet* p, const Binding::DirResult dr) const
{
- if ( !when.split_ports )
+ if (!when.split_ports)
return dr;
uint16_t src_port;
uint16_t dst_port;
- if ( !p )
+ if (!p)
{
src_port = flow->client_port;
dst_port = flow->server_port;
}
- else if ( p->is_tcp() or p->is_udp() )
+ else if (p->is_tcp() or p->is_udp())
{
src_port = p->ptrs.sp;
dst_port = p->ptrs.dp;
inline bool Binding::check_zone(const Packet* p) const
{
- if ( when.split_zones or !p )
+ if (when.split_zones or !p)
return true;
if (p->pkth->egress_group == DAQ_PKTHDR_UNKNOWN or
inline Binding::DirResult Binding::check_split_zone(const Packet* p, const Binding::DirResult dr) const
{
- if ( !when.split_zones )
+ if (!when.split_zones)
return dr;
int src_zone;
int dst_zone;
- if ( p )
+ if (p)
{
src_zone = p->pkth->ingress_group;
dst_zone = p->pkth->egress_group;
{
Binding::DirResult dir = Binding::DR_ANY_MATCH;
- if ( !check_ips_policy(flow) )
+ if (!check_ips_policy(flow))
return false;
- if ( !check_iface(p) )
+ if (!check_iface(p))
return false;
- if ( !check_vlan(flow) )
+ if (!check_vlan(flow))
return false;
// FIXIT-M need to check role and addr/ports relative to it
- if ( !check_addr(flow) )
+ if (!check_addr(flow))
return false;
dir = check_split_addr(flow, p, dir);
- if ( dir == Binding::DR_NO_MATCH )
+ if (dir == Binding::DR_NO_MATCH)
return false;
- if ( !check_proto(flow) )
+ if (!check_proto(flow))
return false;
- if ( !check_port(flow) )
+ if (!check_port(flow))
return false;
dir = check_split_port(flow, p, dir);
- if ( dir == Binding::DR_NO_MATCH )
+ if (dir == Binding::DR_NO_MATCH)
return false;
dir = check_split_zone(p, dir);
- if ( dir == Binding::DR_NO_MATCH )
+ if (dir == Binding::DR_NO_MATCH)
return false;
if (service)
if (!check_service(service))
return false;
}
- else if ( !check_service(flow) )
+ else if (!check_service(flow))
return false;
- if ( !check_zone(p) )
+ if (!check_zone(p))
return false;
return true;
{
Inspector* pin = InspectorManager::get_inspector(key);
- if ( pin )
+ if (pin)
{
// FIXIT-M need to set ssn client and server independently
flow->set_client(pin);
static Inspector* get_gadget(Flow* flow)
{
- if ( flow->ssn_state.snort_protocol_id == UNKNOWN_PROTOCOL_ID )
+ if (flow->ssn_state.snort_protocol_id == UNKNOWN_PROTOCOL_ID)
return nullptr;
const char* s = SnortConfig::get_conf()->proto_ref->get_name(flow->ssn_state.snort_protocol_id);
{
std::string ipset;
- if ( !list or !list->head )
+ if (!list or !list->head)
return "";
for (auto node = list->head; node; node = node->next)
ip->get_addr()->ntop(ip_str);
ipset += std::string(ip_str);
- if ( ((ip->get_family() == AF_INET6) and (ip->get_bits() != 128)) or
- ((ip->get_family() == AF_INET ) and (ip->get_bits() != 32 )) )
+ if (((ip->get_family() == AF_INET6) and (ip->get_bits() != 128)) or
+ ((ip->get_family() == AF_INET) and (ip->get_bits() != 32)))
{
auto bits = ip->get_bits();
bits -= (ip->get_family() == AF_INET and bits) ? 96 : 0;
ipset += ", ";
}
- if ( !ipset.empty() )
+ if (!ipset.empty())
ipset.erase(ipset.end() - 2, ipset.end());
return ipset;
{
std::stringstream ss;
- if ( bitset.none() or bitset.all() )
+ if (bitset.none() or bitset.all())
return "";
for (unsigned i = 0; i < bitset.size(); ++i)
- if ( bitset[i] )
+ if (bitset[i])
ss << i << " ";
auto str = ss.str();
- if ( !str.empty() )
+ if (!str.empty())
str.pop_back();
return str;
static std::string to_string(const BindWhen::Role& role)
{
- switch( role )
+ switch(role)
{
case BindWhen::BR_CLIENT:
return "client";
static std::string proto_to_string(unsigned proto)
{
- switch( proto )
+ switch(proto)
{
case PROTO_BIT__IP:
return "ip";
static std::string to_string(const BindUse::Action& action)
{
- switch( action )
+ switch(action)
{
case BindUse::BA_RESET:
return "reset";
when += "{";
- if ( bw.ips_id_user )
+ if (bw.ips_id_user)
when += " ips_policy_id = " + std::to_string(bw.ips_id_user) + ",";
- if ( !bw.svc.empty() )
+ if (!bw.svc.empty())
when += " service = " + bw.svc + ",";
auto role = to_string(bw.role);
- if ( !role.empty() )
+ if (!role.empty())
when += " role = " + role + ",";
auto proto = proto_to_string(bw.protos);
- if ( !proto.empty() )
+ if (!proto.empty())
when += " proto = " + proto + ",";
auto src_nets = to_string(bw.src_nets);
auto dst_nets = to_string(bw.dst_nets);
- if ( !src_nets.empty() )
+ if (!src_nets.empty())
when += (bw.split_nets ? " src_nets = " : " nets = ") + src_nets + ",";
- if ( bw.split_nets and !dst_nets.empty() )
+ if (bw.split_nets and !dst_nets.empty())
when += " dst_nets = " + dst_nets + ",";
auto src_ports = to_string<65536>(bw.src_ports);
auto dst_ports = to_string<65536>(bw.dst_ports);
- if ( !src_ports.empty() )
+ if (!src_ports.empty())
when += (bw.split_ports ? " src_ports = " : " ports = ") + src_ports + ",";
- if ( bw.split_ports and !dst_ports.empty() )
+ if (bw.split_ports and !dst_ports.empty())
when += " dst_ports = " + dst_ports + ",";
auto src_zones = to_string<64>(bw.src_zones);
auto dst_zones = to_string<64>(bw.dst_zones);
- if ( !src_zones.empty() )
+ if (!src_zones.empty())
when += (bw.split_zones ? " src_zones = " : " zones = ") + src_zones + ",";
- if ( bw.split_zones and !dst_zones.empty() )
+ if (bw.split_zones and !dst_zones.empty())
when += " dst_zones = " + dst_zones + ",";
auto ifaces = to_string<256>(bw.ifaces);
- if ( !ifaces.empty() )
+ if (!ifaces.empty())
when += " ifaces = " + ifaces + ",";
auto vlans = to_string<4096>(bw.vlans);
- if ( !vlans.empty() )
+ if (!vlans.empty())
when += " vlans = " + vlans + ",";
- if ( when.length() > 1 )
+ if (when.length() > 1)
when.pop_back();
when += " }";
use += "{";
auto action = to_string(bu.action);
- if ( !action.empty() )
+ if (!action.empty())
use += " action = " + action + ",";
- if ( !bu.svc.empty() )
+ if (!bu.svc.empty())
use += " service = " + bu.svc + ",";
- if ( !bu.type.empty() )
+ if (!bu.type.empty())
use += " type = " + ((bu.type.at(0) == '.') ? bu.type.substr(1) : bu.type) + ",";
- if ( !bu.name.empty() and (bu.type != bu.name) )
+ if (!bu.name.empty() and (bu.type != bu.name))
use += " name = " + bu.name + ",";
- if ( use.length() > 1 )
+ if (use.length() > 1)
use.pop_back();
use += " }";
bool Stuff::update(Binding* pb)
{
- if ( pb->use.action != BindUse::BA_INSPECT )
+ if (pb->use.action != BindUse::BA_INSPECT)
{
action = pb->use.action;
return true;
}
- switch ( pb->use.what )
+ switch (pb->use.what)
{
case BindUse::BW_NONE:
break;
bool Stuff::apply_action(Flow* flow)
{
- switch ( action )
+ switch (action)
{
case BindUse::BA_RESET:
flow->set_state(Flow::FlowState::RESET);
void Stuff::apply_session(Flow* flow, const HostAttributesEntry host)
{
- if ( server )
+ if (server)
{
flow->set_server(server);
- if ( client )
+ if (client)
flow->set_client(client);
else
flow->set_client(server);
return;
}
- switch ( flow->pkt_type )
+ switch (flow->pkt_type)
{
case PktType::IP:
set_session(flow, INS_IP);
void Stuff::apply_service(Flow* flow, const HostAttributesEntry host)
{
- if ( data )
+ if (data)
flow->set_data(data);
- if ( host )
+ if (host)
set_service(flow, host);
- if ( !gadget )
+ if (!gadget)
gadget = get_gadget(flow);
- if ( gadget )
+ if (gadget)
{
- flow->set_gadget(gadget);
+ if (gadget != flow->gadget)
+ {
+ flow->set_gadget(gadget);
- if ( flow->ssn_state.snort_protocol_id == UNKNOWN_PROTOCOL_ID )
- flow->ssn_state.snort_protocol_id = gadget->get_service();
+ if (flow->ssn_state.snort_protocol_id == UNKNOWN_PROTOCOL_ID)
+ flow->ssn_state.snort_protocol_id = gadget->get_service();
- DataBus::publish(SERVICE_INSPECTOR_CHANGE_EVENT, DetectionEngine::get_current_packet());
+ DataBus::publish(SERVICE_INSPECTOR_CHANGE_EVENT, DetectionEngine::get_current_packet());
+ }
}
-
- else if ( wizard )
+ else if (wizard)
flow->set_clouseau(wizard);
}
void Stuff::apply_assistant(Flow* flow, const char* service)
{
- if ( !gadget )
+ if (!gadget)
gadget = get_gadget_by_id(service);
- if ( gadget )
+ if (gadget)
flow->set_assistant_gadget(gadget);
}
Binder::~Binder()
{
- for ( auto* p : bindings )
+ for (auto* p : bindings)
delete p;
}
{
unsigned sz = bindings.size();
- for ( unsigned i = 0; i < sz; i++ )
+ for (unsigned i = 0; i < sz; i++)
{
Binding* pb = bindings[i];
// Update with actual policy indices instead of user provided names
- if ( pb->when.ips_id_user )
+ if (pb->when.ips_id_user)
{
IpsPolicy* p = sc->policy_map->get_user_ips(pb->when.ips_id_user);
- if ( p )
+ if (p)
pb->when.ips_id = p->policy_id;
else
ParseError("can't bind. ips_policy_id %u does not exist", pb->when.ips_id);
}
- if ( !pb->use.ips_index and !pb->use.inspection_index )
+ if (!pb->use.ips_index and !pb->use.inspection_index)
set_binding(sc, pb);
}
{
std::once_flag once;
- if ( !bindings.size() )
+ if (!bindings.size())
return;
for (const auto& b : bindings)
void Binder::remove_inspector_binding(SnortConfig*, const char* name)
{
vector<Binding*>::iterator it;
- for ( it = bindings.begin(); it != bindings.end(); ++it )
+ for (it = bindings.begin(); it != bindings.end(); ++it)
{
const char* key;
Binding *pb = *it;
- if ( pb->use.svc.empty() )
+ if (pb->use.svc.empty())
key = pb->use.name.c_str();
else
key = pb->use.svc.c_str();
- if ( !strcmp(key, name) )
+ if (!strcmp(key, name))
{
bindings.erase(it);
delete pb;
++bstats.packets;
}
-void Binder::handle_flow_service_change( Flow* flow )
+void Binder::handle_flow_service_change(Flow* flow)
{
Profile profile(bindPerfStats);
if (flow->service)
{
ins = find_gadget(flow);
- if ( flow->gadget != ins )
+ if (flow->gadget != ins)
{
- if ( flow->gadget )
+ if (flow->gadget)
flow->clear_gadget();
- if ( ins )
+ if (ins)
{
flow->set_gadget(ins);
flow->ssn_state.snort_protocol_id = ins->get_service();
{
// reset to wizard when service is not specified
unsigned sz = bindings.size();
- for ( unsigned i = 0; i < sz; i++ )
+ for (unsigned i = 0; i < sz; i++)
{
Binding* pb = bindings[i];
- if ( pb->use.ips_index or pb->use.inspection_index )
+ if (pb->use.ips_index or pb->use.inspection_index)
continue;
- if ( pb->use.what == BindUse::BW_WIZARD )
+ if (pb->use.what == BindUse::BW_WIZARD)
{
ins = (Inspector*)pb->use.object;
break;
}
}
- if ( flow->gadget )
+ if (flow->gadget)
flow->clear_gadget();
- if ( flow->clouseau )
+ if (flow->clouseau)
flow->clear_clouseau();
- if ( ins )
+ if (ins)
{
flow->set_clouseau(ins);
}
// If there is no inspector bound to this flow after the service change, see if there's at least
// an associated protocol ID.
- if ( !ins && flow->service )
+ if (!ins && flow->service)
flow->ssn_state.snort_protocol_id = SnortConfig::get_conf()->proto_ref->find(flow->service);
- if ( !flow->is_stream() )
+ if (!flow->is_stream())
return;
- if ( ins )
+ if (ins)
{
Stream::set_splitter(flow, true, ins->get_splitter(true));
Stream::set_splitter(flow, false, ins->get_splitter(false));
}
}
-void Binder::handle_new_standby_flow( Flow* flow )
+void Binder::handle_new_standby_flow(Flow* flow)
{
Profile profile(bindPerfStats);
void Binder::set_binding(SnortConfig* sc, Binding* pb)
{
- if ( pb->use.action != BindUse::BA_INSPECT )
+ if (pb->use.action != BindUse::BA_INSPECT)
return;
const char* key = pb->use.name.c_str();
pb->use.object = InspectorManager::get_inspector(key, is_global, sc);
- if ( pb->use.object )
+ if (pb->use.object)
{
- switch ( ((Inspector*)pb->use.object)->get_api()->type )
+ switch (((Inspector*)pb->use.object)->get_api()->type)
{
case IT_STREAM: pb->use.what = BindUse::BW_STREAM; break;
case IT_WIZARD: pb->use.what = BindUse::BW_WIZARD; break;
default: break;
}
}
- if ( !pb->use.object )
+ if (!pb->use.object)
pb->use.what = BindUse::BW_NONE;
- if ( pb->use.what == BindUse::BW_NONE )
+ if (pb->use.what == BindUse::BW_NONE)
ParseError("can't bind %s", key);
}
bool inspection_set = false, ips_set = false;
const SnortConfig* sc = SnortConfig::get_conf();
- for ( unsigned i = 0; i < sz; i++ )
+ for (unsigned i = 0; i < sz; i++)
{
Binding* pb = bindings[i];
// Skip any rules that don't contain an ID for a policy type we haven't set yet.
- if ( (!pb->use.inspection_index or inspection_set) and
- (!pb->use.ips_index or ips_set) )
+ if ((!pb->use.inspection_index or inspection_set) and
+ (!pb->use.ips_index or ips_set))
continue;
- if ( !pb->check_all(flow, p, service) )
+ if (!pb->check_all(flow, p, service))
continue;
- if ( pb->use.inspection_index and !inspection_set )
+ if (pb->use.inspection_index and !inspection_set)
{
set_inspection_policy(sc, pb->use.inspection_index - 1);
if (!service)
inspection_set = true;
}
- if ( pb->use.ips_index and !ips_set )
+ if (pb->use.ips_index and !ips_set)
{
set_ips_policy(sc, pb->use.ips_index - 1);
if (!service)
Binder* sub = InspectorManager::get_binder();
// If policy selection produced a new binder to use, use that instead.
- if ( sub && sub != this )
+ if (sub && sub != this)
{
sub->get_bindings(flow, stuff, p);
return;
// If we got here, that means that a sub-policy with a binder was not invoked.
// Continue using this binder for the rest of processing.
- for ( unsigned i = 0; i < sz; i++ )
+ for (unsigned i = 0; i < sz; i++)
{
Binding* pb = bindings[i];
- if ( pb->use.ips_index or pb->use.inspection_index )
+ if (pb->use.ips_index or pb->use.inspection_index)
continue;
- if ( !pb->check_all(flow, p, service) )
+ if (!pb->check_all(flow, p, service))
continue;
- if ( stuff.update(pb) )
+ if (stuff.update(pb))
return;
}
}
void Binder::apply(Flow* flow, Stuff& stuff)
{
// setup action
- if ( !stuff.apply_action(flow) )
+ if (!stuff.apply_action(flow))
return;
const HostAttributesEntry host = HostAttributesManager::find_host(flow->server_ip);
return vid;
}
+bool Packet::is_from_application_client() const
+{
+ if (flow)
+ return flow->flags.app_direction_swapped ? is_from_server() : is_from_client();
+ else
+ return is_from_client();
+}
+
+bool Packet::is_from_application_server() const
+{
+ if (flow)
+ return flow->flags.app_direction_swapped ? is_from_client() : is_from_server();
+ else
+ return is_from_server();
+}
+
} // namespace snort
bool is_from_server_originally() const
{ return (!flow || flow->flags.client_initiated) ? is_from_server() : is_from_client(); }
+
+ bool is_from_application_client() const;
+
+ bool is_from_application_server() const;
bool is_full_pdu() const
{ return (packet_flags & PKT_PDU_FULL) == PKT_PDU_FULL; }
if (data_ssn->packet_flags & FTPDATA_FLG_FLUSH)
{
- file_flows->set_sig_gen_state( true );
+ file_flows->set_sig_gen_state(true);
data_ssn->packet_flags &= ~FTPDATA_FLG_FLUSH;
}
else
- file_flows->set_sig_gen_state( false );
+ file_flows->set_sig_gen_state(false);
status = file_flows->file_process(p, file_data, data_length,
data_ssn->position, data_ssn->direction, data_ssn->path_hash);
- if ( p->active->packet_force_dropped() )
+ if (p->active->packet_force_dropped())
{
FtpFlowData* fd = (FtpFlowData*)Stream::get_flow_data(
&data_ssn->ftp_key, FtpFlowData::inspector_id);
// Ignore the rest of this transfer if file processing is complete
// and status is returned false (eg sig not enabled, sig depth exceeded etc)
// and no IPS rules are configured.
- if ( !status )
+ if (!status)
{
IpsPolicy* empty_policy = snort::get_empty_ips_policy(p->context->conf);
- if ( empty_policy->policy_id == p->flow->ips_policy_id )
+ if (empty_policy->policy_id == p->flow->ips_policy_id)
{
- if ( PacketTracer::is_active() )
+ if (PacketTracer::is_active())
PacketTracer::log("Whitelisting Flow: FTP data\n");
p->flow->set_ignore_direction(SSN_DIR_BOTH);
}
FTP_DATA_SESSION* data_ssn = fdfd ? &fdfd->session : nullptr;
- if ( !data_ssn or (data_ssn->packet_flags & FTPDATA_FLG_STOP) )
+ if (!data_ssn or (data_ssn->packet_flags & FTPDATA_FLG_STOP))
return 0;
assert(PROTO_IS_FTP_DATA(data_ssn));
// precondition - what we registered for
assert(p->has_tcp_data());
- if ( FileService::get_max_file_depth() < 0 )
+ if (FileService::get_max_file_depth() < 0)
return;
SnortFTPData(p);
p, PktType::TCP, IpProtocol::TCP,
&session->clientIP, session->clientPort,
&session->serverIP, session->serverPort,
- ftp_data_snort_protocol_id, fd);
+ ftp_data_snort_protocol_id, fd, true);
if (result < 0)
{
ip_stats.trackers_created++;
ip_stats.current_frags++;
}
-#ifdef ENABLE_EXPECTED_IP
- if ( Stream::expected_flow(flow, p) )
+ if ( flow->ssn_state.ignore_direction != SSN_DIR_NONE )
{
ip_stats.sessions--; // Incremented in SESSION_STATS_ADD
return false;
}
-#endif
return true;
}
{
assert(flow_con);
- return flow_con->add_expected(
+ return flow_con->add_expected_ignore(
ctrlPkt, type, ip_proto, srcIP, srcPort, dstIP, dstPort, direction, fd);
}
flow_con->prune_one(PruneReason::MEMCAP, false);
}
-bool Stream::expected_flow(Flow* f, Packet* p)
-{
- if ( flow_con )
- return flow_con->expected_flow(f, p) != SSN_DIR_NONE;
- return false;
-}
-
//-------------------------------------------------------------------------
// app proto id foo
//-------------------------------------------------------------------------
const Packet* ctrlPkt, PktType type, IpProtocol ip_proto,
const SfIp* srcIP, uint16_t srcPort,
const SfIp* dstIP, uint16_t dstPort,
- SnortProtocolId snort_protocol_id, FlowData* fd)
+ SnortProtocolId snort_protocol_id, FlowData* fd, bool swap_app_direction)
{
assert(flow_con);
return flow_con->add_expected(
- ctrlPkt, type, ip_proto, srcIP, srcPort, dstIP, dstPort, snort_protocol_id, fd);
+ ctrlPkt, type, ip_proto, srcIP, srcPort, dstIP, dstPort, snort_protocol_id, fd,
+ swap_app_direction);
}
void Stream::set_snort_protocol_id(
// TCP only.
static int set_snort_protocol_id_expected(
const Packet* ctrlPkt, PktType, IpProtocol, const snort::SfIp* srcIP, uint16_t srcPort,
- const snort::SfIp* dstIP, uint16_t dstPort, SnortProtocolId, FlowData*);
+ const snort::SfIp* dstIP, uint16_t dstPort, SnortProtocolId, FlowData*,
+ bool swap_app_direction = false);
// Get pointer to application data for a flow based on the lookup tuples for cases where
// Snort does not have an active packet that is relevant.
if ( Stream::blocked_flow(p) )
return true;
- // FIXIT-L expected flow should be checked by Stream before we get here
- // harmonize this with that and the checks above
- if ( Stream::expected_flow(flow, p) )
+ if ( flow->ssn_state.ignore_direction != SSN_DIR_NONE )
{
server.flush_policy = STREAM_FLPOLICY_IGNORE;
client.flush_policy = STREAM_FLPOLICY_IGNORE;
DataBus::publish(FLOW_STATE_EVENT, p);
- if ( Stream::expected_flow(flow, p) )
+ if ( flow->ssn_state.ignore_direction != SSN_DIR_NONE )
{
udpStats.sessions--; // incremented in SESSIONS_STATS_ADD
return false;
StreamUserConfig* pc = get_user_cfg(flow->ssn_server);
flow->set_default_session_timeout(pc->session_timeout, false);
-#ifdef ENABLE_EXPECTED_USER
- if ( Stream::expected_flow(flow, p) )
+ if ( flow->ssn_state.ignore_direction != SSN_DIR_NONE )
return false;
-#endif
return true;
}