From 908f954d74c5db1931f682e4d11f57dccb01821e Mon Sep 17 00:00:00 2001 From: Russ Combs Date: Mon, 24 Oct 2016 12:27:38 -0400 Subject: [PATCH] refactor rtn checks --- src/detection/CMakeLists.txt | 2 + src/detection/Makefile.am | 2 + src/detection/detect.cc | 404 +-------------------------- src/detection/detect.h | 13 - src/detection/detection_engine.cc | 2 +- src/detection/detection_util.cc | 11 - src/detection/rtn_checks.cc | 440 ++++++++++++++++++++++++++++++ src/detection/rtn_checks.h | 42 +++ src/detection/rules.h | 4 +- src/parser/parse_rule.cc | 7 + 10 files changed, 497 insertions(+), 430 deletions(-) create mode 100644 src/detection/rtn_checks.cc create mode 100644 src/detection/rtn_checks.h diff --git a/src/detection/CMakeLists.txt b/src/detection/CMakeLists.txt index fffbc7202..082edefc3 100644 --- a/src/detection/CMakeLists.txt +++ b/src/detection/CMakeLists.txt @@ -33,6 +33,8 @@ add_library (detection STATIC pattern_match_data.h pcrm.cc pcrm.h + rtn_checks.cc + rtn_checks.h service_map.cc service_map.h sfrim.cc diff --git a/src/detection/Makefile.am b/src/detection/Makefile.am index e8b51bb3a..3366bc21a 100644 --- a/src/detection/Makefile.am +++ b/src/detection/Makefile.am @@ -35,6 +35,8 @@ ips_context.cc \ pattern_match_data.h \ pcrm.cc \ pcrm.h \ +rtn_checks.cc \ +rtn_checks.h \ service_map.cc \ service_map.h \ sfrim.cc \ diff --git a/src/detection/detect.cc b/src/detection/detect.cc index 786d237d8..4cd1f7f7d 100644 --- a/src/detection/detect.cc +++ b/src/detection/detect.cc @@ -46,15 +46,10 @@ #include "detection_defines.h" #include "detection_engine.h" #include "fp_detect.h" +#include "rules.h" #include "tag.h" #include "treenodes.h" -#define CHECK_SRC_IP 0x01 -#define CHECK_DST_IP 0x02 -#define INVERSE 0x04 -#define CHECK_SRC_PORT 0x08 -#define CHECK_DST_PORT 0x10 - THREAD_LOCAL ProfileStats detectPerfStats; THREAD_LOCAL ProfileStats eventqPerfStats; THREAD_LOCAL ProfileStats rebuiltPacketPerfStats; @@ -156,400 +151,3 @@ void check_tags(Packet* p) } } -static int CheckAddrPort( - sfip_var_t* rule_addr, - PortObject* po, - Packet* p, - uint32_t flags, int mode) -{ - const SfIp* pkt_addr; /* packet IP address */ - u_short pkt_port; /* packet port */ - int global_except_addr_flag = 0; /* global exception flag is set */ - int any_port_flag = 0; /* any port flag set */ - int except_port_flag = 0; /* port exception flag set */ - int ip_match = 0; /* flag to indicate addr match made */ - - DebugMessage(DEBUG_DETECT, "CheckAddrPort: "); - /* set up the packet particulars */ - if (mode & CHECK_SRC_IP) - { - pkt_addr = p->ptrs.ip_api.get_src(); - pkt_port = p->ptrs.sp; - - DebugMessage(DEBUG_DETECT,"SRC "); - - if (mode & INVERSE) - { - global_except_addr_flag = flags & EXCEPT_DST_IP; - any_port_flag = flags & ANY_DST_PORT; - except_port_flag = flags & EXCEPT_DST_PORT; - } - else - { - global_except_addr_flag = flags & EXCEPT_SRC_IP; - any_port_flag = flags & ANY_SRC_PORT; - except_port_flag = flags & EXCEPT_SRC_PORT; - } - } - else - { - pkt_addr = p->ptrs.ip_api.get_dst(); - pkt_port = p->ptrs.dp; - - DebugMessage(DEBUG_DETECT, "DST "); - - if (mode & INVERSE) - { - global_except_addr_flag = flags & EXCEPT_SRC_IP; - any_port_flag = flags & ANY_SRC_PORT; - except_port_flag = flags & EXCEPT_SRC_PORT; - } - else - { - global_except_addr_flag = flags & EXCEPT_DST_IP; - any_port_flag = flags & ANY_DST_PORT; - except_port_flag = flags & EXCEPT_DST_PORT; - } - } - - DebugFormat(DEBUG_DETECT, "addr %s, port %d ", pkt_addr->ntoa(), pkt_port); - - if (!rule_addr) - goto bail; - - if (!(global_except_addr_flag)) /*modeled after Check{Src,Dst}IP function*/ - { - if (sfvar_ip_in(rule_addr, pkt_addr)) - ip_match = 1; - } - else - { - DebugMessage(DEBUG_DETECT, ", global exception flag set"); - /* global exception flag is up, we can't match on *any* - * of the source addresses - */ - - if (sfvar_ip_in(rule_addr, pkt_addr)) - return 0; - - ip_match=1; - } - -bail: - if (!ip_match) - { - DebugMessage(DEBUG_DETECT, ", no address match, " - "packet rejected\n"); - return 0; - } - - DebugMessage(DEBUG_DETECT, ", addresses accepted"); - - /* if the any port flag is up, we're all done (success) */ - if (any_port_flag) - { - DebugMessage(DEBUG_DETECT, ", any port match, " - "packet accepted\n"); - return 1; - } - - if (!(mode & (CHECK_SRC_PORT | CHECK_DST_PORT))) - { - return 1; - } - - /* check the packet port against the rule port */ - if ( !PortObjectHasPort(po,pkt_port) ) - { - /* if the exception flag isn't up, fail */ - if (!except_port_flag) - { - DebugMessage(DEBUG_DETECT, ", port mismatch, " - "packet rejected\n"); - return 0; - } - DebugMessage(DEBUG_DETECT, ", port mismatch exception"); - } - else - { - /* if the exception flag is up, fail */ - if (except_port_flag) - { - DebugMessage(DEBUG_DETECT, - ", port match exception, packet rejected\n"); - return 0; - } - DebugMessage(DEBUG_DETECT, ", ports match"); - } - - /* ports and address match */ - DebugMessage(DEBUG_DETECT, ", packet accepted!\n"); - return 1; -} - -#define CHECK_ADDR_SRC_ARGS(x) (x)->src_portobject -#define CHECK_ADDR_DST_ARGS(x) (x)->dst_portobject - -int CheckBidirectional(Packet* p, RuleTreeNode* rtn_idx, - RuleFpList*, int check_ports) -{ - DebugMessage(DEBUG_DETECT, "Checking bidirectional rule...\n"); - - if (CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, - rtn_idx->flags, CHECK_SRC_IP | (check_ports ? CHECK_SRC_PORT : 0))) - { - DebugMessage(DEBUG_DETECT, " Src->Src check passed\n"); - if (!CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, - rtn_idx->flags, CHECK_DST_IP | (check_ports ? CHECK_DST_PORT : 0))) - { - DebugMessage(DEBUG_DETECT, - " Dst->Dst check failed, checking inverse combination\n"); - if (CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, - rtn_idx->flags, (CHECK_SRC_IP | INVERSE | (check_ports ? CHECK_SRC_PORT : 0)))) - { - DebugMessage(DEBUG_DETECT, - " Inverse Dst->Src check passed\n"); - if (!CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, - rtn_idx->flags, (CHECK_DST_IP | INVERSE | (check_ports ? CHECK_DST_PORT : 0)))) - { - DebugMessage(DEBUG_DETECT, - " Inverse Src->Dst check failed\n"); - return 0; - } - else - { - DebugMessage(DEBUG_DETECT, "Inverse addr/port match\n"); - } - } - else - { - DebugMessage(DEBUG_DETECT, " Inverse Dst->Src check failed," - " trying next rule\n"); - return 0; - } - } - else - { - DebugMessage(DEBUG_DETECT, "dest IP/port match\n"); - } - } - else - { - DebugMessage(DEBUG_DETECT, - " Src->Src check failed, trying inverse test\n"); - if (CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, - rtn_idx->flags, CHECK_SRC_IP | INVERSE | (check_ports ? CHECK_SRC_PORT : 0))) - { - DebugMessage(DEBUG_DETECT, - " Dst->Src check passed\n"); - - if (!CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, - rtn_idx->flags, CHECK_DST_IP | INVERSE | (check_ports ? CHECK_DST_PORT : 0))) - { - DebugMessage(DEBUG_DETECT, - " Src->Dst check failed\n"); - return 0; - } - else - { - DebugMessage(DEBUG_DETECT, - "Inverse addr/port match\n"); - } - } - else - { - DebugMessage(DEBUG_DETECT," Inverse test failed, " - "testing next rule...\n"); - return 0; - } - } - - DebugMessage(DEBUG_DETECT," Bidirectional success!\n"); - return 1; -} - -/**************************************************************************** - * - * Function: CheckSrcIp(Packet *, RuleTreeNode *, RuleFpList *) - * - * Purpose: Test the source IP and see if it equals the SIP of the packet - * - * Arguments: p => ptr to the decoded packet data structure - * rtn_idx => ptr to the current rule data struct - * fp_list => ptr to the current function pointer node - * - * Returns: 0 on failure (no match), 1 on success (match) - * - ***************************************************************************/ -int CheckSrcIP(Packet* p, RuleTreeNode* rtn_idx, RuleFpList* fp_list, int check_ports) -{ - DebugMessage(DEBUG_DETECT,"CheckSrcIPEqual: "); - - if (!(rtn_idx->flags & EXCEPT_SRC_IP)) - { - if ( sfvar_ip_in(rtn_idx->sip, p->ptrs.ip_api.get_src()) ) - { - /* the packet matches this test, proceed to the next test */ - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - } - else - { - /* global exception flag is up, we can't match on *any* - * of the source addresses - */ - DebugMessage(DEBUG_DETECT," global exception flag, \n"); - - if ( sfvar_ip_in(rtn_idx->sip, p->ptrs.ip_api.get_src()) ) - return 0; - - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - - DebugMessage(DEBUG_DETECT," Mismatch on SIP\n"); - - /* return 0 on a failed test */ - return 0; -} - -/**************************************************************************** - * - * Function: CheckDstIp(Packet *, RuleTreeNode *, RuleFpList *) - * - * Purpose: Test the dest IP and see if it equals the DIP of the packet - * - * Arguments: p => ptr to the decoded packet data structure - * rtn_idx => ptr to the current rule data struct - * fp_list => ptr to the current function pointer node - * - * Returns: 0 on failure (no match), 1 on success (match) - * - ***************************************************************************/ -int CheckDstIP(Packet* p, RuleTreeNode* rtn_idx, RuleFpList* fp_list, int check_ports) -{ - DebugMessage(DEBUG_DETECT, "CheckDstIPEqual: "); - - if (!(rtn_idx->flags & EXCEPT_DST_IP)) - { - if ( sfvar_ip_in(rtn_idx->dip, p->ptrs.ip_api.get_dst()) ) - { - /* the packet matches this test, proceed to the next test */ - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - } - else - { - /* global exception flag is up, we can't match on *any* - * of the source addresses */ - DebugMessage(DEBUG_DETECT," global exception flag, \n"); - - if ( sfvar_ip_in(rtn_idx->dip, p->ptrs.ip_api.get_dst()) ) - return 0; - - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - - return 0; -} - -int CheckSrcPortEqual(Packet* p, RuleTreeNode* rtn_idx, - RuleFpList* fp_list, int check_ports) -{ - DebugMessage(DEBUG_DETECT,"CheckSrcPortEqual: "); - - /* Check if attributes provided match earlier */ - if (check_ports == 0) - { - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - if ( PortObjectHasPort(rtn_idx->src_portobject,p->ptrs.sp) ) - { - DebugMessage(DEBUG_DETECT, " SP match!\n"); - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - else - { - DebugMessage(DEBUG_DETECT, " SP mismatch!\n"); - } - - return 0; -} - -int CheckSrcPortNotEq(Packet* p, RuleTreeNode* rtn_idx, - RuleFpList* fp_list, int check_ports) -{ - DebugMessage(DEBUG_DETECT,"CheckSrcPortNotEq: "); - - /* Check if attributes provided match earlier */ - if (check_ports == 0) - { - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - if ( !PortObjectHasPort(rtn_idx->src_portobject,p->ptrs.sp) ) - { - DebugMessage(DEBUG_DETECT, " !SP match!\n"); - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - else - { - DebugMessage(DEBUG_DETECT, " !SP mismatch!\n"); - } - - return 0; -} - -int CheckDstPortEqual(Packet* p, RuleTreeNode* rtn_idx, - RuleFpList* fp_list, int check_ports) -{ - DebugMessage(DEBUG_DETECT,"CheckDstPortEqual: "); - - /* Check if attributes provided match earlier */ - if (check_ports == 0) - { - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - if ( PortObjectHasPort(rtn_idx->dst_portobject,p->ptrs.dp) ) - { - DebugMessage(DEBUG_DETECT, " DP match!\n"); - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - else - { - DebugMessage(DEBUG_DETECT," DP mismatch!\n"); - } - return 0; -} - -int CheckDstPortNotEq(Packet* p, RuleTreeNode* rtn_idx, - RuleFpList* fp_list, int check_ports) -{ - DebugMessage(DEBUG_DETECT,"CheckDstPortNotEq: "); - - /* Check if attributes provided match earlier */ - if (check_ports == 0) - { - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - if ( !PortObjectHasPort(rtn_idx->dst_portobject,p->ptrs.dp) ) - { - DebugMessage(DEBUG_DETECT, " !DP match!\n"); - return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); - } - else - { - DebugMessage(DEBUG_DETECT," !DP mismatch!\n"); - } - - return 0; -} - -int RuleListEnd(Packet*, RuleTreeNode*, RuleFpList*, int) -{ - return 1; -} - -int OptListEnd(void*, Cursor&, Packet*) -{ - return DETECTION_OPTION_MATCH; -} - diff --git a/src/detection/detect.h b/src/detection/detect.h index 4fe11ad64..f6ef5dc48 100644 --- a/src/detection/detect.h +++ b/src/detection/detect.h @@ -38,19 +38,6 @@ extern THREAD_LOCAL ProfileStats rebuiltPacketPerfStats; void snort_ignore(Packet*); void snort_log(Packet*); -// parsing -int RuleListEnd(Packet*, RuleTreeNode*, RuleFpList*, int); -int OptListEnd(void* option_data, class Cursor&, Packet*); - -// detection -int CheckBidirectional(Packet*, RuleTreeNode*, RuleFpList*, int); -int CheckSrcIP(Packet*, RuleTreeNode*, RuleFpList*, int); -int CheckDstIP(Packet*, RuleTreeNode*, RuleFpList*, int); -int CheckSrcPortEqual(Packet*, RuleTreeNode*, RuleFpList*, int); -int CheckDstPortEqual(Packet*, RuleTreeNode*, RuleFpList*, int); -int CheckSrcPortNotEq(Packet*, RuleTreeNode*, RuleFpList*, int); -int CheckDstPortNotEq(Packet*, RuleTreeNode*, RuleFpList*, int); - // alerts void CallLogFuncs(Packet*, ListHead*, Event*, const char*); void CallLogFuncs(Packet*, const OptTreeNode*, ListHead*); diff --git a/src/detection/detection_engine.cc b/src/detection/detection_engine.cc index 6eedf01d0..193f160f6 100644 --- a/src/detection/detection_engine.cc +++ b/src/detection/detection_engine.cc @@ -278,7 +278,7 @@ int DetectionEngine::queue_event(const OptTreeNode* otn) return 0; } -int DetectionEngine::queue_event(uint32_t gid, uint32_t sid, RuleType type) +int DetectionEngine::queue_event(unsigned gid, unsigned sid, RuleType type) { OptTreeNode* otn = GetOTN(gid, sid); diff --git a/src/detection/detection_util.cc b/src/detection/detection_util.cc index bfdbb5f7d..11dd70e19 100644 --- a/src/detection/detection_util.cc +++ b/src/detection/detection_util.cc @@ -31,22 +31,11 @@ #include "treenodes.h" -THREAD_LOCAL DataPointer g_file_data; - #define LOG_CHARS 16 static THREAD_LOCAL TextLog* tlog = NULL; static THREAD_LOCAL unsigned nEvents = 0; -SO_PUBLIC DataPointer& get_file_data() -{ return g_file_data; } - -SO_PUBLIC void set_file_data(uint8_t* p, unsigned n) -{ - g_file_data.data = p; - g_file_data.len = n; -} - static void LogBuffer(const char* s, const uint8_t* p, unsigned n) { char hex[(3*LOG_CHARS)+1]; diff --git a/src/detection/rtn_checks.cc b/src/detection/rtn_checks.cc new file mode 100644 index 000000000..03c15f1ec --- /dev/null +++ b/src/detection/rtn_checks.cc @@ -0,0 +1,440 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2014-2016 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2002-2013 Sourcefire, Inc. +// Copyright (C) 1998-2002 Martin Roesch +// +// 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. +//-------------------------------------------------------------------------- + +// rtn_checks.cc is part of work originally done by: +// +// Dan Roelker +// Marc Norton + +#include "rtn_checks.h" + +#include "main/snort_debug.h" +#include "ports/port_object.h" +#include "protocols/packet.h" +#include "sfip/sf_ip.h" +#include "sfip/sf_ipvar.h" + +#include "detection_defines.h" +#include "rules.h" +#include "treenodes.h" + +#define CHECK_SRC_IP 0x01 +#define CHECK_DST_IP 0x02 +#define INVERSE 0x04 +#define CHECK_SRC_PORT 0x08 +#define CHECK_DST_PORT 0x10 + +static int CheckAddrPort( + sfip_var_t* rule_addr, + PortObject* po, + Packet* p, + uint32_t flags, int mode) +{ + const SfIp* pkt_addr; /* packet IP address */ + u_short pkt_port; /* packet port */ + int global_except_addr_flag = 0; /* global exception flag is set */ + int any_port_flag = 0; /* any port flag set */ + int except_port_flag = 0; /* port exception flag set */ + int ip_match = 0; /* flag to indicate addr match made */ + + DebugMessage(DEBUG_DETECT, "CheckAddrPort: "); + /* set up the packet particulars */ + if (mode & CHECK_SRC_IP) + { + pkt_addr = p->ptrs.ip_api.get_src(); + pkt_port = p->ptrs.sp; + + DebugMessage(DEBUG_DETECT,"SRC "); + + if (mode & INVERSE) + { + global_except_addr_flag = flags & EXCEPT_DST_IP; + any_port_flag = flags & ANY_DST_PORT; + except_port_flag = flags & EXCEPT_DST_PORT; + } + else + { + global_except_addr_flag = flags & EXCEPT_SRC_IP; + any_port_flag = flags & ANY_SRC_PORT; + except_port_flag = flags & EXCEPT_SRC_PORT; + } + } + else + { + pkt_addr = p->ptrs.ip_api.get_dst(); + pkt_port = p->ptrs.dp; + + DebugMessage(DEBUG_DETECT, "DST "); + + if (mode & INVERSE) + { + global_except_addr_flag = flags & EXCEPT_SRC_IP; + any_port_flag = flags & ANY_SRC_PORT; + except_port_flag = flags & EXCEPT_SRC_PORT; + } + else + { + global_except_addr_flag = flags & EXCEPT_DST_IP; + any_port_flag = flags & ANY_DST_PORT; + except_port_flag = flags & EXCEPT_DST_PORT; + } + } + + DebugFormat(DEBUG_DETECT, "addr %s, port %d ", sfip_to_str(pkt_addr), pkt_port); + + if (!rule_addr) + goto bail; + + if (!(global_except_addr_flag)) /*modeled after Check{Src,Dst}IP function*/ + { + if (sfvar_ip_in(rule_addr, pkt_addr)) + ip_match = 1; + } + else + { + DebugMessage(DEBUG_DETECT, ", global exception flag set"); + /* global exception flag is up, we can't match on *any* + * of the source addresses + */ + + if (sfvar_ip_in(rule_addr, pkt_addr)) + return 0; + + ip_match=1; + } + +bail: + if (!ip_match) + { + DebugMessage(DEBUG_DETECT, ", no address match, " + "packet rejected\n"); + return 0; + } + + DebugMessage(DEBUG_DETECT, ", addresses accepted"); + + /* if the any port flag is up, we're all done (success) */ + if (any_port_flag) + { + DebugMessage(DEBUG_DETECT, ", any port match, " + "packet accepted\n"); + return 1; + } + + if (!(mode & (CHECK_SRC_PORT | CHECK_DST_PORT))) + { + return 1; + } + + /* check the packet port against the rule port */ + if ( !PortObjectHasPort(po,pkt_port) ) + { + /* if the exception flag isn't up, fail */ + if (!except_port_flag) + { + DebugMessage(DEBUG_DETECT, ", port mismatch, " + "packet rejected\n"); + return 0; + } + DebugMessage(DEBUG_DETECT, ", port mismatch exception"); + } + else + { + /* if the exception flag is up, fail */ + if (except_port_flag) + { + DebugMessage(DEBUG_DETECT, + ", port match exception, packet rejected\n"); + return 0; + } + DebugMessage(DEBUG_DETECT, ", ports match"); + } + + /* ports and address match */ + DebugMessage(DEBUG_DETECT, ", packet accepted!\n"); + return 1; +} + +#define CHECK_ADDR_SRC_ARGS(x) (x)->src_portobject +#define CHECK_ADDR_DST_ARGS(x) (x)->dst_portobject + +int CheckBidirectional(Packet* p, RuleTreeNode* rtn_idx, + RuleFpList*, int check_ports) +{ + DebugMessage(DEBUG_DETECT, "Checking bidirectional rule...\n"); + + if (CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, + rtn_idx->flags, CHECK_SRC_IP | (check_ports ? CHECK_SRC_PORT : 0))) + { + DebugMessage(DEBUG_DETECT, " Src->Src check passed\n"); + if (!CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, + rtn_idx->flags, CHECK_DST_IP | (check_ports ? CHECK_DST_PORT : 0))) + { + DebugMessage(DEBUG_DETECT, + " Dst->Dst check failed, checking inverse combination\n"); + if (CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, + rtn_idx->flags, (CHECK_SRC_IP | INVERSE | (check_ports ? CHECK_SRC_PORT : 0)))) + { + DebugMessage(DEBUG_DETECT, + " Inverse Dst->Src check passed\n"); + if (!CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, + rtn_idx->flags, (CHECK_DST_IP | INVERSE | (check_ports ? CHECK_DST_PORT : 0)))) + { + DebugMessage(DEBUG_DETECT, + " Inverse Src->Dst check failed\n"); + return 0; + } + else + { + DebugMessage(DEBUG_DETECT, "Inverse addr/port match\n"); + } + } + else + { + DebugMessage(DEBUG_DETECT, " Inverse Dst->Src check failed," + " trying next rule\n"); + return 0; + } + } + else + { + DebugMessage(DEBUG_DETECT, "dest IP/port match\n"); + } + } + else + { + DebugMessage(DEBUG_DETECT, + " Src->Src check failed, trying inverse test\n"); + if (CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, + rtn_idx->flags, CHECK_SRC_IP | INVERSE | (check_ports ? CHECK_SRC_PORT : 0))) + { + DebugMessage(DEBUG_DETECT, + " Dst->Src check passed\n"); + + if (!CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, + rtn_idx->flags, CHECK_DST_IP | INVERSE | (check_ports ? CHECK_DST_PORT : 0))) + { + DebugMessage(DEBUG_DETECT, + " Src->Dst check failed\n"); + return 0; + } + else + { + DebugMessage(DEBUG_DETECT, + "Inverse addr/port match\n"); + } + } + else + { + DebugMessage(DEBUG_DETECT," Inverse test failed, " + "testing next rule...\n"); + return 0; + } + } + + DebugMessage(DEBUG_DETECT," Bidirectional success!\n"); + return 1; +} + +/**************************************************************************** + * + * Function: CheckSrcIp(Packet *, RuleTreeNode *, RuleFpList *) + * + * Purpose: Test the source IP and see if it equals the SIP of the packet + * + * Arguments: p => ptr to the decoded packet data structure + * rtn_idx => ptr to the current rule data struct + * fp_list => ptr to the current function pointer node + * + * Returns: 0 on failure (no match), 1 on success (match) + * + ***************************************************************************/ +int CheckSrcIP(Packet* p, RuleTreeNode* rtn_idx, RuleFpList* fp_list, int check_ports) +{ + DebugMessage(DEBUG_DETECT,"CheckSrcIPEqual: "); + + if (!(rtn_idx->flags & EXCEPT_SRC_IP)) + { + if ( sfvar_ip_in(rtn_idx->sip, p->ptrs.ip_api.get_src()) ) + { + /* the packet matches this test, proceed to the next test */ + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + } + else + { + /* global exception flag is up, we can't match on *any* + * of the source addresses + */ + DebugMessage(DEBUG_DETECT," global exception flag, \n"); + + if ( sfvar_ip_in(rtn_idx->sip, p->ptrs.ip_api.get_src()) ) + return 0; + + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + + DebugMessage(DEBUG_DETECT," Mismatch on SIP\n"); + + /* return 0 on a failed test */ + return 0; +} + +/**************************************************************************** + * + * Function: CheckDstIp(Packet *, RuleTreeNode *, RuleFpList *) + * + * Purpose: Test the dest IP and see if it equals the DIP of the packet + * + * Arguments: p => ptr to the decoded packet data structure + * rtn_idx => ptr to the current rule data struct + * fp_list => ptr to the current function pointer node + * + * Returns: 0 on failure (no match), 1 on success (match) + * + ***************************************************************************/ +int CheckDstIP(Packet* p, RuleTreeNode* rtn_idx, RuleFpList* fp_list, int check_ports) +{ + DebugMessage(DEBUG_DETECT, "CheckDstIPEqual: "); + + if (!(rtn_idx->flags & EXCEPT_DST_IP)) + { + if ( sfvar_ip_in(rtn_idx->dip, p->ptrs.ip_api.get_dst()) ) + { + /* the packet matches this test, proceed to the next test */ + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + } + else + { + /* global exception flag is up, we can't match on *any* + * of the source addresses */ + DebugMessage(DEBUG_DETECT," global exception flag, \n"); + + if ( sfvar_ip_in(rtn_idx->dip, p->ptrs.ip_api.get_dst()) ) + return 0; + + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + + return 0; +} + +int CheckSrcPortEqual(Packet* p, RuleTreeNode* rtn_idx, + RuleFpList* fp_list, int check_ports) +{ + DebugMessage(DEBUG_DETECT,"CheckSrcPortEqual: "); + + /* Check if attributes provided match earlier */ + if (check_ports == 0) + { + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + if ( PortObjectHasPort(rtn_idx->src_portobject,p->ptrs.sp) ) + { + DebugMessage(DEBUG_DETECT, " SP match!\n"); + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + else + { + DebugMessage(DEBUG_DETECT, " SP mismatch!\n"); + } + + return 0; +} + +int CheckSrcPortNotEq(Packet* p, RuleTreeNode* rtn_idx, + RuleFpList* fp_list, int check_ports) +{ + DebugMessage(DEBUG_DETECT,"CheckSrcPortNotEq: "); + + /* Check if attributes provided match earlier */ + if (check_ports == 0) + { + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + if ( !PortObjectHasPort(rtn_idx->src_portobject,p->ptrs.sp) ) + { + DebugMessage(DEBUG_DETECT, " !SP match!\n"); + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + else + { + DebugMessage(DEBUG_DETECT, " !SP mismatch!\n"); + } + + return 0; +} + +int CheckDstPortEqual(Packet* p, RuleTreeNode* rtn_idx, + RuleFpList* fp_list, int check_ports) +{ + DebugMessage(DEBUG_DETECT,"CheckDstPortEqual: "); + + /* Check if attributes provided match earlier */ + if (check_ports == 0) + { + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + if ( PortObjectHasPort(rtn_idx->dst_portobject,p->ptrs.dp) ) + { + DebugMessage(DEBUG_DETECT, " DP match!\n"); + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + else + { + DebugMessage(DEBUG_DETECT," DP mismatch!\n"); + } + return 0; +} + +int CheckDstPortNotEq(Packet* p, RuleTreeNode* rtn_idx, + RuleFpList* fp_list, int check_ports) +{ + DebugMessage(DEBUG_DETECT,"CheckDstPortNotEq: "); + + /* Check if attributes provided match earlier */ + if (check_ports == 0) + { + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + if ( !PortObjectHasPort(rtn_idx->dst_portobject,p->ptrs.dp) ) + { + DebugMessage(DEBUG_DETECT, " !DP match!\n"); + return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); + } + else + { + DebugMessage(DEBUG_DETECT," !DP mismatch!\n"); + } + + return 0; +} + +int RuleListEnd(Packet*, RuleTreeNode*, RuleFpList*, int) +{ + return 1; +} + +int OptListEnd(void*, Cursor&, Packet*) +{ + return DETECTION_OPTION_MATCH; +} + diff --git a/src/detection/rtn_checks.h b/src/detection/rtn_checks.h new file mode 100644 index 000000000..ddd724895 --- /dev/null +++ b/src/detection/rtn_checks.h @@ -0,0 +1,42 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2014-2016 Cisco and/or its affiliates. All rights reserved. +// Copyright (C) 2002-2013 Sourcefire, Inc. +// Copyright (C) 1998-2002 Martin Roesch +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- + +#ifndef RTN_CHECKS_H +#define RTN_CHECKS_H + +struct Packet; +struct RuleFpList; +struct RuleTreeNode; + +// parsing +int RuleListEnd(Packet*, RuleTreeNode*, RuleFpList*, int); +int OptListEnd(void* option_data, class Cursor&, Packet*); + +// detection +int CheckBidirectional(Packet*, RuleTreeNode*, RuleFpList*, int); +int CheckSrcIP(Packet*, RuleTreeNode*, RuleFpList*, int); +int CheckDstIP(Packet*, RuleTreeNode*, RuleFpList*, int); +int CheckSrcPortEqual(Packet*, RuleTreeNode*, RuleFpList*, int); +int CheckDstPortEqual(Packet*, RuleTreeNode*, RuleFpList*, int); +int CheckSrcPortNotEq(Packet*, RuleTreeNode*, RuleFpList*, int); +int CheckDstPortNotEq(Packet*, RuleTreeNode*, RuleFpList*, int); + +#endif + diff --git a/src/detection/rules.h b/src/detection/rules.h index 38da7196d..e3de23664 100644 --- a/src/detection/rules.h +++ b/src/detection/rules.h @@ -26,8 +26,8 @@ #include "actions/actions.h" -#define EXCEPT_SRC_IP 0x0001 -#define EXCEPT_DST_IP 0x0002 +#define EXCEPT_SRC_IP 0x0001 // FIXIT-L checked but not set, same as 2.X +#define EXCEPT_DST_IP 0x0002 // FIXIT-L checked but not set, same as 2.X #define ANY_SRC_PORT 0x0004 #define ANY_DST_PORT 0x0008 #define ANY_FLAGS 0x0010 diff --git a/src/parser/parse_rule.cc b/src/parser/parse_rule.cc index ea4ed0449..dad8d1584 100644 --- a/src/parser/parse_rule.cc +++ b/src/parser/parse_rule.cc @@ -26,6 +26,7 @@ #include "detection/detect.h" #include "detection/fp_config.h" #include "detection/fp_utils.h" +#include "detection/rtn_checks.h" #include "detection/treenodes.h" #include "framework/decode_data.h" #include "log/messages.h" @@ -44,6 +45,12 @@ #include "parse_conf.h" #include "parse_ports.h" +#include "parser.h" +#include "cmd_line.h" +#include "config_file.h" +#include "parse_conf.h" +#include "parse_ports.h" + #define SRC 0 #define DST 1 -- 2.47.2