]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Squashed commit of the following:
authorRuss Combs <rucombs@cisco.com>
Wed, 1 Jul 2015 22:01:18 +0000 (18:01 -0400)
committerRuss Combs <rucombs@cisco.com>
Wed, 1 Jul 2015 22:01:18 +0000 (18:01 -0400)
commit 510940569cf8f66668e7265ee004c7fa4127ee00
Author: Russ Combs <rucombs@cisco.com>
Date:   Thu Jun 25 23:33:05 2015 -0400

    fixed duplicate patterns in file_magic.lua
    warn about rules with no fast pattern
    run fast patterns according to packet type
    tweak shutdown output
    add slow search count; match alert service ports
    binder sets service from gadget if not set
    allow abbreviated rule headers
    split file / user protos
    eliminate need for MAX_PROTOCOL_ORDINAL; vectorize sopg_table_t
    warn if file rule has no file_data fp
    add legacy mode warning
    split raw vs cooked counts
    limit detection of service file data
    default to not inspect stream inserts
    valgrind cleanup for smtp and misc
    fix up mail leaks
    fix cmake build on linux w/o asciidoc

47 files changed:
doc/CMakeLists.txt
lua/file_magic.lua
src/detection/detection_options.cc
src/detection/fp_config.cc
src/detection/fp_config.h
src/detection/fp_create.cc
src/detection/fp_create.h
src/detection/fp_detect.cc
src/detection/pcrm.cc
src/detection/pcrm.h
src/detection/service_map.cc
src/detection/service_map.h
src/file_api/file_mime_process.cc
src/file_api/file_mime_process.h
src/file_api/file_service.cc
src/file_api/file_stats.cc
src/file_api/file_stats.h
src/file_api/libs/file_identifier.cc
src/file_api/libs/file_identifier.h
src/ips_options/ips_flow.cc
src/main/modules.cc
src/main/snort_config.h
src/managers/inspector_manager.cc
src/network_inspectors/binder/binder.cc
src/parser/parse_conf.cc
src/parser/parse_rule.cc
src/parser/parse_stream.cc
src/ports/port_object2.cc
src/search_engines/bnfa_search.cc
src/service_inspectors/CMakeLists.txt
src/service_inspectors/http_inspect/hi_main.cc
src/service_inspectors/http_inspect/hi_paf.cc
src/service_inspectors/imap/imap.cc
src/service_inspectors/imap/imap.h
src/service_inspectors/pop/pop.cc
src/service_inspectors/pop/pop.h
src/service_inspectors/smtp/smtp.cc
src/service_inspectors/smtp/smtp.h
src/service_inspectors/smtp/smtp_module.cc
src/stream/stream.h
src/stream/tcp/tcp_session.cc
src/target_based/snort_protocols.cc
src/target_based/snort_protocols.h
src/utils/sf_email_attach_decode.cc
src/utils/sf_email_attach_decode.h
src/utils/stats.cc
src/utils/stats.h

index 36b01aa45758377d984ff82382141b12110fd1d0..8932e41f1d479dced3bb33d0b5082b4f9d0ec4df 100644 (file)
@@ -30,14 +30,6 @@ set (MODULE_SOURCES
     logger.txt
 )
 
-set(BUILT_SOURCES
-    ${HELP_SOURCES}
-    ${LIST_SOURCES}
-    ${MODULE_SOURCES}
-#   version.txt         Requires special formatting. manually added below.
-#   config_changes.txt  If ruby executable found
-)
-
 set (UNBUILT_SOURCES
     daq.txt
     differences.txt
@@ -60,12 +52,22 @@ set (UNBUILT_SOURCES
 #   config_changes.txt  If ruby executable is not found
 )
 
-set (EXTRA_SOURCES
-    ${BUILT_SOURCES}
-    config_changes.txt
-    snort2lua_cmds.txt
-    version.txt
-)
+if (MAKE_PDF_DOC OR MAKE_HTML_DOC OR MAKE_TEXT_DOC)
+    set(BUILT_SOURCES
+        ${HELP_SOURCES}
+        ${LIST_SOURCES}
+        ${MODULE_SOURCES}
+    #   version.txt         Requires special formatting. manually added below.
+    #   config_changes.txt  If ruby executable found
+    )
+
+    set (EXTRA_SOURCES
+        ${BUILT_SOURCES}
+        config_changes.txt
+        snort2lua_cmds.txt
+        version.txt
+    )
+endif()
 
 if (MAKE_HTML_DOC)
     set(HTML_DOCS snort_manual.html)
index 9d648f2c4d43e20018de5737c3051d74fb3ce970..96ecb991616efdd1968d8d53f550e3530d2af475 100644 (file)
@@ -205,9 +205,6 @@ file_magic =
     { type = "FLV", id = 74, category = "Multimedia", rev = 1,
       magic = { { content = "| 46 4C 56 01 |",offset = 0 } } },
 
-    { type = "WAV", id = 75, category = "Multimedia", rev = 1,
-      magic = { { content = "| 52 49 46 58 |",offset = 0 } } },
-
     { type = "WAV", id = 76, category = "Multimedia", rev = 1,
       magic = { { content = "| 62 65 61 74 |",offset = 0 } } },
 
@@ -343,9 +340,6 @@ file_magic =
     { type = "DWG", id = 130, category = "Graphics", rev = 1,
       magic = { { content = "| 41 43 31 30 |",offset = 0 } } },
 
-    { type = "ISO", id = 131, category = "System files", rev = 1,
-      magic = { { content = "| 00 00 01 BA |",offset = 0 } } },
-
     { type = "MDI", id = 132, category = "Office Documents", rev = 1,
       magic = { { content = "| 45 50 |",offset = 0 } } },
 
@@ -373,9 +367,6 @@ file_magic =
     { type = "ONE", id = 140, category = "Office Documents", rev = 1,
       magic = { { content = "| E4 52 5C 7B 8C D8 A7 4D AE B1 53 78 D0 29 96 D3 |",offset = 0 } } },
 
-    { type = "MP4", id = 141, category = "Multimedia", rev = 1,
-      magic = { { content = "| 00 00 00 18 66 74 79 70 33 67 70 35 |",offset = 0 } } },
-
     { type = "MP4", id = 142, category = "Multimedia", rev = 1,
       magic = { { content = "| 00 00 00 14 66 74 79 70 69 73 6F 6D |",offset = 0 } } },
 
index 920a25fe500f04b5a20ad8cbec5cbdd5b82fd8c9..ae8954c3c01f4a602cc4d470bf7f4d0ea7ff631d 100644 (file)
@@ -459,14 +459,15 @@ int detection_option_node_evaluate(
             if (pmd)
                 pattern_size = pmd->pattern_size;
 
-            if (eval_data->p->application_protocol_ordinal != 0)
+            if ( eval_data->p->application_protocol_ordinal and
+                ((OTNX_MATCH_DATA*)(eval_data->pomd))->check_ports != 2 )
             {
                 for (svc_idx = 0; svc_idx < otn->sigInfo.num_services; svc_idx++)
                 {
                     if (eval_data->p->application_protocol_ordinal ==
                         otn->sigInfo.services[svc_idx].service_ordinal)
                     {
-                        check_ports = 0;  // FIXIT need to check for alert service
+                        check_ports = 0;
                         break;  /* out of for */
                     }
                 }
index 4f0a5acbcb000e0a2adfbb4f4cdfc153d11b1607..65474ceafce7e91a1be1b459aad9985d106b4c97 100644 (file)
@@ -38,7 +38,7 @@ FastPatternConfig::FastPatternConfig()
 {
     memset(this, 0, sizeof(*this));
 
-    inspect_stream_insert = 1;
+    inspect_stream_insert = false;
     max_queue_events = 5;
     bleedover_port_limit = 1024;
 
@@ -48,8 +48,7 @@ FastPatternConfig::FastPatternConfig()
 }
 
 FastPatternConfig::~FastPatternConfig()
-{
-}
+{ }
 
 int FastPatternConfig::set_detect_search_method(const char* method)
 {
index 44dfc2782daf07c675a885eb58c63c1b088d615b..1ccf67c9e40999fd563778f3254e372bfc4cb762 100644 (file)
@@ -153,7 +153,6 @@ private:
     unsigned bleedover_port_limit;
 
     int search_opt;
-    int search_method_verbose;
     int portlists_flags;
     int max_pattern_len;
     int num_patterns_truncated;  // due to max_pattern_len
index b2d6bc06b76adc3b926fd011d40b3265db84cc21..f6c931fdd9d013d28d371edf04286fa0be0495f4 100644 (file)
@@ -68,6 +68,8 @@
 #include "search/intel_soft_cpm.h"
 #endif
 
+static unsigned mpse_count = 0;
+
 static void fpDeletePMX(void* data);
 
 static int fpGetFinalPattern(FastPatternConfig*, PatternMatchData* pmd,
@@ -493,6 +495,7 @@ bool set_fp_content(OptTreeNode* otn)
     CursorActionType curr_cat = CAT_SET_RAW;
     FpFoo best;
     PatternMatchData* pmd = nullptr;
+    bool content = false;
     bool fp_only = true;
 
     for (ofl = otn->opt_func; ofl != NULL; ofl = ofl->next)
@@ -511,6 +514,7 @@ bool set_fp_content(OptTreeNode* otn)
         if ( ofl->type != RULE_OPTION_TYPE_CONTENT )
             continue;
 
+        content = true;
         PatternMatchData* tmp = get_pmd(ofl);
         assert(tmp);
 
@@ -542,9 +546,28 @@ bool set_fp_content(OptTreeNode* otn)
             best = curr;
     }
     if ( !pmd && best.pmd )
-        best.pmd->fp = 1;
+    {
+        pmd = best.pmd;
+        pmd->fp = 1;
+    }
+
+    if ( best.pmd and otn->proto == SNORT_PROTO_FILE and best.cat != CAT_SET_FILE )
+    {
+        ParseWarning(WARN_RULES, "file rule %d:%d does not have file_data fast pattern",
+            otn->sigInfo.generator, otn->sigInfo.id);
+
+        best.pmd->fp = 0;
+        return false;
+    }
+
+    if ( pmd )
+        return true;
 
-    return pmd or best.pmd;
+    if ( content )
+        ParseWarning(WARN_RULES, "content based rule %d:%d has no fast pattern",
+            otn->sigInfo.generator, otn->sigInfo.id);
+
+    return false;
 }
 
 static PatternMatchData* get_fp_content(OptTreeNode* otn, OptFpList*& next)
@@ -616,6 +639,8 @@ static int fpFinishPortGroupRule(
                 ParseError("Failed to create pattern matcher for %d\n", pmd->pm_type);
                 return -1;
             }
+            mpse_count++;
+
             if ( fp->get_search_opt() )
                 pg->mpse[pmd->pm_type]->set_opt(1);
         }
@@ -911,12 +936,6 @@ static int fpCreateRuleMaps(SnortConfig* sc, RulePortTables* p)
     if (fpCreateInitRuleMap(sc->prmUdpRTNX, p->udp.src, p->udp.dst, p->udp.any))
         return -1;
 
-    if ( !(sc->prmSvcRTNX = prmNewMap()) )
-        return -1;
-
-    if (fpCreateInitRuleMap(sc->prmSvcRTNX, nullptr, nullptr, p->svc_any))
-        return -1;
-
     return 0;
 }
 
@@ -948,12 +967,6 @@ static void fpFreeRuleMaps(SnortConfig* sc)
         free(sc->prmUdpRTNX);
         sc->prmUdpRTNX = NULL;
     }
-
-    if (sc->prmSvcRTNX != NULL)
-    {
-        free(sc->prmSvcRTNX);
-        sc->prmUdpRTNX = NULL;
-    }
 }
 
 static int fpGetFinalPattern(
@@ -1508,7 +1521,7 @@ static void fpBuildServicePortGroupByServiceOtnList(
  *
  */
 static void fpBuildServicePortGroups(
-    SnortConfig* sc, SFGHASH* spg, PortGroup** sopg, SFGHASH* srm, FastPatternConfig* fp)
+    SnortConfig* sc, SFGHASH* spg, PortGroupVector& sopg, SFGHASH* srm, FastPatternConfig* fp)
 {
     SFGHASH_NODE* n;
     char* srvc;
@@ -1520,10 +1533,12 @@ static void fpBuildServicePortGroups(
         n=sfghash_findnext(srm) )
     {
         list = (SF_LIST*)n->data;
+
         if (!list)
             continue;
 
         srvc = (char*)n->key;
+
         if (!srvc)
             continue;
 
@@ -1531,43 +1546,17 @@ static void fpBuildServicePortGroups(
 
         /* Add this PortGroup to the protocol-ordinal -> port_group table */
         pg = (PortGroup*)sfghash_find(spg, srvc);
-        if ( pg )
-        {
-            int16_t id;
-            id = FindProtocolReference(srvc);
-
-            if (id==SFTARGET_UNKNOWN_PROTOCOL)
-            {
-                id = AddProtocolReference(srvc);
-
-                if (id <=0 )
-                    FatalError("Could not AddProtocolReference\n");
 
-                else if ( id >= MAX_PROTOCOL_ORDINAL )
-                    ParseWarning(WARN_RULES, "protocol-ordinal=%d exceeds "
-                        "limit of %d for service=%s\n",id,MAX_PROTOCOL_ORDINAL,srvc);
-            }
-            else if ( id > 0 )
-            {
-                if ( id < MAX_PROTOCOL_ORDINAL )
-                {
-                    //LogMessage("adding protocol-ordinal=%d as service=%s\n",id,srvc);
-                    sopg[ id ] = pg;
-                }
-                else
-                    ParseError("protocol-ordinal=%d exceeds "
-                        "limit of %d for service=%s\n",id,MAX_PROTOCOL_ORDINAL,srvc);
-            }
-            else /* id < 0 */
-            {
-                ParseError("adding protocol-ordinal=%d for "
-                    "service=%s, can't use that\n",id,srvc);
-            }
-        }
-        else
+        if ( !pg )
         {
             ParseError("*** failed to create and find a port group for '%s'\n",srvc);
+            continue;
         }
+        int16_t id = FindProtocolReference(srvc);
+        assert(id != SFTARGET_UNKNOWN_PROTOCOL);
+
+        assert((unsigned)id < sopg.size());
+        sopg[ id ] = pg;
     }
 }
 
@@ -1579,32 +1568,21 @@ static void fpCreateServiceMapPortGroups(SnortConfig* sc)
     FastPatternConfig* fp = sc->fast_pattern_config;
 
     sc->spgmmTable = ServicePortGroupMapNew();
-    sc->sopgTable = ServicePortGroupTableNew();
-
-    fpBuildServicePortGroups(sc, sc->spgmmTable->ip_to_srv, sc->sopgTable->ip_to_srv,
-        sc->srmmTable->ip_to_srv, fp);
-    fpBuildServicePortGroups(sc, sc->spgmmTable->ip_to_cli, sc->sopgTable->ip_to_srv,
-        sc->srmmTable->ip_to_cli, fp);
-
-    fpBuildServicePortGroups(sc, sc->spgmmTable->icmp_to_srv, sc->sopgTable->icmp_to_srv,
-        sc->srmmTable->icmp_to_srv, fp);
-    fpBuildServicePortGroups(sc, sc->spgmmTable->icmp_to_cli, sc->sopgTable->icmp_to_cli,
-        sc->srmmTable->icmp_to_cli, fp);
-
-    fpBuildServicePortGroups(sc, sc->spgmmTable->tcp_to_srv, sc->sopgTable->tcp_to_srv,
-        sc->srmmTable->tcp_to_srv, fp);
-    fpBuildServicePortGroups(sc, sc->spgmmTable->tcp_to_cli, sc->sopgTable->tcp_to_cli,
-        sc->srmmTable->tcp_to_cli, fp);
-
-    fpBuildServicePortGroups(sc, sc->spgmmTable->udp_to_srv, sc->sopgTable->udp_to_srv,
-        sc->srmmTable->udp_to_srv, fp);
-    fpBuildServicePortGroups(sc, sc->spgmmTable->udp_to_cli, sc->sopgTable->udp_to_cli,
-        sc->srmmTable->udp_to_cli, fp);
-
-    fpBuildServicePortGroups(sc, sc->spgmmTable->svc_to_srv, sc->sopgTable->svc_to_srv,
-        sc->srmmTable->svc_to_srv, fp);
-    fpBuildServicePortGroups(sc, sc->spgmmTable->svc_to_cli, sc->sopgTable->svc_to_cli,
-        sc->srmmTable->svc_to_cli, fp);
+    sc->sopgTable = new sopg_table_t;
+
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
+    {
+        fpBuildServicePortGroups(sc, sc->spgmmTable->to_srv[i],
+            sc->sopgTable->to_srv[i], sc->srmmTable->to_srv[i], fp);
+
+        fpBuildServicePortGroups(sc, sc->spgmmTable->to_cli[i],
+            sc->sopgTable->to_cli[i], sc->srmmTable->to_cli[i], fp);
+    }
+    if ( !sc->sopgTable->set_user_mode() )
+    {
+        fp->set_stream_insert(true);
+        ParseWarning(WARN_RULES, "legacy mode fast pattern searching enabled");
+    }
 }
 
 /*
@@ -1623,7 +1601,7 @@ static void fpPrintRuleList(SF_LIST* list)
     }
 }
 
-static void fpPrintServiceRuleMapTable(SFGHASH* p, const char* msg)
+static void fpPrintServiceRuleMapTable(SFGHASH* p, const char* proto, const char* dir)
 {
     SFGHASH_NODE* n;
 
@@ -1631,7 +1609,9 @@ static void fpPrintServiceRuleMapTable(SFGHASH* p, const char* msg)
         return;
 
     std::string label = "service rule counts - ";
-    label += msg;
+    label += proto;
+    label += " ";
+    label += dir;
     LogLabel(label.c_str());
 
     for ( n = sfghash_findfirst(p);
@@ -1655,20 +1635,12 @@ static void fpPrintServiceRuleMapTable(SFGHASH* p, const char* msg)
 
 static void fpPrintServiceRuleMaps(srmm_table_t* service_map)
 {
-    fpPrintServiceRuleMapTable(service_map->ip_to_srv,   "ip to server");
-    fpPrintServiceRuleMapTable(service_map->ip_to_cli,   "ip to client");
-
-    fpPrintServiceRuleMapTable(service_map->icmp_to_srv, "icmp to server");
-    fpPrintServiceRuleMapTable(service_map->icmp_to_cli, "icmp to client");
-
-    fpPrintServiceRuleMapTable(service_map->tcp_to_srv,  "tcp to server");
-    fpPrintServiceRuleMapTable(service_map->tcp_to_cli,  "tcp to client");
-
-    fpPrintServiceRuleMapTable(service_map->udp_to_srv,  "udp to server");
-    fpPrintServiceRuleMapTable(service_map->udp_to_cli,  "udp to client");
-
-    fpPrintServiceRuleMapTable(service_map->svc_to_srv,  "svc to server");
-    fpPrintServiceRuleMapTable(service_map->svc_to_cli,  "svc to client");
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; ++i )
+    {
+        const char* s = get_protocol_name(i);
+        fpPrintServiceRuleMapTable(service_map->to_srv[i], s, "to server");
+        fpPrintServiceRuleMapTable(service_map->to_cli[i], s, "to client");
+    }
 }
 
 static void fp_print_service_rules(SFGHASH* cli, SFGHASH* srv, const char* msg)
@@ -1706,14 +1678,8 @@ static void fp_print_service_rules(SFGHASH* cli, SFGHASH* srv, const char* msg)
 
 static void fp_print_service_rules_by_proto(srmm_table_t* srmm)
 {
-    // FIXIT-L should these be supported?
-    fp_print_service_rules(srmm->ip_to_srv, srmm->ip_to_cli, "ip");
-    fp_print_service_rules(srmm->icmp_to_srv, srmm->icmp_to_cli, "icmp");
-
-    fp_print_service_rules(srmm->tcp_to_srv, srmm->tcp_to_cli, "tcp");
-    fp_print_service_rules(srmm->udp_to_srv, srmm->udp_to_cli, "udp");
-
-    fp_print_service_rules(srmm->svc_to_srv, srmm->svc_to_cli, "svc");
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; ++i )
+        fp_print_service_rules(srmm->to_srv[i], srmm->to_cli[i], get_protocol_name(i));
 }
 
 static void fp_sum_port_groups(PortGroup* pg, unsigned c[PM_TYPE_MAX])
@@ -1741,20 +1707,11 @@ static void fp_print_service_groups(srmm_table_t* srmm)
     unsigned to_srv[PM_TYPE_MAX] = { 0 };
     unsigned to_cli[PM_TYPE_MAX] = { 0 };
 
-    fp_sum_service_groups(srmm->ip_to_srv, to_srv);
-    fp_sum_service_groups(srmm->ip_to_cli, to_cli);
-
-    fp_sum_service_groups(srmm->icmp_to_srv, to_srv);
-    fp_sum_service_groups(srmm->icmp_to_cli, to_cli);
-
-    fp_sum_service_groups(srmm->tcp_to_srv, to_srv);
-    fp_sum_service_groups(srmm->tcp_to_cli, to_cli);
-
-    fp_sum_service_groups(srmm->udp_to_srv, to_srv);
-    fp_sum_service_groups(srmm->udp_to_cli, to_cli);
-
-    fp_sum_service_groups(srmm->svc_to_srv, to_srv);
-    fp_sum_service_groups(srmm->svc_to_cli, to_cli);
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; ++i )
+    {
+        fp_sum_service_groups(srmm->to_srv[i], to_srv);
+        fp_sum_service_groups(srmm->to_cli[i], to_cli);
+    }
 
     bool label = true;
 
@@ -1857,16 +1814,21 @@ static int fpCreateServicePortGroups(SnortConfig* sc)
 */
 int fpCreateFastPacketDetection(SnortConfig* sc)
 {
-    /* This is somewhat necessary because of how the detection option trees
-     * are added via a callback from the pattern matcher */
-    if ( !get_rule_count() or !sc )
-        return 0;
+    assert(sc);
 
     RulePortTables* port_tables = sc->port_tables;
     FastPatternConfig* fp = sc->fast_pattern_config;
 
-    if ( !port_tables or !fp )
+    assert(port_tables);
+    assert(fp);
+
+    if ( !get_rule_count() )
+    {
+        sc->sopgTable = new sopg_table_t;
         return 0;
+    }
+
+    mpse_count = 0;
 
     MpseManager::start_search_engine(fp->get_search_api());
 
@@ -1907,23 +1869,16 @@ int fpCreateFastPacketDetection(SnortConfig* sc)
     fp_print_port_groups(port_tables);
     fp_print_service_groups(sc->spgmmTable);
 
-    // FIXIT-L cleanup the mpse startup output
-    //LogMessage("\n");
-    //LogMessage("[ Port and Service Based Pattern Matching Memory ]\n" );
+    if ( mpse_count )
+        LogLabel("search engine");
 
-#if 1
-    // FIXIT-L update format of search engine startup foo
-    LogLabel("search engine");
     MpseManager::print_mpse_summary(fp->get_search_api());
 
-    if ( fp->get_max_pattern_len() )
-    {
-        LogMessage("%25.25s: %-12u\n", "max_pattern_len", fp->get_max_pattern_len());
+    if ( fp->get_num_patterns_truncated() )
         LogMessage("%25.25s: %-12u\n", "truncated patterns", fp->get_num_patterns_truncated());
-    }
+
     if ( fp->get_num_patterns_trimmed() )
         LogMessage("%25.25s: %-12u\n", "prefix trims", fp->get_num_patterns_trimmed());
-#endif
 
     MpseManager::setup_search_engine(fp->get_search_api(), sc);
 
@@ -1943,8 +1898,9 @@ void fpDeleteFastPacketDetection(SnortConfig* sc)
 
     ServiceMapFree(sc->srmmTable);
     ServicePortGroupMapFree(sc->spgmmTable);
-    if (sc->sopgTable != NULL)
-        free(sc->sopgTable);
+
+    if ( sc->sopgTable )
+        delete sc->sopgTable;
 }
 
 /*
@@ -1974,15 +1930,11 @@ void fpShowEventStats(SnortConfig* sc)
     LogMessage("\n");
     LogMessage("** UDP Event Stats --\n");
     prmShowEventStats(sc->prmUdpRTNX);
-
-    LogMessage("\n");
-    LogMessage("** SVC Event Stats --\n");
-    prmShowEventStats(sc->prmSvcRTNX);
 }
 
-const char* PatternRawToContent(const char* pattern, int pattern_len)
+static const char* PatternRawToContent(const char* pattern, int pattern_len)
 {
-    static THREAD_LOCAL char content_buf[1024];
+    static char content_buf[1024];
     int max_write_size = sizeof(content_buf) - 64;
     int i, j = 0;
     int hex = 0;
@@ -2063,6 +2015,19 @@ static void PrintFastPatternInfo(OptTreeNode* otn, PatternMatchData* pmd,
     if ((otn == NULL) || (pmd == NULL))
         return;
 
+#if 0
+    std::string hex, txt;
+    char buf[8];
+
+    for ( int i = 0; i < pattern_length; ++i )
+    {
+        snprintf(buf, sizeof(buf), "%2.02X ", (uint8_t)pattern[i]);
+        hex += buf;
+        txt += isprint(pattern[i]) ? pattern[i] : '.';
+
+    }
+    printf("fast pattern[%d] = x%s '%s'\n", pattern_length, hex.c_str(), txt.c_str());
+#else
     LogMessage("%u:%u\n", otn->sigInfo.generator, otn->sigInfo.id);
     LogMessage("  Fast pattern matcher: %s\n", pm_type_strings[pmd->pm_type]);
     LogMessage("  Fast pattern set: %s\n", pmd->fp ? "yes" : "no");
@@ -2103,5 +2068,6 @@ static void PrintFastPatternInfo(OptTreeNode* otn, PatternMatchData* pmd,
 
     LogMessage("  Final pattern\n");
     LogMessage("    %s\n", PatternRawToContent(pattern, pattern_length));
+#endif
 }
 
index 56624c7cfe93df75fb280f9778bc879eb16956a9..c666cd6d2df05033dd0e8d28608f9398b77a50d1 100644 (file)
@@ -66,7 +66,6 @@ void fpWalkOtns(int, OtnWalkFcn);
 void fpDeletePortGroup(void*);
 
 bool set_fp_content(struct OptTreeNode*);
-const char* PatternRawToContent(const char* pattern, int pattern_len);
 
 #endif
 
index b2043e6d51cfdeda01902e3ad3b2e975241eac00..235c3998af4472fbef491808c30cc8d2fcf88b49 100644 (file)
@@ -33,6 +33,7 @@
 **               per session tracking).
 **
 */
+
 #include "fp_detect.h"
 
 #ifdef HAVE_CONFIG_H
 #include "protocols/udp.h"
 #include "protocols/icmp4.h"
 
-/*
-**  Static function prototypes
-*/
-int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports);
-static inline int fpEvalHeaderIp(Packet* p, int ip_proto, OTNX_MATCH_DATA*);
-static inline int fpEvalHeaderIcmp(Packet* p, OTNX_MATCH_DATA*);
-static inline int fpEvalHeaderTcp(Packet* p, OTNX_MATCH_DATA*);
-static inline int fpEvalHeaderUdp(Packet* p, OTNX_MATCH_DATA*);
-static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p,
-    int check_ports, char ip_rule, OTNX_MATCH_DATA*);
-static int rule_tree_match(void* id, void* tree, int index, void* data, void* neg_list);
-static inline int fpAddSessionAlert(Packet* p, OptTreeNode* otn);
-static inline int fpSessionAlerted(Packet* p, OptTreeNode* otn);
-
 #ifdef PERF_PROFILING
 THREAD_LOCAL ProfileStats rulePerfStats;
 THREAD_LOCAL ProfileStats ncrulePerfStats;
@@ -107,10 +94,10 @@ void otnx_match_data_init(int num_rule_types)
 
 void otnx_match_data_term()
 {
-    if (t_omd.matchInfo != NULL)
+    if ( t_omd.matchInfo )
         free(t_omd.matchInfo);
 
-    t_omd.matchInfo = NULL;
+    t_omd.matchInfo = nullptr;
 }
 
 /*
@@ -383,7 +370,7 @@ int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports)
 
     MODULE_PROFILE_START(ruleRTNEvalPerfStats);
 
-    if (rtn == NULL)
+    if ( !rtn )
     {
         MODULE_PROFILE_END(ruleRTNEvalPerfStats);
         return 0;
@@ -503,7 +490,7 @@ static int rule_tree_match(void* id, void* tree, int index, void* data, void* ne
      * may muck with an unintended rule */
 
     /* Set flag for not contents so they aren't evaluated */
-    for (ncl = (NCListNode*)neg_list; ncl != NULL; ncl = ncl->next)
+    for (ncl = (NCListNode*)neg_list; ncl != nullptr; ncl = ncl->next)
     {
         PMX* neg_pmx = (PMX*)ncl->pmx;
         PatternMatchData* neg_pmd = (PatternMatchData*)neg_pmx->PatternMatchData;
@@ -565,7 +552,7 @@ static int rule_tree_match(void* id, void* tree, int index, void* data, void* ne
                 eval_data.p->dsize = eval_data.p->ptrs.ip_api.pay_len();
 
                 /* Recurse, and evaluate with the inner IP */
-                rule_tree_match(id, tree, index, data, NULL);
+                rule_tree_match(id, tree, index, data, nullptr);
             }
             while (layer::set_inner_ip_api(eval_data.p,
                 eval_data.p->ptrs.ip_api,
@@ -637,6 +624,63 @@ static int sortOrderByContentLength(const void* e1, const void* e2)
     return 0;
 }
 
+/*
+**
+**  NAME
+**    fpAddSessionAlert::
+**
+**  DESCRIPTION
+**    This function flags an alert per session.
+**
+**  FORMAL INPUTS
+**    Packet *      - the packet to inspect
+**    OptTreeNode * - the rule that generated the alert
+**
+**  FORMAL OUTPUTS
+**    int - 0 if not flagged
+**          1 if flagged
+**
+*/
+static inline int fpAddSessionAlert(Packet* p, OptTreeNode* otn)
+{
+    if ( !p->flow )
+        return 0;
+
+    if ( !otn )
+        return 0;
+
+    return !stream.add_session_alert(
+        p->flow, p, otn->sigInfo.generator, otn->sigInfo.id);
+}
+
+/*
+**
+**  NAME
+**    fpSessionAlerted::
+**
+**  DESCRIPTION
+**    This function indicates whether or not an alert has been generated previously
+**    in this session, but only if this is a rebuilt packet.
+**
+**  FORMAL INPUTS
+**    Packet *      - the packet to inspect
+**    OptTreeNode * - the rule that generated the alert
+**
+**  FORMAL OUTPUTS
+**    int - 0 if alert NOT previously generated
+**          1 if alert previously generated
+**
+*/
+static inline int fpSessionAlerted(Packet* p, OptTreeNode* otn)
+{
+    SigInfo* si = &otn->sigInfo;
+
+    if (!stream.check_session_alerted(p->flow, p, si->generator, si->id))
+        return 0;
+    else
+        return 1;
+}
+
 /*
 **
 **  NAME
@@ -762,7 +806,7 @@ static inline int fpFinalSelectEvent(OTNX_MATCH_DATA* o, Packet* p)
                 otn = o->matchInfo[i].MatchArray[j];
                 rtn = getRtnFromOtn(otn);
 
-                if ((otn != NULL) && (rtn != NULL) && pass_action(rtn->type))
+                if (otn && rtn && pass_action(rtn->type))
                 {
                     /* Already acted on rules, so just don't act on anymore */
                     if ( tcnt > 0 )
@@ -777,7 +821,7 @@ static inline int fpFinalSelectEvent(OTNX_MATCH_DATA* o, Packet* p)
                 {
                     if (o->matchInfo[i].MatchArray[k] == otn)
                     {
-                        otn = NULL;
+                        otn = nullptr;
                         break;
                     }
                 }
@@ -809,7 +853,7 @@ static inline int fpFinalSelectEvent(OTNX_MATCH_DATA* o, Packet* p)
                 }
 
                 /* only log/count one pass */
-                if ((otn != NULL) && (rtn != NULL) && pass_action(rtn->type))
+                if ( otn && rtn && pass_action(rtn->type))
                 {
                     p->packet_flags |= PKT_PASS_RULE;
                     return 1;
@@ -821,106 +865,10 @@ static inline int fpFinalSelectEvent(OTNX_MATCH_DATA* o, Packet* p)
     return 0;
 }
 
-/*
-**
-**  NAME
-**    fpAddSessionAlert::
-**
-**  DESCRIPTION
-**    This function flags an alert per session.
-**
-**  FORMAL INPUTS
-**    Packet *      - the packet to inspect
-**    OptTreeNode * - the rule that generated the alert
-**
-**  FORMAL OUTPUTS
-**    int - 0 if not flagged
-**          1 if flagged
-**
-*/
-static inline int fpAddSessionAlert(Packet* p, OptTreeNode* otn)
-{
-    if ( !p->flow )
-        return 0;
-
-    if ( !otn )
-        return 0;
-
-    return !stream.add_session_alert(
-        p->flow, p, otn->sigInfo.generator, otn->sigInfo.id);
-}
-
-/*
-**
-**  NAME
-**    fpSessionAlerted::
-**
-**  DESCRIPTION
-**    This function indicates whether or not an alert has been generated previously
-**    in this session, but only if this is a rebuilt packet.
-**
-**  FORMAL INPUTS
-**    Packet *      - the packet to inspect
-**    OptTreeNode * - the rule that generated the alert
-**
-**  FORMAL OUTPUTS
-**    int - 0 if alert NOT previously generated
-**          1 if alert previously generated
-**
-*/
-static inline int fpSessionAlerted(Packet* p, OptTreeNode* otn)
-{
-    SigInfo* si = &otn->sigInfo;
-
-    if (!stream.check_session_alerted(p->flow, p, si->generator, si->id))
-        return 0;
-    else
-        return 1;
-}
-
-#if 0
-Not currently used
-/*
- * Prints an OTN in a simple format with:
- *
- * rule proto: # gid: # sid: # sp: # dp # \n
- */
-void printRuleFmt1(SnortConfig* sc, OptTreeNode* otn)
-{
-    RuleTreeNode* rtn = getParserRtnFromOtn(otn);
-
-    LogMessage("rule proto: ");
-
-    if (      rtn->proto== SNORT_PROTO_TCP     )
-        LogMessage("tcp  ");
-    else if ( rtn->proto== SNORT_PROTO_UDP     )
-        LogMessage("udp  ");
-    else if ( rtn->proto== SNORT_PROTO_ICMP    )
-        LogMessage("icmp ");
-    else if ( rtn->proto== SNORT_PROTO_IP)
-        LogMessage("ip   ");
-
-    LogMessage("gid:%u sid:%5u ", otn->sigInfo.generator,otn->sigInfo.id);
-
-    LogMessage(" sp:");
-
-    fflush(stdout); fflush(stderr);
-    PortObjectPrintPortsRaw(rtn->src_portobject);
-    fflush(stdout); fflush(stderr);
-
-    LogMessage(" dp:");
-
-    PortObjectPrintPortsRaw(rtn->dst_portobject);
-    printf("\n");
-    fflush(stdout); fflush(stderr);
-}
-
-#endif
-
 #ifdef PPM_MGR
 #define CHECK_PPM() \
     if (PPM_PACKET_ABORT_FLAG()) \
-        goto fp_eval_header_sw_reset_ip;
+        return 1;
 #else
 #define CHECK_PPM()
 #endif
@@ -945,6 +893,62 @@ void printRuleFmt1(SnortConfig* sc, OptTreeNode* otn)
     if ( len ) \
         SEARCH_DATA(buf, len, cnt)
 
+static int fp_search(
+    PortGroup* port_group, Packet* p,
+    int check_ports, int type, OTNX_MATCH_DATA* omd)
+{
+    Inspector* gadget = p->flow ? p->flow->gadget : nullptr;
+    InspectionBuffer buf;
+
+    omd->pg = port_group;
+    omd->p = p;
+    omd->check_ports = check_ports;
+
+    bool user_mode = snort_conf->sopgTable->user_mode;
+
+    if ( (!user_mode or type < 2) and p->data and p->dsize )
+    {
+        // ports search raw packet only
+        if ( Mpse* so = port_group->mpse[PM_TYPE_PKT] )
+        {
+            uint16_t pattern_match_size = p->dsize;
+
+            if ( IsLimitedDetect(p) && (p->alt_dsize < p->dsize) )
+                pattern_match_size = p->alt_dsize;
+
+            SEARCH_PACKET(p->data, pattern_match_size, pc.pkt_searches);
+
+            if ( pattern_match_size )
+                p->is_cooked() ?  pc.cooked_searches++ : pc.raw_searches++;
+        }
+    }
+
+    if ( (!user_mode or type == 1) and gadget )
+    {
+        // service searches PDU buffers and file
+        SEARCH_BUFFER(buf.IBT_KEY, PM_TYPE_KEY, pc.key_searches);
+        SEARCH_BUFFER(buf.IBT_HEADER, PM_TYPE_HEADER, pc.header_searches);
+        SEARCH_BUFFER(buf.IBT_BODY, PM_TYPE_BODY, pc.body_searches);
+
+        // FIXIT-L PM_TYPE_ALT will never be set unless we add
+        // norm_data keyword or telnet, rpc_decode, smtp keywords
+        // until then we must use the standard packet mpse
+        SEARCH_BUFFER(buf.IBT_ALT, PM_TYPE_PKT, pc.alt_searches);
+    }
+
+    if ( !user_mode or type == 2 )
+    {
+        // file searches file only
+        if ( Mpse* so = port_group->mpse[PM_TYPE_FILE] )
+        {
+            // FIXIT-M file data should be obtained from
+            // inspector gadget as is done with SEARCH_BUFFER
+            SEARCH_PACKET(g_file_data.data, g_file_data.len, pc.file_searches);
+        }
+    }
+    return 0;
+}
+
 /*
 **
 **  NAME
@@ -967,7 +971,7 @@ void printRuleFmt1(SnortConfig* sc, OptTreeNode* otn)
 **
 */
 static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p,
-    int check_ports, char ip_rule, OTNX_MATCH_DATA* omd)
+    int check_ports, char ip_rule, int type, OTNX_MATCH_DATA* omd)
 {
     const uint8_t* tmp_payload;
     int8_t curr_ip_layer = 0;
@@ -994,91 +998,15 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p,
         p->packet_flags &= ~PKT_IP_RULE;
     }
 
-    /*
-     **  Init the info for rule ordering selection
-     */
-    //InitMatchInfo(omd);
-
     if (do_detect_content)
     {
         // FIXIT-L sdf etc. ran here
 
         if ( fp->get_stream_insert() || !(p->packet_flags & PKT_STREAM_INSERT) )
-        {
-            Inspector* gadget = p->flow ? p->flow->gadget : nullptr;
-            InspectionBuffer buf;
-
-            omd->pg = port_group;
-            omd->p = p;
-            omd->check_ports = check_ports;
-
-            if ( Mpse* so = port_group->mpse[PM_TYPE_FILE] )
-            {
-                // FIXIT-M file data should be obtained from
-                // inspector gadget as an extension of below
-                SEARCH_PACKET(g_file_data.data, g_file_data.len, pc.file_searches);
-            }
-
-            if ( gadget )
-            {
-                SEARCH_BUFFER(buf.IBT_KEY, PM_TYPE_KEY, pc.key_searches);
-                SEARCH_BUFFER(buf.IBT_HEADER, PM_TYPE_HEADER, pc.header_searches);
-                SEARCH_BUFFER(buf.IBT_BODY, PM_TYPE_BODY, pc.body_searches);
-
-                // FIXIT-L PM_TYPE_ALT will never be set unless we add
-                // norm_data keyword or telnet, rpc_decode, smtp keywords
-                // until then we must use the standard packet mpse
-                SEARCH_BUFFER(buf.IBT_ALT, PM_TYPE_PKT, pc.alt_searches);
-            }
-
-            if ( Mpse* so = port_group->mpse[PM_TYPE_PKT] )
-            {
-                if (p->data && p->dsize /*&&
-                    // FIXIT-P this is a huge win but means that raw packets aren't
-                    // inspected if service reassembly is going on
-                    (p->is_cooked() or !gadget or !stream.is_paf_active(p->flow, true))*/ )
-                {
-                    uint16_t pattern_match_size = p->dsize;
-
-                    if ( IsLimitedDetect(p) && (p->alt_dsize < p->dsize) )
-                        pattern_match_size = p->alt_dsize;
-
-                    SEARCH_PACKET(p->data, pattern_match_size, pc.raw_searches);
-                }
-            }
-        }
+            if ( fp_search(port_group, p, check_ports, type, omd) )
+                return 0;
     }
 
-    /*
-     **  PKT_REBUILT_STREAM packets are re-injected streams.  This means
-     **  that the "packet headers" are completely bogus and only the
-     **  content matches are important.  So for PKT_REBUILT_STREAMs, we
-     **  don't inspect against no-content OTNs since these deal with
-     **  packet headers, packet sizes, etc.
-     **
-     **  NOTE:
-     **  This has been changed when evaluating no-content rules because
-     **  it was interfering with the pass->alert ordering.  We still
-     **  need to check no-contents against rebuilt packets, because of
-     **  this problem.  Immediate solution is to have the detection plugins
-     **  bail if the rule should only be inspected against packets, a.k.a
-     **  dsize checks.
-     **
-     **  NOTE 2:
-     **  PKT_REBUILT_STREAM packets are now cooked (encoded by Snort)
-     **  and have the same encapsulations as the raw packets.  The
-     **  headers are "good enough" for detection (valid TCP sequence
-     **  numbers, but zero checksums) but packet sizes are different.
-     **  Given that TCP segmentation is arbitrary to start with, the
-     **  use of dsize in a rule is questionable for raw or rebuilt.
-     */
-
-    /*
-     **  Walk and test the non-content OTNs
-     */
-    if ( fp->get_debug_print_nc_rules() )
-        LogMessage("NC-testing %u rules\n", port_group->nfp_rule_count);
-
 #ifdef PPM_MGR
     if ( PPM_ENABLED() )
         PPM_GET_TIME();
@@ -1086,14 +1014,25 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p,
 
     do
     {
+        // FIXIT-L restrict to non-data packets?  (non-data includes
+        // defrags).  strictly speaking, nfp (no fast pattern) rules are
+        // not the same as nc (no content).  since these rules may have
+        // content, they must be run against all packets.
+        //if ( p->is_data() )
+        //    break;
+
         if (port_group->nfp_rule_count)
         {
+            // walk and test the nfp OTNs
+            if ( fp->get_debug_print_nc_rules() )
+                LogMessage("NC-testing %u rules\n", port_group->nfp_rule_count);
+
             detection_option_eval_data_t eval_data;
             int rval;
 
             eval_data.pomd = omd;
             eval_data.p = p;
-            eval_data.pmd = NULL;
+            eval_data.pmd = nullptr;
             eval_data.flowbit_failed = 0;
             eval_data.flowbit_noalert = 0;
 
@@ -1114,8 +1053,11 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p,
                 port_group->match_count++;
                 UpdateNQEvents(&sfEvent);
             }
+            pc.slow_searches++;
         }
 
+        // FIXIT-L need to eval all IP layers, etc.
+        // FIXIT-L why run only nfp rules?
         if (ip_rule)
         {
             /* Evaluate again with the next IP layer */
@@ -1137,228 +1079,157 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p,
     }
     while (repeat);
 
-#ifdef PPM_MGR  /* Tag only used with PPM right now */
-fp_eval_header_sw_reset_ip:
-#endif
-
     return 0;
 }
 
-/*
-** fpEvalHeaderUdp::
-*/
-static inline int fpEvalHeaderUdp(Packet* p, OTNX_MATCH_DATA* omd)
+static inline void fpEvalHeaderIp(Packet* p, OTNX_MATCH_DATA* omd)
 {
-    PortGroup* src = NULL, * dst = NULL, * gen = NULL;
+    PortGroup* any = nullptr, * ip_group = nullptr;
 
-    {
-        /* Check for a service/protocol ordinal for this packet */
-        int16_t proto_ordinal = p->flow ? p->flow->ssn_state.application_protocol : 0;
+    if ( !prmFindRuleGroupIp(snort_conf->prmIpRTNX, ANYPORT, &ip_group, &any) )
+        return;
 
-        DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE,"proto_ordinal=%d\n",proto_ordinal); );
+    if ( snort_conf->fast_pattern_config->get_debug_print_nc_rules() )
+        LogMessage("fpEvalHeaderIp: ip_group=%p, any=%p\n", (void*)ip_group, (void*)any);
 
-        if (proto_ordinal > 0)
-        {
-            /* Grab the generic group -- the any-any rules */
-            prmFindGenericRuleGroup(snort_conf->prmUdpRTNX, &gen);
-
-            /* TODO:  To From Server ?, else we apply  */
-            dst = fpGetServicePortGroupByOrdinal(snort_conf->sopgTable, SNORT_PROTO_UDP,
-                TO_SERVER, proto_ordinal);
-            src = fpGetServicePortGroupByOrdinal(snort_conf->sopgTable, SNORT_PROTO_UDP,
-                TO_CLIENT, proto_ordinal);
-
-            DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE,
-                "fpEvalHeaderUdpp:targetbased-ordinal-lookup: "
-                "sport=%d, dport=%d, proto_ordinal=%d, src:%x, "
-                "dst:%x, gen:%x\n",p->ptrs.sp,p->ptrs.dp,proto_ordinal,src,dst,gen); );
-        }
-    }
+    if ( ip_group )
+        fpEvalHeaderSW(ip_group, p, 0, 1, 0, omd);
 
-    if ((src == NULL) && (dst == NULL))
-    {
-        /* we did not have a target based port group, use ports */
-        if (!prmFindRuleGroupUdp(snort_conf->prmUdpRTNX, p->ptrs.dp, p->ptrs.sp, &src, &dst, &gen))
-            return 0;
+    if  (any )
+        fpEvalHeaderSW(any, p, 0, 1, 0, omd);
+}
 
-        DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE,
-            "fpEvalHeaderUdp: sport=%d, dport=%d, "
-            "src:%x, dst:%x, gen:%x\n",p->ptrs.sp,p->ptrs.dp,src,dst,gen); );
-    }
+static inline void fpEvalHeaderIcmp(Packet* p, OTNX_MATCH_DATA* omd)
+{
+    PortGroup* any = nullptr, * type = nullptr;
 
-    if (snort_conf->fast_pattern_config->get_debug_print_nc_rules())
-    {
-        LogMessage(
-            "fpEvalHeaderUdp: sport=%d, dport=%d, src:%p, dst:%p, gen:%p\n",
-            p->ptrs.sp, p->ptrs.dp, (void*)src, (void*)dst, (void*)gen);
-    }
+    if ( !prmFindRuleGroupIcmp(snort_conf->prmIcmpRTNX, p->ptrs.icmph->type, &type, &any) )
+        return;
 
-    InitMatchInfo(omd);
+    if ( type )
+        fpEvalHeaderSW(type, p, 0, 0, 0, omd);
 
-    if (dst != NULL)
-    {
-        if (fpEvalHeaderSW(dst, p, 1, 0, omd))
-            return 1;
-    }
-
-    if (src != NULL)
-    {
-        if (fpEvalHeaderSW(src, p, 1, 0, omd))
-            return 1;
-    }
-
-    if (gen != NULL)
-    {
-        if (fpEvalHeaderSW(gen, p, 1, 0, omd))
-            return 1;
-    }
-
-    return fpFinalSelectEvent(omd, p);
+    if ( any )
+        fpEvalHeaderSW(any, p, 0, 0, 0, omd);
 }
 
-/*
-**  fpEvalHeaderTcp::
-*/
-static inline int fpEvalHeaderTcp(Packet* p, OTNX_MATCH_DATA* omd)
+static inline void fpEvalHeaderTcp(Packet* p, OTNX_MATCH_DATA* omd)
 {
-    PortGroup* src = NULL, * dst = NULL, * gen = NULL;
+    PortGroup* src = nullptr, * dst = nullptr, * any = nullptr;
 
-    {
-        int16_t proto_ordinal = p->flow ? p->flow->ssn_state.application_protocol : 0;
+    if ( !prmFindRuleGroupTcp(snort_conf->prmTcpRTNX, p->ptrs.dp, p->ptrs.sp, &src, &dst, &any) )
+        return;
 
-        DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE, "proto_ordinal=%d\n", proto_ordinal); );
+    DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE,
+        "fpEvalHeaderTcp: sport=%d, "
+        "dport=%d, src:%x, dst:%x, any:%x\n",p->ptrs.sp,p->ptrs.dp,src,dst,any); );
 
-        if (proto_ordinal > 0)
-        {
-            /* Grab the generic group -- the any-any rules */
-            prmFindGenericRuleGroup(snort_conf->prmTcpRTNX, &gen);
+    if ( dst )
+        fpEvalHeaderSW(dst, p, 1, 0, 0, omd);
 
-            if (p->packet_flags & PKT_FROM_SERVER) /* to cli */
-            {
-                DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE, "pkt_from_server\n"); );
+    if ( src )
+        fpEvalHeaderSW(src, p, 1, 0, 0, omd);
 
-                src = fpGetServicePortGroupByOrdinal(snort_conf->sopgTable, SNORT_PROTO_TCP,
-                    0 /*to_cli */,  proto_ordinal);
-            }
+    if ( any )
+        fpEvalHeaderSW(any, p, 1, 0, 0, omd);
+}
 
-            if (p->packet_flags & PKT_FROM_CLIENT) /* to srv */
-            {
-                DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE, "pkt_from_client\n"); );
+static inline void fpEvalHeaderUdp(Packet* p, OTNX_MATCH_DATA* omd)
+{
+    PortGroup* src = nullptr, * dst = nullptr, * any = nullptr;
 
-                dst = fpGetServicePortGroupByOrdinal(snort_conf->sopgTable, SNORT_PROTO_TCP,
-                    1 /*to_srv */,  proto_ordinal);
-            }
+    if ( !prmFindRuleGroupUdp(snort_conf->prmUdpRTNX, p->ptrs.dp, p->ptrs.sp, &src, &dst, &any) )
+        return;
 
-            DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE,
-                "fpEvalHeaderTcp:targetbased-ordinal-lookup: "
-                "sport=%d, dport=%d, proto_ordinal=%d, src:%x, "
-                "dst:%x, gen:%x\n",p->ptrs.sp,p->ptrs.dp,proto_ordinal,src,dst,gen); );
-        }
-    }
+    DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE,
+        "fpEvalHeaderUdp: sport=%d, dport=%d, "
+        "src:%x, dst:%x, any:%x\n",p->ptrs.sp,p->ptrs.dp,src,dst,any); );
 
-    if ((src == NULL) && (dst == NULL))
-    {
-        /* grab the src/dst groups from the lookup above */
-        if (!prmFindRuleGroupTcp(snort_conf->prmTcpRTNX, p->ptrs.dp, p->ptrs.sp, &src, &dst, &gen))
-            return 0;
+    if ( dst )
+        fpEvalHeaderSW(dst, p, 1, 0, 0, omd) ;
 
-        DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE,
-            "fpEvalHeaderTcp: sport=%d, "
-            "dport=%d, src:%x, dst:%x, gen:%x\n",p->ptrs.sp,p->ptrs.dp,src,dst,gen); );
-    }
+    if ( src )
+        fpEvalHeaderSW(src, p, 1, 0, 0, omd) ;
 
-    if (snort_conf->fast_pattern_config->get_debug_print_nc_rules())
-    {
-        LogMessage(
-            "fpEvalHeaderTcp: sport=%d, dport=%d, src:%p, dst:%p, gen:%p\n",
-            p->ptrs.sp, p->ptrs.dp, (void*)src, (void*)dst, (void*)gen);
-    }
+    if ( any )
+        fpEvalHeaderSW(any, p, 1, 0, 0, omd) ;
+}
 
-    InitMatchInfo(omd);
+static inline void fpEvalHeaderSvc(Packet* p, OTNX_MATCH_DATA* omd, int proto)
+{
+    PortGroup* svc = nullptr, * file = nullptr;
 
-    if (dst != NULL)
-    {
-        if (fpEvalHeaderSW(dst, p, 1, 0, omd))
-            return 1;
-    }
+    int16_t proto_ordinal = p->flow ? p->flow->ssn_state.application_protocol : 0;
 
-    if (src != NULL)
-    {
-        if (fpEvalHeaderSW(src, p, 1, 0, omd))
-            return 1;
-    }
+    DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE, "proto_ordinal=%d\n", proto_ordinal); );
 
-    if (gen != NULL)
+    if (proto_ordinal > 0)
     {
-        if (fpEvalHeaderSW(gen, p, 1, 0, omd))
-            return 1;
-    }
-
-    return fpFinalSelectEvent(omd, p);
-}
-
-/*
-**  fpEvalHeaderICMP::
-*/
-static inline int fpEvalHeaderIcmp(Packet* p, OTNX_MATCH_DATA* omd)
-{
-    PortGroup* gen = NULL, * type = NULL;
+        if (p->packet_flags & PKT_FROM_SERVER) /* to cli */
+        {
+            DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE, "pkt_from_server\n"); );
 
-    if (!prmFindRuleGroupIcmp(snort_conf->prmIcmpRTNX, p->ptrs.icmph->type, &type, &gen))
-        return 0;
+            svc = snort_conf->sopgTable->get_port_group(proto, false, proto_ordinal);
+            file = snort_conf->sopgTable->get_port_group(proto, false, SNORT_PROTO_FILE);
+        }
 
-    if (snort_conf->fast_pattern_config->get_debug_print_nc_rules())
-    {
-        LogMessage(
-            "fpEvalHeaderIcmp: icmp->type=%d type=%p gen=%p\n",
-            p->ptrs.icmph->type, (void*)type, (void*)gen);
-    }
+        if (p->packet_flags & PKT_FROM_CLIENT) /* to srv */
+        {
+            DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE, "pkt_from_client\n"); );
 
-    InitMatchInfo(omd);
+            svc = snort_conf->sopgTable->get_port_group(proto, true, proto_ordinal);
+            file = snort_conf->sopgTable->get_port_group(proto, true, SNORT_PROTO_FILE);
+        }
 
-    if (type != NULL)
-    {
-        if (fpEvalHeaderSW(type, p, 0, 0, omd))
-            return 1;
+        DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE,
+            "fpEvalHeaderSvc:targetbased-ordinal-lookup: "
+            "sport=%d, dport=%d, proto_ordinal=%d, proto=%d, src:%x, "
+            "file:%x\n",p->ptrs.sp,p->ptrs.dp,proto_ordinal,proto,svc,file); );
     }
 
-    if (gen != NULL)
-    {
-        if (fpEvalHeaderSW(gen, p, 0, 0, omd))
-            return 1;
-    }
+    if ( file )
+        fpEvalHeaderSW(file, p, 2, 0, 2, omd);
 
-    return fpFinalSelectEvent(omd, p);
+    if ( svc )
+        fpEvalHeaderSW(svc, p, 2, 0, 1, omd);
 }
 
-/*
-**  fpEvalHeaderIP::
-*/
-static inline int fpEvalHeaderIp(Packet* p, int ip_proto, OTNX_MATCH_DATA* omd)
+static void fpEvalPacketUdp(Packet* p)
 {
-    PortGroup* gen = NULL, * ip_group = NULL;
+    OTNX_MATCH_DATA* omd = &t_omd;
 
-    if (!prmFindRuleGroupIp(snort_conf->prmIpRTNX, ip_proto, &ip_group, &gen))
-        return 0;
+    uint16_t tmp_sp = p->ptrs.sp;
+    uint16_t tmp_dp = p->ptrs.dp;
+    const udp::UDPHdr* tmp_udph = p->ptrs.udph;
+    const uint8_t* tmp_data = p->data;
+    int tmp_do_detect_content = do_detect_content;
+    uint16_t tmp_dsize = p->dsize;
 
-    if (snort_conf->fast_pattern_config->get_debug_print_nc_rules())
-        LogMessage("fpEvalHeaderIp: ip_group=%p, gen=%p\n", (void*)ip_group, (void*)gen);
+    const udp::UDPHdr* udph = layer::get_outer_udp_lyr(p);
 
-    InitMatchInfo(omd);
+    p->ptrs.udph = udph;
+    p->ptrs.sp = ntohs(udph->uh_sport);
+    p->ptrs.dp = ntohs(udph->uh_dport);
+    p->data = (const uint8_t*)udph + udp::UDP_HEADER_LEN;
 
-    if (ip_group != NULL)
-    {
-        if (fpEvalHeaderSW(ip_group, p, 0, 1, omd))
-            return 1;
-    }
+    ip::IpApi tmp_api;
+    int8_t curr_layer = 0;
+    layer::set_outer_ip_api(p, tmp_api, curr_layer);
 
-    if (gen != NULL)
-    {
-        if (fpEvalHeaderSW(gen, p, 0, 1, omd))
-            return 1;
-    }
+    if (tmp_api.pay_len() >  udp::UDP_HEADER_LEN)
+        p->dsize = tmp_api.pay_len() - udp::UDP_HEADER_LEN;
 
-    return fpFinalSelectEvent(omd, p);
+    if (p->dsize)
+        do_detect_content = 1;
+
+    fpEvalHeaderUdp(p, omd);
+
+    p->ptrs.sp = tmp_sp;
+    p->ptrs.dp = tmp_dp;
+    p->ptrs.udph = tmp_udph;
+    p->data = tmp_data;
+    p->dsize = tmp_dsize;
+    do_detect_content = tmp_do_detect_content;
 }
 
 /*
@@ -1389,72 +1260,55 @@ static inline int fpEvalHeaderIp(Packet* p, int ip_proto, OTNX_MATCH_DATA* omd)
 int fpEvalPacket(Packet* p)
 {
     OTNX_MATCH_DATA* omd = &t_omd;
+    InitMatchInfo(omd);
 
     /* Run UDP rules against the UDP header of Teredo packets */
+    // FIXIT-L udph is always inner; need to check for outer
     if ( p->ptrs.udph && (p->proto_bits & (PROTO_BIT__TEREDO | PROTO_BIT__GTP)) )
-    {
-        uint16_t tmp_sp = p->ptrs.sp;
-        uint16_t tmp_dp = p->ptrs.dp;
-        const udp::UDPHdr* tmp_udph = p->ptrs.udph;
-        const uint8_t* tmp_data = p->data;
-        int tmp_do_detect_content = do_detect_content;
-        uint16_t tmp_dsize = p->dsize;
-
-        const udp::UDPHdr* udph = layer::get_outer_udp_lyr(p);
-
-        p->ptrs.udph = udph;
-        p->ptrs.sp = ntohs(udph->uh_sport);
-        p->ptrs.dp = ntohs(udph->uh_dport);
-        p->data = (const uint8_t*)udph + udp::UDP_HEADER_LEN;
-
-        ip::IpApi tmp_api;
-        int8_t curr_layer = 0;
-        layer::set_outer_ip_api(p, tmp_api, curr_layer);
-
-        if (tmp_api.pay_len() >  udp::UDP_HEADER_LEN)
-            p->dsize = tmp_api.pay_len() - udp::UDP_HEADER_LEN;
-
-        if (p->dsize)
-            do_detect_content = 1;
-
-        fpEvalHeaderUdp(p, omd);
-
-        p->ptrs.sp = tmp_sp;
-        p->ptrs.dp = tmp_dp;
-        p->ptrs.udph = tmp_udph;
-        p->data = tmp_data;
-        p->dsize = tmp_dsize;
-        do_detect_content = tmp_do_detect_content;
-    }
+        fpEvalPacketUdp(p);
 
     switch (p->type())
     {
+    case PktType::IP:
+        fpEvalHeaderIp(p, omd);
+        fpEvalHeaderSvc(p, omd, SNORT_PROTO_IP);
+        break;
+
+    case PktType::ICMP:
+        fpEvalHeaderIcmp(p, omd);
+        fpEvalHeaderSvc(p, omd, SNORT_PROTO_ICMP);
+        break;
+
     case PktType::TCP:
-        return fpEvalHeaderTcp(p, omd);
+        fpEvalHeaderTcp(p, omd);
+        fpEvalHeaderSvc(p, omd, SNORT_PROTO_TCP);
+        break;
 
     case PktType::UDP:
-        return fpEvalHeaderUdp(p, omd);
-
-    case PktType::ICMP:
-        return fpEvalHeaderIcmp(p, omd);
+        fpEvalHeaderUdp(p, omd);
+        fpEvalHeaderSvc(p, omd, SNORT_PROTO_UDP);
+        break;
 
     case PktType::USER:
-    case PktType::FILE:
-        if ( p->proto_bits & PROTO_BIT__TCP )
-            return fpEvalHeaderTcp(p, omd);
+        if ( snort_conf->sopgTable->user_mode )
+            fpEvalHeaderSvc(p, omd, SNORT_PROTO_USER);
+
+        else if ( p->proto_bits & PROTO_BIT__TCP )
+            fpEvalHeaderTcp(p, omd);
 
         else if ( p->proto_bits & PROTO_BIT__UDP )
-            return fpEvalHeaderUdp(p, omd);
-        else
-            break;
+            fpEvalHeaderUdp(p, omd);
+        break;
+
+    case PktType::FILE:
+        fpEvalHeaderSvc(p, omd, SNORT_PROTO_FILE);
+        break;
 
-    /*
-    **  No Match on TCP/UDP, Do IP
-    */
     default:
-        return fpEvalHeaderIp(p, -1, omd);
+        break;
     }
-    return 0;
+
+    return fpFinalSelectEvent(omd, p);
 }
 
 OptTreeNode* GetOTN(uint32_t gid, uint32_t sid)
@@ -1467,7 +1321,7 @@ OptTreeNode* GetOTN(uint32_t gid, uint32_t sid)
     if ( !getRtnFromOtn(otn) )
     {
         // If not configured to autogenerate and there isn't an RTN, meaning
-        // this rule isn't in the current policy, return NULL.
+        // this rule isn't in the current policy, return nullptr.
         return nullptr;
     }
 
index 6454516f54a48bc61757b2dfbaa7685a190015af..894cb9ab8170d0ba73035d41ad6af2ab62fb0fef 100644 (file)
 #include "fp_create.h"
 #include "snort_config.h"
 
-#define ANYPORT   -1
-
 /*
 **
 **  NAME
index 22e8aad7d3a56d20d89963f9aa9364c0854d6fa0..7caeea413e250c590e42924c0390f48afd97bd70 100644 (file)
@@ -28,6 +28,8 @@
 #include "protocols/packet.h"
 #include "ports/port_group.h"
 
+#define ANYPORT (-1)
+
 struct PORT_RULE_MAP
 {
     int prmNumDstRules;
index 0d6276d2f9f0eb45688f72a32811d95dfde64b79..ea08bce932ee81ec91f3689d79aeb56aa01c2b5b 100644 (file)
 #include "detection/fp_detect.h"
 #include "parser/parser.h"
 
+//-------------------------------------------------------------------------
+// service map stuff
+//-------------------------------------------------------------------------
+
 static SFGHASH* alloc_srvmap()
 {
-    SFGHASH* p = sfghash_new(1000,
-        0,
-        0,
+    SFGHASH* p = sfghash_new(1000, 0, 0,
         /*nodes are lists,free them in sfghash_delete*/
         (void (*)(void*))sflist_free);
-    if (p == NULL)
+
+    if ( !p )
         FatalError("could not allocate a service rule map - no memory?\n");
 
     return p;
 }
 
+static void free_srvmap(SFGHASH* table)
+{
+    if ( table )
+        sfghash_delete(table);
+}
+
 srmm_table_t* ServiceMapNew()
 {
     srmm_table_t* table = (srmm_table_t*)SnortAlloc(sizeof(srmm_table_t));
 
-    table->ip_to_srv = alloc_srvmap();
-    table->ip_to_cli = alloc_srvmap();
-
-    table->icmp_to_srv = alloc_srvmap();
-    table->icmp_to_cli = alloc_srvmap();
-
-    table->tcp_to_srv = alloc_srvmap();
-    table->tcp_to_cli = alloc_srvmap();
-
-    table->udp_to_srv = alloc_srvmap();
-    table->udp_to_cli = alloc_srvmap();
-
-    table->svc_to_srv = alloc_srvmap();
-    table->svc_to_cli = alloc_srvmap();
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
+    {
+        table->to_srv[i] = alloc_srvmap();
+        table->to_cli[i] = alloc_srvmap();
+    }
 
     return table;
 }
 
-void ServiceTableFree(SFGHASH* table)
-{
-    if (table != NULL)
-        sfghash_delete(table);
-}
-
-void ServiceMapFree(srmm_table_t* srvc_map)
+void ServiceMapFree(srmm_table_t* table)
 {
-    if (srvc_map == NULL)
+    if ( !table )
         return;
 
-    ServiceTableFree(srvc_map->ip_to_srv);
-    ServiceTableFree(srvc_map->ip_to_cli);
-
-    ServiceTableFree(srvc_map->icmp_to_srv);
-    ServiceTableFree(srvc_map->icmp_to_cli);
-
-    ServiceTableFree(srvc_map->tcp_to_srv);
-    ServiceTableFree(srvc_map->tcp_to_cli);
-
-    ServiceTableFree(srvc_map->udp_to_srv);
-    ServiceTableFree(srvc_map->udp_to_cli);
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
+    {
+        if ( table->to_srv[i] )
+            free_srvmap(table->to_srv[i]);
 
-    ServiceTableFree(srvc_map->svc_to_srv);
-    ServiceTableFree(srvc_map->svc_to_cli);
+        if ( table->to_cli[i] )
+            free_srvmap(table->to_cli[i]);
+    }
 
-    free(srvc_map);
+    free(table);
 }
 
+//-------------------------------------------------------------------------
+// service pg stuff
+//-------------------------------------------------------------------------
+
 static SFGHASH* alloc_spgmm()
 {
-    SFGHASH* p;
-
-    /* TODO: keys are ascii service names - for now ! */
-    p = sfghash_new(1000, /* # rows in table */
-        0,            /* size: of key 0 = ascii, >0 = fixed size */
-        0,            /* bool:user keys,  if true just store this pointer, don't copy the key */
+    SFGHASH* p = sfghash_new(
+     1000,  /* # rows in table */
+        0, /* size: of key 0 = ascii, >0 = fixed size */
+        0, /* bool:user keys,  if true just store this pointer, don't copy the key */
         fpDeletePortGroup);
-    /* ??? Why shouldn't we delete the port groups ??? */
-    //(void(*)(void*))0 /* free nodes are port_groups do not delete here */ );
 
-    if (p == NULL)
+    if ( !p )
         FatalError("could not allocate a service port_group map : no memory?\n");
 
     return p;
 }
 
-srmm_table_t* ServicePortGroupMapNew()
+static void free_spgmm(SFGHASH* table)
 {
-    srmm_table_t* table = (srmm_table_t*)SnortAlloc(sizeof(srmm_table_t));
-
-    table->ip_to_srv = alloc_spgmm();
-    table->ip_to_cli = alloc_spgmm();
-
-    table->icmp_to_srv = alloc_spgmm();
-    table->icmp_to_cli = alloc_spgmm();
-
-    table->tcp_to_srv = alloc_spgmm();
-    table->tcp_to_cli = alloc_spgmm();
-
-    table->udp_to_srv = alloc_spgmm();
-    table->udp_to_cli = alloc_spgmm();
-
-    table->svc_to_srv = alloc_spgmm();
-    table->svc_to_cli = alloc_spgmm();
+    if ( !table )
+        return;
 
-    return table;
+    sfghash_delete(table);
 }
 
-static void ServicePortGroupTableFree(SFGHASH* table)
+srmm_table_t* ServicePortGroupMapNew()
 {
-#if 0
-    SFGHASH_NODE* node;
-    PortGroup* pg;
-
-    /* Not sure why we wouldn't want to free the data */
-    for (node = sfghash_findfirst(table);
-        node != NULL;
-        node = sfghash_findnext(table))
-    {
-        pg = (PortGroup*)node->data;
-        if (pg == NULL)
-            continue;
+    srmm_table_t* table = (srmm_table_t*)SnortAlloc(sizeof(srmm_table_t));
 
-        /* XXX XXX (if we need to recycle these) free the PortGroup */
-        node->data = NULL;
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
+    {
+        table->to_srv[i] = alloc_spgmm();
+        table->to_cli[i] = alloc_spgmm();
     }
-#endif
-
-    if (table == NULL)
-        return;
 
-    sfghash_delete(table);
+    return table;
 }
 
-void ServicePortGroupMapFree(srmm_table_t* srvc_pg_map)
+void ServicePortGroupMapFree(srmm_table_t* table)
 {
-    if (srvc_pg_map == NULL)
+    if ( !table )
         return;
 
-    ServicePortGroupTableFree(srvc_pg_map->ip_to_srv);
-    ServicePortGroupTableFree(srvc_pg_map->ip_to_cli);
-
-    ServicePortGroupTableFree(srvc_pg_map->icmp_to_srv);
-    ServicePortGroupTableFree(srvc_pg_map->icmp_to_cli);
-
-    ServicePortGroupTableFree(srvc_pg_map->tcp_to_srv);
-    ServicePortGroupTableFree(srvc_pg_map->tcp_to_cli);
-
-    ServicePortGroupTableFree(srvc_pg_map->udp_to_srv);
-    ServicePortGroupTableFree(srvc_pg_map->udp_to_cli);
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
+    {
+        if ( table->to_srv[i] )
+            free_spgmm(table->to_srv[i]);
 
-    ServicePortGroupTableFree(srvc_pg_map->svc_to_srv);
-    ServicePortGroupTableFree(srvc_pg_map->svc_to_cli);
+        if ( table->to_cli[i] )
+            free_spgmm(table->to_cli[i]);
+    }
 
-    free(srvc_pg_map);
+    free(table);
 }
 
+//-------------------------------------------------------------------------
+// service pg stuff
+//-------------------------------------------------------------------------
+
 /*
  * Add the otn to the list stored by the key = servicename.
  *
@@ -241,49 +200,24 @@ static void ServiceMapAddOtnRaw(SFGHASH* table, char* servicename, OptTreeNode*
  */
 static int ServiceMapAddOtn(srmm_table_t* srmm, int proto, char* servicename, OptTreeNode* otn)
 {
-    SFGHASH* to_srv;  /* to srv service rule map */
-    SFGHASH* to_cli;  /* to cli service rule map */
-
     if ( !servicename )
-        return 0;
+        return -1;
 
-    if (!otn )
-        return 0;
+    if ( !otn )
+        return -1;
 
-    if ( proto == SNORT_PROTO_IP )
-    {
-        to_srv = srmm->ip_to_srv;
-        to_cli = srmm->ip_to_cli;
-    }
-    else if ( proto == SNORT_PROTO_ICMP )
-    {
-        to_srv = srmm->icmp_to_srv;
-        to_cli = srmm->icmp_to_cli;
-    }
-    else if ( proto == SNORT_PROTO_TCP )
-    {
-        to_srv = srmm->tcp_to_srv;
-        to_cli = srmm->tcp_to_cli;
-    }
-    else if ( proto == SNORT_PROTO_UDP )
-    {
-        to_srv = srmm->udp_to_srv;
-        to_cli = srmm->udp_to_cli;
-    }
-    else
-    {
-        to_srv = srmm->svc_to_srv;
-        to_cli = srmm->svc_to_cli;
-    }
+    if ( proto > SNORT_PROTO_USER )
+        proto = SNORT_PROTO_USER;
+
+    SFGHASH* to_srv = srmm->to_srv[proto];
+    SFGHASH* to_cli = srmm->to_cli[proto];
 
     if ( OtnFlowFromClient(otn) )
-    {
         ServiceMapAddOtnRaw(to_srv, servicename, otn);
-    }
+
     else if ( OtnFlowFromServer(otn) )
-    {
         ServiceMapAddOtnRaw(to_cli, servicename, otn);
-    }
+
     else /* else add to both sides */
     {
         ServiceMapAddOtnRaw(to_srv, servicename, otn);
@@ -299,30 +233,14 @@ void fpPrintServicePortGroupSummary(srmm_table_t* srvc_pg_map)
     LogMessage("| Service-PortGroup Table Summary \n");
     LogMessage("---------------------------------\n");
 
-    if (srvc_pg_map->ip_to_srv->count)
-        LogMessage("| ip to server   : %d services\n",srvc_pg_map->ip_to_srv->count);
-    if (srvc_pg_map->ip_to_cli->count)
-        LogMessage("| ip to cient    : %d services\n",srvc_pg_map->ip_to_cli->count);
-
-    if (srvc_pg_map->icmp_to_srv->count)
-        LogMessage("| icmp to server : %d services\n",srvc_pg_map->icmp_to_srv->count);
-    if (srvc_pg_map->icmp_to_cli->count)
-        LogMessage("| icmp to cient  : %d services\n",srvc_pg_map->icmp_to_cli->count);
-
-    if (srvc_pg_map->tcp_to_srv->count)
-        LogMessage("| tcp to server  : %d services\n",srvc_pg_map->tcp_to_srv->count);
-    if (srvc_pg_map->tcp_to_cli->count)
-        LogMessage("| tcp to cient   : %d services\n",srvc_pg_map->tcp_to_cli->count);
-
-    if (srvc_pg_map->udp_to_srv->count)
-        LogMessage("| udp to server  : %d services\n",srvc_pg_map->udp_to_srv->count);
-    if (srvc_pg_map->udp_to_cli->count)
-        LogMessage("| udp to cient   : %d services\n",srvc_pg_map->udp_to_cli->count);
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
+    {
+        if ( unsigned n = srvc_pg_map->to_srv[i]->count )
+            LogMessage("| %s to server   : %d services\n", get_protocol_name(i), n);
 
-    if (srvc_pg_map->svc_to_srv->count)
-        LogMessage("| svc to server  : %d services\n",srvc_pg_map->svc_to_srv->count);
-    if (srvc_pg_map->svc_to_cli->count)
-        LogMessage("| svc to cient   : %d services\n",srvc_pg_map->svc_to_cli->count);
+        if ( unsigned n = srvc_pg_map->to_cli[i]->count )
+            LogMessage("| %s to client   : %d services\n", get_protocol_name(i), n);
+    }
 
     LogMessage("---------------------------------\n");
 }
@@ -373,67 +291,60 @@ int fpCreateServiceMaps(SnortConfig* sc)
     return 0;
 }
 
-sopg_table_t* ServicePortGroupTableNew()
+//-------------------------------------------------------------------------
+// sopg_table_t stuff
+//-------------------------------------------------------------------------
+
+sopg_table_t::sopg_table_t()
 {
-    return (sopg_table_t*)SnortAlloc(sizeof(sopg_table_t));
+    unsigned n = (unsigned)get_protocol_count();
+
+    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; ++i )
+    {
+        if ( to_srv[i].size() < n )
+            to_srv[i].resize(n, nullptr);
+
+        if ( to_cli[i].size() < n )
+            to_cli[i].resize(n, nullptr);
+    }
+    user_mode = false;
 }
 
-PortGroup* fpGetServicePortGroupByOrdinal(
-    sopg_table_t* sopg, int proto, int dir, int16_t proto_ordinal)
+PortGroup* sopg_table_t::get_port_group(
+    int proto, bool c2s, int16_t proto_ordinal)
 {
-    PortGroup* pg = NULL;
+    assert(proto < SNORT_PROTO_MAX);
+
+    PortGroupVector& v = c2s ? to_srv[proto] : to_cli[proto];
 
-    if (proto_ordinal >= MAX_PROTOCOL_ORDINAL)
-        return NULL;
+    if ( (unsigned)proto_ordinal > v.size() )
+        return nullptr;
+
+    return v[proto_ordinal];
+}
 
-    if (sopg == NULL)
-        return NULL;
+bool sopg_table_t::set_user_mode()
+{
+    PortGroupVector& v1 = to_srv[SNORT_PROTO_USER];
 
-    switch (proto)
+    for ( unsigned i = 0; i < v1.size(); ++i )
     {
-    case SNORT_PROTO_IP:
-        if (dir == TO_SERVER)
-            pg = sopg->ip_to_srv[proto_ordinal];
-        else
-            pg = sopg->ip_to_cli[proto_ordinal];
-        break;
-
-    case SNORT_PROTO_ICMP:
-        if (dir == TO_SERVER)
-            pg = sopg->icmp_to_srv[proto_ordinal];
-        else
-            pg = sopg->icmp_to_cli[proto_ordinal];
-        break;
-
-    case SNORT_PROTO_TCP:
-        if (dir == TO_SERVER)
-            pg = sopg->tcp_to_srv[proto_ordinal];
-        else
-            pg = sopg->tcp_to_cli[proto_ordinal];
-        break;
-
-    case SNORT_PROTO_UDP:
-        if (dir == TO_SERVER)
-            pg = sopg->udp_to_srv[proto_ordinal];
-        else
-            pg = sopg->udp_to_cli[proto_ordinal];
-        break;
-
-    default:
-        if (dir == TO_SERVER)
-            pg = sopg->svc_to_srv[proto_ordinal];
-        else
-            pg = sopg->svc_to_cli[proto_ordinal];
-        break;
+        if ( v1[i] )
+        {
+            user_mode = true;
+            return true;
+        }
     }
+    v1 = to_cli[SNORT_PROTO_USER];
 
-    if ( !pg )
+    for ( unsigned i = 0; i < v1.size(); ++i )
     {
-        if (dir == TO_SERVER)
-            pg = sopg->svc_to_srv[proto_ordinal];
-        else
-            pg = sopg->svc_to_cli[proto_ordinal];
+        if ( v1[i] )
+        {
+            user_mode = true;
+            break;
+        }
     }
-    return pg;
+    return user_mode;
 }
 
index 45ae9cca73342bfda996ede698993a34b1be52bc..f1db8d2a40887ea67457b559fe615918a3785d7a 100644 (file)
@@ -30,6 +30,8 @@
 #ifndef SERVICE_MAP_H
 #define SERVICE_MAP_H
 
+#include <vector>
+
 #include "detection/pcrm.h"
 #include "target_based/snort_protocols.h"
 
@@ -38,20 +40,8 @@ struct SFGHASH;
 //  Service Rule Map Master Table
 struct srmm_table_t
 {
-    SFGHASH* ip_to_srv;
-    SFGHASH* ip_to_cli;
-
-    SFGHASH* icmp_to_srv;
-    SFGHASH* icmp_to_cli;
-
-    SFGHASH* tcp_to_srv;
-    SFGHASH* tcp_to_cli;
-
-    SFGHASH* udp_to_srv;
-    SFGHASH* udp_to_cli;
-
-    SFGHASH* svc_to_srv;
-    SFGHASH* svc_to_cli;
+    SFGHASH* to_srv[SNORT_PROTO_MAX];
+    SFGHASH* to_cli[SNORT_PROTO_MAX];
 };
 
 srmm_table_t* ServiceMapNew();
@@ -60,33 +50,24 @@ void ServiceMapFree(srmm_table_t*);
 srmm_table_t* ServicePortGroupMapNew();
 void ServicePortGroupMapFree(srmm_table_t*);
 
-void ServiceTableFree(SFGHASH*);
 void fpPrintServicePortGroupSummary(srmm_table_t*);
 int fpCreateServiceMaps(struct SnortConfig*);
 
 //  Service/Protocol Oridinal To PortGroup table
+typedef std::vector<PortGroup*> PortGroupVector;
+
 struct sopg_table_t
 {
-    PortGroup* ip_to_srv[MAX_PROTOCOL_ORDINAL];
-    PortGroup* ip_to_cli[MAX_PROTOCOL_ORDINAL];
-
-    PortGroup* icmp_to_srv[MAX_PROTOCOL_ORDINAL];
-    PortGroup* icmp_to_cli[MAX_PROTOCOL_ORDINAL];
+    sopg_table_t();
+    bool set_user_mode();
+    PortGroup* get_port_group(int proto, bool c2s, int16_t proto_ordinal);
 
-    PortGroup* tcp_to_srv[MAX_PROTOCOL_ORDINAL];
-    PortGroup* tcp_to_cli[MAX_PROTOCOL_ORDINAL];
+    PortGroupVector to_srv[SNORT_PROTO_MAX];
+    PortGroupVector to_cli[SNORT_PROTO_MAX];
 
-    PortGroup* udp_to_srv[MAX_PROTOCOL_ORDINAL];
-    PortGroup* udp_to_cli[MAX_PROTOCOL_ORDINAL];
-
-    PortGroup* svc_to_srv[MAX_PROTOCOL_ORDINAL];
-    PortGroup* svc_to_cli[MAX_PROTOCOL_ORDINAL];
+    bool user_mode;
 };
 
-sopg_table_t* ServicePortGroupTableNew();
-
-PortGroup* fpGetServicePortGroupByOrdinal(
-    sopg_table_t* sopg, int proto, int dir, int16_t proto_ordinal);
 
 #endif
 
index a857be9c9eccae1b87cc3c2dad38a3536299387a..00a48d5d79ac3422df339b211093fee548f1cb96 100644 (file)
@@ -851,6 +851,7 @@ const uint8_t* process_mime_data_paf(Flow* flow, const uint8_t* start, const uin
     {
         DecodeConfig* conf= mime_ssn->decode_conf;
         Email_DecodeState* ds = (Email_DecodeState*)(mime_ssn->decode_state);
+
         if (conf)
         {
             int detection_size = getDetectionSize(conf->b64_depth, conf->qp_depth,
@@ -968,20 +969,21 @@ void free_mime(void)
         delete mime_hdr_search_mpse;
 }
 
+void free_mime_session(MimeState& mime_ssn)
+{
+    if ( mime_ssn.decode_state )
+        free(mime_ssn.decode_state);
+
+    if ( mime_ssn.log_state )
+        free(mime_ssn.log_state);
+}
+
 void free_mime_session(MimeState* mime_ssn)
 {
     if (!mime_ssn)
         return;
 
-    if (mime_ssn->decode_state != NULL)
-    {
-        free(mime_ssn->decode_state);
-    }
-    if (mime_ssn->log_state != NULL)
-    {
-        free(mime_ssn->log_state);
-    }
-
+    free_mime_session(*mime_ssn);
     free(mime_ssn);
 }
 
index 9533dab1a62b3a878ae5d4a441e1073efd71fd53..c28664363a265b1beccecc73eb16bc933e573bb3 100644 (file)
@@ -65,7 +65,8 @@ void init_mime(void);
 void free_mime(void);
 const uint8_t* process_mime_data(Flow *flow, const uint8_t *start, const uint8_t *end,
                 MimeState *mime_ssn, bool upload, FilePosition position);
-void free_mime_session(MimeState* mime_ssn);
+void free_mime_session(MimeState*);
+void free_mime_session(MimeState&);
 void finalize_mime_position(Flow* flow, void* decode_state, FilePosition* position);
 void reset_mime_paf_state(MimeDataPafInfo *data_info);
 /*  Process data boundary and flush each file based on boundary*/
index acd70266e29211418ff08c845ed3a48fef63f560..b8859a2321628163353edf53a25dc4a956045c36 100644 (file)
@@ -528,7 +528,10 @@ static inline void _file_signature_lookup(FileContext* context,
     File_Verdict verdict = FILE_VERDICT_UNKNOWN;
 
     if (!pkt)
+    {
+        finish_signature_lookup(context);
         return;
+    }
 
     if (file_signature_cb)
     {
index 0be75c8d681b353b16137d42b152927a7082be82..4250bbf4eb9a499b332d92fc12878562b004809c 100644 (file)
@@ -103,7 +103,6 @@ void print_file_stats()
     int i;
     uint64_t processed_total[2];
     uint64_t processed_data_total[2];
-    uint64_t verdicts_total;
 
     if (!file_stats.files_total)
         return;
@@ -119,7 +118,7 @@ void print_file_stats()
     if ( !check_total )
         return;
 
-    LogLabel("file type stats (files):");
+    LogLabel("file type stats (files)");
 
     LogMessage("         Type              Download   Upload \n");
 
@@ -146,7 +145,7 @@ void print_file_stats()
     LogMessage("            Total          " FMTu64("-10") " " FMTu64("-10") " \n",
         processed_total[0], processed_total[1]);
 
-    LogLabel("file type stats (bytes):");
+    LogLabel("file type stats (bytes)");
 
     LogMessage("         Type              Download   Upload \n");
 
@@ -180,7 +179,7 @@ void print_file_stats()
     if ( !check_total )
         return;
 
-    LogLabel("file signature stats:\n");
+    LogLabel("file signature stats");
 
     LogMessage("         Type              Download   Upload \n");
 
@@ -202,9 +201,10 @@ void print_file_stats()
     LogMessage("            Total          " FMTu64("-10") " " FMTu64("-10") " \n",
         processed_total[0], processed_total[1]);
 
-    LogLabel("file type verdicts:\n");
+#if 0
+    LogLabel("file type verdicts");
 
-    verdicts_total = 0;
+    uint64_t verdicts_total = 0;
     for (i = 0; i < FILE_VERDICT_MAX; i++)
     {
         verdicts_total+=file_stats.verdicts_type[i];
@@ -350,5 +350,6 @@ void print_file_stats()
             "-10") " \n", file_stats.files_sig_depth);
 
     file_capture_mem_usage();
+#endif
 }
 
index d510d77758c07b662ae8180ecdb93577263ba462..522369c5100ccde432d860a01dec5561efa3209b 100644 (file)
@@ -36,6 +36,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#define MAX_PROTOCOL_ORDINAL 8192  // FIXIT-L use std::vector and get_protocol_count()
+
 typedef struct _File_Stats
 {
     uint64_t files_total;
index 9140993b5286c55e4165a0cd80eb6f073a85536e..0a480f779528e84b0ed5c14d07e9763c07e251f0 100644 (file)
@@ -277,7 +277,7 @@ void FileIdenfifier::update_trie(IdentifierNode* start, IdentifierNode* append)
         if (append->type_id)
         {
             if (start->type_id)
-                ParseWarning(WARN_RULES, "Duplicated type definition '%d -> %d at offset %d.\n",
+                ParseWarning(WARN_RULES, "Duplicated type definition '%d -> %d at offset %d",
                     start->type_id, append->type_id, append->offset);
             start->type_id = append->type_id;
         }
index e4c39e8bcac3a3ea1d20c4bc84d21142ab174d5b..326f40f01fa226ff681d2b5115bcc5d38177c2db 100644 (file)
@@ -63,10 +63,10 @@ class FileMagicRule
 {
 public:
     void clear(void);
-    uint32_t rev;
+    uint32_t rev = 0;
+    uint32_t id = 0;
     std::string message;
     std::string type;
-    uint32_t id;
     std::string category;
     std::string version;
     FileMagics file_magics;
index e633992bed0cb773954938858761ffc13202a13e..2b42c31caf18e0de75dc44e0413f95fd2ba53e91 100644 (file)
@@ -73,7 +73,7 @@ public:
 
     int eval(Cursor&, Packet*) override;
 
-private:
+//private:  // FIXTHIS-L privatize
     FlowCheckData config;
 };
 
@@ -227,12 +227,12 @@ int FlowCheckOption::eval(Cursor&, Packet* p)
 
 int OtnFlowFromServer(OptTreeNode* otn)
 {
-    FlowCheckData* fcd =
-        (FlowCheckData*)get_rule_type_data(otn, s_name);
+    FlowCheckOption* fco =
+        (FlowCheckOption*)get_rule_type_data(otn, s_name);
 
-    if (fcd )
+    if (fco )
     {
-        if ( fcd->from_server )
+        if ( fco->config.from_server )
             return 1;
     }
     return 0;
@@ -240,12 +240,12 @@ int OtnFlowFromServer(OptTreeNode* otn)
 
 int OtnFlowFromClient(OptTreeNode* otn)
 {
-    FlowCheckData* fcd =
-        (FlowCheckData*)get_rule_type_data(otn, s_name);
+    FlowCheckOption* fco =
+        (FlowCheckOption*)get_rule_type_data(otn, s_name);
 
-    if (fcd )
+    if (fco )
     {
-        if ( fcd->from_client )
+        if ( fco->config.from_client )
             return 1;
     }
     return 0;
@@ -253,12 +253,12 @@ int OtnFlowFromClient(OptTreeNode* otn)
 
 int OtnFlowIgnoreReassembled(OptTreeNode* otn)
 {
-    FlowCheckData* fcd =
-        (FlowCheckData*)get_rule_type_data(otn, s_name);
+    FlowCheckOption* fco =
+        (FlowCheckOption*)get_rule_type_data(otn, s_name);
 
-    if ( fcd )
+    if ( fco )
     {
-        if ( fcd->ignore_reassembled )
+        if ( fco->config.ignore_reassembled )
             return 1;
     }
     return 0;
@@ -266,12 +266,12 @@ int OtnFlowIgnoreReassembled(OptTreeNode* otn)
 
 int OtnFlowOnlyReassembled(OptTreeNode* otn)
 {
-    FlowCheckData* fcd =
-        (FlowCheckData*)get_rule_type_data(otn, s_name);
+    FlowCheckOption* fco =
+        (FlowCheckOption*)get_rule_type_data(otn, s_name);
 
-    if ( fcd )
+    if ( fco )
     {
-        if ( fcd->only_reassembled )
+        if ( fco->config.only_reassembled )
             return 1;
     }
     return 0;
index 656ae83e4d571e96fd17ea04061f3a991d3cbba3..0a6f10078ab41a2e3e925c44a4792de7f19c8f52 100644 (file)
@@ -212,7 +212,7 @@ static const Parameter search_engine_params[] =
     { "max_queue_events", Parameter::PT_INT, nullptr, "5",
       "maximum number of matching fast pattern states to queue per packet" },
 
-    { "inspect_stream_inserts", Parameter::PT_BOOL, nullptr, "true",
+    { "inspect_stream_inserts", Parameter::PT_BOOL, nullptr, "false",
       "inspect reassembled payload - disabling is good for performance, bad for detection" },
 
     { "search_method", Parameter::PT_STRING, nullptr, "ac_bnfa_q",
index 46fd35ba2e660512848437fae0e03f431737fef9..61c989cc127069ac1af1aec33c67dfcfbd0cd647 100644 (file)
@@ -290,7 +290,6 @@ public:
     PORT_RULE_MAP* prmIcmpRTNX = nullptr;
     PORT_RULE_MAP* prmTcpRTNX = nullptr;
     PORT_RULE_MAP* prmUdpRTNX = nullptr;
-    PORT_RULE_MAP* prmSvcRTNX = nullptr;
 
     srmm_table_t* srmmTable = nullptr;   /* srvc rule map master table */
     srmm_table_t* spgmmTable = nullptr;  /* srvc port_group map master table */
index e31b068dfd13cb7ac42acb0d39a319be2ff46250..10aa1f7cd254f3a637b6cb9ea551114d3c66cbc6 100644 (file)
@@ -115,6 +115,9 @@ PHInstance::PHInstance(PHClass& p, Module* mod) : pp_class(p)
     {
         handler->set_api(&p.api);
         handler->add_ref();
+
+        if ( p.api.service )
+            handler->set_service(AddProtocolReference(p.api.service));
     }
 }
 
@@ -234,9 +237,6 @@ void InspectorManager::add_plugin(const InspectApi* api)
 {
     PHGlobal* g = new PHGlobal(*api);
     s_handlers.push_back(g);
-
-    if ( api->service )
-        AddProtocolReference(api->service);
 }
 
 static const InspectApi* get_plugin(const char* keyword)
index 4f15caeecd334442bbf968215b4be24de4fff4d2..0ad2366c75091964037a92f99b853c165bbdd65b 100644 (file)
@@ -364,8 +364,13 @@ void Stuff::apply_service(Flow* flow, const HostAttributeEntry* host)
         gadget = get_gadget(flow);
 
     if ( gadget )
+    {
         flow->set_gadget(gadget);
 
+        if ( !flow->ssn_state.application_protocol )
+            flow->ssn_state.application_protocol = gadget->get_service();
+    }
+
     else if ( wizard )
         flow->set_clouseau(wizard);
 }
@@ -451,15 +456,16 @@ int Binder::exec(int, void* pv)
     Inspector* ins = find_gadget(flow);
 
     if ( ins )
+    {
         flow->set_gadget(ins);
+        flow->ssn_state.application_protocol = ins->get_service();
+    }
+    else if ( flow->service )
+        flow->ssn_state.application_protocol = FindProtocolReference(flow->service);
 
     if ( !flow->is_stream() )
         return 0;
 
-    if ( flow->service )
-        // FIXIT-H use Inspector::get_service() (not yet initialized)
-        flow->ssn_state.application_protocol = FindProtocolReference(flow->service);
-
     if ( ins )
     {
         stream.set_splitter(flow, true, ins->get_splitter(true));
index 949f5bb9ae8fb5ac4d471dc05d8ffc3255406ea1..de6af1b67cad72cc2cc5d2bc9a3242a3a74963bf 100644 (file)
@@ -195,10 +195,7 @@ void add_service_to_otn(
         ParseError("too many service's specified for rule, can't add %s", svc_name);
         return;
     }
-    int16_t svc_id = FindProtocolReference(svc_name);
-
-    if ( svc_id == SFTARGET_UNKNOWN_PROTOCOL )
-        svc_id = AddProtocolReference(svc_name);
+    int16_t svc_id = AddProtocolReference(svc_name);
 
     for ( unsigned i = 0; i < otn->sigInfo.num_services; ++i )
         if ( otn->sigInfo.services[i].service_ordinal == svc_id )
index e8832915a8dd67b104c09470b73b22157ce7e8c3..afbd46a08d11fe3266dacd00360f2736b67ac0b4 100644 (file)
@@ -191,42 +191,44 @@ static int FinishPortListRule(
     PortTable* srcTable;
     PortObject* aaObject;
     rule_count_t* prc;
+    uint32_t orig_flags = rtn->flags;
 
     assert(otn->proto == proto);
 
     /* Select the Target PortTable for this rule, based on protocol, src/dst
      * dir, and if there is rule content */
-    if (proto == SNORT_PROTO_TCP)
+    switch ( proto )
     {
+    case SNORT_PROTO_IP:
+        dstTable = port_tables->ip.dst;
+        srcTable = port_tables->ip.src;
+        aaObject = port_tables->ip.any;
+        prc = &ipCnt;
+        break;
+
+    case SNORT_PROTO_ICMP:
+        dstTable = port_tables->icmp.dst;
+        srcTable = port_tables->icmp.src;
+        aaObject = port_tables->icmp.any;
+        prc = &icmpCnt;
+        break;
+
+    case SNORT_PROTO_TCP:
         dstTable = port_tables->tcp.dst;
         srcTable = port_tables->tcp.src;
         aaObject = port_tables->tcp.any;
         prc = &tcpCnt;
-    }
-    else if (proto == SNORT_PROTO_UDP)
-    {
+        break;
+
+    case SNORT_PROTO_UDP:
         dstTable = port_tables->udp.dst;
         srcTable = port_tables->udp.src;
         aaObject = port_tables->udp.any;
         prc = &udpCnt;
-    }
-    else if (proto == SNORT_PROTO_ICMP)
-    {
-        dstTable = port_tables->icmp.dst;
-        srcTable = port_tables->icmp.src;
-        aaObject = port_tables->icmp.any;
-        prc = &icmpCnt;
-    }
-    else if (proto == SNORT_PROTO_IP)
-    {
-        dstTable = port_tables->ip.dst;
-        srcTable = port_tables->ip.src;
-        aaObject = port_tables->ip.any;
-        prc = &ipCnt;
-    }
-    else
-    {
-        rtn->flags |= ANY_DST_PORT|ANY_DST_PORT;
+        break;
+
+    default:
+        rtn->flags |= ANY_SRC_PORT|ANY_DST_PORT;
         dstTable = srcTable = nullptr;
         aaObject = port_tables->svc_any;
         prc = &svcCnt;
@@ -340,6 +342,7 @@ static int FinishPortListRule(
         /* For all protocols-add to the any any group */
         PortObjectAddRule(aaObject, rim_index);
         prc->any++;
+        rtn->flags = orig_flags;
         return 0; /* done */
     }
 
@@ -1281,6 +1284,14 @@ void parse_rule_print()
     LogCount("option chains", otn_count);
     LogCount("chain headers", head_count);
 
+    unsigned ip = ipCnt.src + ipCnt.dst + ipCnt.any + ipCnt.both + ipCnt.nfp;
+    unsigned icmp = icmpCnt.src + icmpCnt.dst + icmpCnt.any + icmpCnt.both + icmpCnt.nfp;
+    unsigned tcp = tcpCnt.src + tcpCnt.dst + tcpCnt.any + tcpCnt.both + tcpCnt.nfp;
+    unsigned udp = udpCnt.src + udpCnt.dst + udpCnt.any + udpCnt.both + udpCnt.nfp;
+
+    if ( !ip and !icmp and !tcp and !udp )
+        return;
+
     LogLabel("port rule counts");
     LogMessage("%8s%8s%8s%8s%8s\n", " ", "tcp", "udp", "icmp", "ip");
 
@@ -1301,14 +1312,9 @@ void parse_rule_print()
             tcpCnt.both, udpCnt.both, icmpCnt.both, ipCnt.both);
 
     if ( tcpCnt.nfp || udpCnt.nfp || icmpCnt.nfp || ipCnt.nfp )
-        LogMessage("%8s%8u%8u%8u%8u\n", "no fp",
+        LogMessage("%8s%8u%8u%8u%8u\n", "slow",
             tcpCnt.nfp, udpCnt.nfp, icmpCnt.nfp, ipCnt.nfp);
 
-    unsigned tcp = tcpCnt.src + tcpCnt.dst + tcpCnt.any + tcpCnt.both + tcpCnt.nfp;
-    unsigned udp = udpCnt.src + udpCnt.dst + udpCnt.any + udpCnt.both + udpCnt.nfp;
-    unsigned icmp = icmpCnt.src + icmpCnt.dst + icmpCnt.any + icmpCnt.both + icmpCnt.nfp;
-    unsigned ip = ipCnt.src + ipCnt.dst + ipCnt.any + ipCnt.both + ipCnt.nfp;
-
     LogMessage("%8s%8u%8u%8u%8u\n", "total", tcp, udp, icmp, ip);
 
     //print_rule_index_map( ruleIndexMap );
@@ -1351,6 +1357,10 @@ void parse_rule_proto(SnortConfig*, const char* s, RuleTreeNode& rtn)
     else if ( !strcmp(s, "ip") )
         rule_proto = PROTO_BIT__IP;
 
+    else
+        // this will allow other protocols like http to have ports
+        rule_proto = PROTO_BIT__TCP;
+
     rtn.proto = AddProtocolReference(s);
 
     if ( rtn.proto <= 0 )
index 21d14028db0674612a0ce44718cf27d49fe8e7ff..152cb4207d9243ca7c0d96f7ad849232b6a13e06 100644 (file)
@@ -359,11 +359,11 @@ static TokenType get_token(
 
 enum FsmAction
 {
-    FSM_ACT, FSM_PRO,
-    FSM_SIP, FSM_SP,
+    FSM_ACT, FSM_PRO,FSM_HDR,
+    FSM_SIP, FSM_SP, FSM_SPX,
     FSM_DIR,
-    FSM_DIP, FSM_DP,
-    FSM_STB, FSM_SOB,
+    FSM_DIP, FSM_DP, FSM_DPX,
+    FSM_SOB, FSM_STB,
     FSM_EOB,
     FSM_KEY, FSM_OPT,
     FSM_VAL, FSM_SET,
@@ -404,14 +404,18 @@ static const State fsm[] =
     { 0, 15, TT_LITERAL, FSM_KEY, "include",  "" },
     { 0,  1, TT_LITERAL, FSM_ACT, nullptr,    "(" },
     { 1,  8, TT_PUNCT,   FSM_STB, "(",        "(:,;)" },
-    { 1,  2, TT_LITERAL, FSM_PRO, nullptr,    "" },
-    { 2,  3, TT_LIST,    FSM_SIP, nullptr,    nullptr },
-    { 2,  3, TT_LITERAL, FSM_SIP, nullptr,    nullptr },
+    { 1,  2, TT_LITERAL, FSM_PRO, nullptr,    "(" },
+    { 2,  8, TT_PUNCT,   FSM_HDR, "(",        "(:,;)" },
+    { 2,  3, TT_LIST,    FSM_SIP, nullptr,    "" },
+    { 2,  3, TT_LITERAL, FSM_SIP, nullptr,    "" },
+    { 3,  5, TT_LITERAL, FSM_SPX, "->",       nullptr },
+    { 3,  5, TT_LITERAL, FSM_SPX, "<>",       nullptr },
     { 3,  4, TT_LIST,    FSM_SP,  nullptr,    nullptr },
     { 3,  4, TT_LITERAL, FSM_SP,  nullptr,    nullptr },
     { 4,  5, TT_LITERAL, FSM_DIR, nullptr,    nullptr },
-    { 5,  6, TT_LIST,    FSM_DIP, nullptr,    nullptr },
-    { 5,  6, TT_LITERAL, FSM_DIP, nullptr,    nullptr },
+    { 5,  6, TT_LIST,    FSM_DIP, nullptr,    "(" },
+    { 5,  6, TT_LITERAL, FSM_DIP, nullptr,    "(" },
+    { 6,  8, TT_PUNCT,   FSM_DPX, "(",        "(:,;)" },
     { 6,  7, TT_LIST,    FSM_DP,  nullptr,    "(:,;)" },
     { 6,  7, TT_LITERAL, FSM_DP,  nullptr,    "(:,;)" },
     { 7,  8, TT_PUNCT,   FSM_SOB, "(",        nullptr },
@@ -456,7 +460,7 @@ static const State* get_state(int num, TokenType type, const string& tok)
             (!s->type || type == s->type) &&
             (!s->match || tok == s->match) )
         {
-            return fsm + i;
+            return s;
         }
     }
     ParseError("syntax error");
@@ -496,12 +500,23 @@ static bool exec(
     case FSM_PRO:
         parse_rule_proto(sc, tok.c_str(), rps.rtn);
         break;
+    case FSM_HDR:
+        parse_rule_nets(sc, "any", true, rps.rtn);
+        parse_rule_ports(sc, "any", true, rps.rtn);
+        parse_rule_dir(sc, "->", rps.rtn);
+        parse_rule_nets(sc, "any", false, rps.rtn);
+        parse_rule_ports(sc, "any", false, rps.rtn);
+        rps.otn = parse_rule_open(sc, rps.rtn);
+        break;
     case FSM_SIP:
         parse_rule_nets(sc, tok.c_str(), true, rps.rtn);
         break;
     case FSM_SP:
         parse_rule_ports(sc, tok.c_str(), true, rps.rtn);
         break;
+    case FSM_SPX:
+        parse_rule_ports(sc, "any", true, rps.rtn);
+        // fall thru ...
     case FSM_DIR:
         parse_rule_dir(sc, tok.c_str(), rps.rtn);
         break;
@@ -511,12 +526,15 @@ static bool exec(
     case FSM_DP:
         parse_rule_ports(sc, tok.c_str(), false, rps.rtn);
         break;
-    case FSM_STB:
-        rps.otn = parse_rule_open(sc, rps.rtn, true);
-        break;
+    case FSM_DPX:
+        parse_rule_ports(sc, "any", false, rps.rtn);
+        // fall thru ...
     case FSM_SOB:
         rps.otn = parse_rule_open(sc, rps.rtn);
         break;
+    case FSM_STB:
+        rps.otn = parse_rule_open(sc, rps.rtn, true);
+        break;
     case FSM_EOB:
     {
         if ( rps.tbd )
index bc6bae66af782a89416e5d5c8b26836be569997e..0cf3c65fc180f8ef13e2d6cf1994e13c883768f2 100644 (file)
@@ -219,8 +219,12 @@ PortObject2* PortObject2Dup(PortObject* po)
             poi =(PortObjectItem*)sflist_next(&lpos) )
         {
             poinew = PortObjectItemDup(poi);
+
             if (!poinew)
-                return 0;
+            {
+                free(ponew);
+                return NULL;
+            }
 
             PortObjectAddItem( (PortObject*)ponew, poinew, NULL);
         }
@@ -236,6 +240,7 @@ PortObject2* PortObject2Dup(PortObject* po)
             prule = (int*)calloc(1,sizeof(int));
             if (!prule)
             {
+                free(ponew);
                 return NULL;
             }
             *prule = *prid;
index d1d29c47eb274d546b28cf554d27779ea1ef8d55..ce53cdf44dee31288924fe39a188fa9fb36b8f5c 100644 (file)
@@ -817,7 +817,7 @@ static int _bnfa_opt_nfa(bnfa_struct_t* bnfa)
             FailState[ k ] = fs;
         }
     }
-#ifdef DEBUG
+#if 0
     if ( cnt)
         LogMessage("ac-bnfa: %d nfa optimizations found in %d states\n",cnt,bnfa->bnfaNumStates);
 #endif
index cd15a9b0baf91b093be9c6b551b38d0560d76655..bfa864a64855f680a2cc80d045c01159142d8f93 100644 (file)
@@ -24,6 +24,7 @@ if (STATIC_INSPECTORS)
         rpc_decode
         smtp
         ssh
+        ssl
         wizard
     )
 endif()
index f8f564693b89c921fa1d855780dad0437142905e..0b74f03b5d5176791d51ab07573a7c83fa66fc57 100644 (file)
@@ -1125,6 +1125,9 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p)
     if ( iCallDetect == 0 )
     {
         /* snort_detect called at least once from above pkt processing loop. */
+        // FIXIT this throws off nfp rules like this:
+        // alert tcp any any -> any any ( sid:1; msg:"1"; flags:S; )
+        // (check shutdown counts)
         DisableInspection(p);
     }
 
index d005bd7f77cc34c28ebb53a82606c97fa46e03bc..24a9dc8ae4864e993ddb5e28c2c8848be5aa53fa 100644 (file)
@@ -834,9 +834,11 @@ static void hi_pipe_pop(Hi5State* s_rsp, Flow* ssn)
     DEBUG_WRAP(DebugMessage(DEBUG_STREAM_PAF,
         "%s: nreq=%d, pipe=0x%X\n", __FUNCTION__, nreq, pipe); )
 
+    // FIXIT-L valgrind: Conditional jump or move depends on uninitialised value(s)
     if ( nreq == 0 || nreq == PIPELINE_RUPTURED )
         return;
 
+    // FIXIT-L valgrind: Conditional jump or move depends on uninitialised value(s)
     if ( --nreq < MAX_PIPELINE )
     {
         if ( pipe & 0x1 )
index 7b2b467442ec8f661bb20d006d9b39525b77a312..00baff916987007556cd034a3f5b5fba2d03654d 100644 (file)
@@ -49,6 +49,7 @@
 #include "search_engines/search_tool.h"
 #include "sf_email_attach_decode.h"
 #include "protocols/ssl.h"
+#include "file_api/file_mime_process.h"
 
 THREAD_LOCAL ProfileStats imapPerfStats;
 THREAD_LOCAL SimpleStats imapstats;
@@ -139,6 +140,12 @@ void IMAP_DecodeAlert(void* ds);
 
 MimeMethods imap_mime_methods = { NULL, NULL, IMAP_DecodeAlert, IMAP_ResetState, imap_is_data_end };
 
+ImapFlowData::ImapFlowData() : FlowData(flow_id)
+{ memset(&session, 0, sizeof(session)); }
+
+ImapFlowData::~ImapFlowData()
+{ free_mime_session(session.mime_ssn); }
+
 unsigned ImapFlowData::flow_id = 0;
 static IMAPData* get_session_data(Flow* flow)
 {
index 5ee11eb023ff3879e7f9b8ab670a290c3b818659..61b31c83c4ab37095004b0115d0c33e9db4f0428 100644 (file)
@@ -181,10 +181,8 @@ struct IMAPData
 class ImapFlowData : public FlowData
 {
 public:
-    ImapFlowData() : FlowData(flow_id)
-    { memset(&session, 0, sizeof(session)); }
-
-    ~ImapFlowData() { }
+    ImapFlowData();
+    ~ImapFlowData();
 
     static void init()
     { flow_id = FlowData::get_flow_id(); }
@@ -194,5 +192,5 @@ public:
     IMAPData session;
 };
 
-#endif /* IMAP_H */
+#endif
 
index e11eba09344e435ae32c2e749762b70b61d19034..56c72964176e146558a59d828bff9c966df9b942 100644 (file)
@@ -47,6 +47,7 @@
 #include "search_engines/search_tool.h"
 #include "sf_email_attach_decode.h"
 #include "protocols/ssl.h"
+#include "file_api/file_mime_process.h"
 
 THREAD_LOCAL ProfileStats popPerfStats;
 THREAD_LOCAL SimpleStats popstats;
@@ -92,6 +93,12 @@ void POP_DecodeAlert(void* ds);
 
 MimeMethods pop_mime_methods = { NULL, NULL, POP_DecodeAlert, POP_ResetState, pop_is_data_end };
 
+PopFlowData::PopFlowData() : FlowData(flow_id)
+{ memset(&session, 0, sizeof(session)); }
+
+PopFlowData::~PopFlowData()
+{ free_mime_session(session.mime_ssn); }
+
 unsigned PopFlowData::flow_id = 0;
 static POPData* get_session_data(Flow* flow)
 {
index 61aa049e18760289d73255325df598caae48a772..47d6eb4eaa64fc469764767d7883c95eb724ef4c 100644 (file)
@@ -137,10 +137,8 @@ struct POPData
 class PopFlowData : public FlowData
 {
 public:
-    PopFlowData() : FlowData(flow_id)
-    { memset(&session, 0, sizeof(session)); }
-
-    ~PopFlowData() { }
+    PopFlowData();
+    ~PopFlowData();
 
     static void init()
     { flow_id = FlowData::get_flow_id(); }
@@ -150,5 +148,5 @@ public:
     POPData session;
 };
 
-#endif /* POP_H */
+#endif
 
index ed03b9327dfbed846dc47e9a64180fdaafc7761b..8a3eb81c02f8f03730b5777f5b3d2099595f08eb 100644 (file)
@@ -46,6 +46,7 @@
 #include "protocols/ssl.h"
 #include "unified2_common.h"
 #include "detection/detection_util.h"
+#include "file_api/file_mime_process.h"
 
 THREAD_LOCAL ProfileStats smtpPerfStats;
 THREAD_LOCAL SimpleStats smtpstats;
@@ -170,6 +171,12 @@ static int SMTP_NormalizeData(void* conf, const uint8_t* ptr, const uint8_t* dat
 MimeMethods smtp_mime_methods = { SMTP_HandleHeaderLine, SMTP_NormalizeData, SMTP_DecodeAlert,
                                   SMTP_ResetState, smtp_is_data_end };
 
+SmtpFlowData::SmtpFlowData() : FlowData(flow_id)
+{ memset(&session, 0, sizeof(session)); }
+
+SmtpFlowData::~SmtpFlowData()
+{ free_mime_session(session.mime_ssn); }
+
 unsigned SmtpFlowData::flow_id = 0;
 static SMTPData* get_session_data(Flow* flow)
 {
@@ -226,21 +233,16 @@ void SMTP_DecodeAlert(void* ds)
     }
 }
 
-void SMTP_InitCmds(SMTP_PROTO_CONF* config)
+static void SMTP_InitCmds(SMTP_PROTO_CONF* config)
 {
-    const SMTPToken* tmp;
-
     if (config == NULL)
         return;
 
-    /* add one to CMD_LAST for NULL entry */
-    config->cmds = (SMTPToken*)calloc(CMD_LAST + 1, sizeof(SMTPToken));
-    if (config->cmds == NULL)
-    {
-        FatalError("Could not allocate memory for SMTP Command structure.\n");
-    }
+    config->cmd_config = (SMTPCmdConfig*)SnortAlloc(CMD_LAST * sizeof(SMTPCmdConfig));
+    config->cmd_search = (SMTPSearch*)SnortAlloc(CMD_LAST * sizeof(SMTPSearch));
+    config->cmds = (SMTPToken*)SnortAlloc((CMD_LAST + 1) * sizeof(SMTPToken));
 
-    for (tmp = &smtp_known_cmds[0]; tmp->name != NULL; tmp++)
+    for (const SMTPToken* tmp = &smtp_known_cmds[0]; tmp->name != NULL; tmp++)
     {
         config->cmds[tmp->search_id].name_len = tmp->name_len;
         config->cmds[tmp->search_id].search_id = tmp->search_id;
@@ -248,29 +250,27 @@ void SMTP_InitCmds(SMTP_PROTO_CONF* config)
         config->cmds[tmp->search_id].type = tmp->type;
 
         if (config->cmds[tmp->search_id].name == NULL)
-        {
             FatalError("Could not allocate memory for SMTP Command structure.\n");
-        }
-    }
-
-    /* initialize memory for command searches */
-    config->cmd_search = (SMTPSearch*)calloc(CMD_LAST, sizeof(SMTPSearch));
-    if (config->cmd_search == NULL)
-    {
-        FatalError("Could not allocate memory for SMTP Command Structure.\n");
     }
 
     config->num_cmds = CMD_LAST;
 }
 
-void SMTP_CommandSearchInit(SMTP_PROTO_CONF* config)
+static void SMTP_TermCmds(SMTP_PROTO_CONF* config)
+{
+    for ( int i = 0; i <= CMD_LAST; ++i )
+        free((char*)config->cmds[i].name);
+
+    free(config->cmds);
+    free(config->cmd_search);
+    free(config->cmd_config);
+}
+
+static void SMTP_CommandSearchInit(SMTP_PROTO_CONF* config)
 {
     const SMTPToken* tmp;
     config->cmd_search_mpse = new SearchTool();
-    if (config->cmd_search_mpse == NULL)
-    {
-        FatalError("Could not allocate memory for SMTP Command search.\n");
-    }
+
     for (tmp = config->cmds; tmp->name != NULL; tmp++)
     {
         config->cmd_search[tmp->search_id].name = (char *)tmp->name;
@@ -281,6 +281,11 @@ void SMTP_CommandSearchInit(SMTP_PROTO_CONF* config)
     config->cmd_search_mpse->prep();
 }
 
+static void SMTP_CommandSearchTerm(SMTP_PROTO_CONF* config)
+{
+    delete config->cmd_search_mpse;
+}
+
 void SMTP_ResponseSearchInit(void)
 {
     const SMTPToken* tmp;
@@ -314,24 +319,10 @@ static int AddCmd(SMTP_PROTO_CONF* config, const char* name, SMTPCmdTypeEnum typ
     config->num_cmds++;
 
     /* allocate enough memory for new commmand - alloc one extra for NULL entry */
-    cmds = (SMTPToken*)calloc(config->num_cmds + 1, sizeof(SMTPToken));
-    if (cmds == NULL)
-    {
-        FatalError("Failed to allocate memory for SMTP command structure\n");
-    }
-
-    /* This gets filled in later */
-    cmd_search = (SMTPSearch*)calloc(config->num_cmds, sizeof(SMTPSearch));
-    if (cmd_search == NULL)
-    {
-        FatalError("Failed to allocate memory for SMTP command structure\n");
-    }
-
-    cmd_config = (SMTPCmdConfig*)calloc(config->num_cmds, sizeof(SMTPCmdConfig));
-    if (cmd_config == NULL)
-    {
-        FatalError("Failed to allocate memory for SMTP command structure\n");
-    }
+    // FIXIT-L this constant reallocation is not necessary; use vector
+    cmds = (SMTPToken*)SnortAlloc((config->num_cmds + 1) * sizeof(SMTPToken));
+    cmd_search = (SMTPSearch*)SnortAlloc(config->num_cmds * sizeof(SMTPSearch));
+    cmd_config = (SMTPCmdConfig*)SnortAlloc(config->num_cmds * sizeof(SMTPCmdConfig));
 
     /* copy existing commands into newly allocated memory
      *      * don't need to copy anything from cmd_search since this hasn't been initialized yet */
@@ -404,38 +395,6 @@ static int GetCmdId(SMTP_PROTO_CONF* config, const char* name, SMTPCmdTypeEnum t
     return AddCmd(config, name, type);
 }
 
-void ProcessSmtpCmdsList(SMTP_PROTO_CONF* config, const SmtpCmd* sc)
-{
-    const char* cmd = sc->name.c_str();
-    int id;
-    SMTPCmdTypeEnum type;
-
-    if ( sc->flags & PCMD_AUTH )
-        type = SMTP_CMD_TYPE_AUTH;
-
-    else if (  sc->flags & PCMD_BDATA )
-        type = SMTP_CMD_TYPE_BDATA;
-
-    else if (  sc->flags & PCMD_DATA )
-        type = SMTP_CMD_TYPE_DATA;
-
-    else
-        type = SMTP_CMD_TYPE_NORMAL;
-
-    id = GetCmdId(config, cmd, type);
-    if (  sc->flags & PCMD_INVALID )
-        config->cmd_config[id].alert = true;
-
-    else if ( sc->flags & PCMD_NORM )
-        config->cmd_config[id].normalize = true;
-
-    else
-        config->cmd_config[id].alert = false;
-
-    if ( sc->flags & PCMD_ALT )
-        config->cmd_config[id].max_line_len = sc->number;
-}
-
 void SMTP_PrintConfig(SMTP_PROTO_CONF *config)
 {
     const SMTPToken* cmd;
@@ -1630,6 +1589,8 @@ public:
     StreamSplitter* get_splitter(bool c2s) override
     { return new SmtpSplitter(c2s); }
 
+    void ProcessSmtpCmdsList(const SmtpCmd*);
+
 private:
     SMTP_PROTO_CONF* config;
 };
@@ -1637,12 +1598,18 @@ private:
 Smtp::Smtp(SMTP_PROTO_CONF* pc)
 {
     config = pc;
+
+    SMTP_RegXtraDataFuncs(config);
+    SMTP_InitCmds(config);
+    SMTP_CommandSearchInit(config);
 }
 
 Smtp::~Smtp()
 {
-    if ( config )
-        delete config;
+    SMTP_CommandSearchTerm(config);
+    SMTP_TermCmds(config);
+
+    delete config;
 }
 
 bool Smtp::configure(SnortConfig*)
@@ -1698,6 +1665,38 @@ void Smtp::clear(Packet*)
     SMTP_ResetAltBuffer();
 }
 
+void Smtp::ProcessSmtpCmdsList(const SmtpCmd* sc)
+{
+    const char* cmd = sc->name.c_str();
+    int id;
+    SMTPCmdTypeEnum type;
+
+    if ( sc->flags & PCMD_AUTH )
+        type = SMTP_CMD_TYPE_AUTH;
+
+    else if (  sc->flags & PCMD_BDATA )
+        type = SMTP_CMD_TYPE_BDATA;
+
+    else if (  sc->flags & PCMD_DATA )
+        type = SMTP_CMD_TYPE_DATA;
+
+    else
+        type = SMTP_CMD_TYPE_NORMAL;
+
+    id = GetCmdId(config, cmd, type);
+    if (  sc->flags & PCMD_INVALID )
+        config->cmd_config[id].alert = true;
+
+    else if ( sc->flags & PCMD_NORM )
+        config->cmd_config[id].normalize = true;
+
+    else
+        config->cmd_config[id].alert = false;
+
+    if ( sc->flags & PCMD_ALT )
+        config->cmd_config[id].max_line_len = sc->number;
+}
+
 //-------------------------------------------------------------------------
 // api stuff
 //-------------------------------------------------------------------------
@@ -1723,16 +1722,14 @@ static Inspector* smtp_ctor(Module* m)
 {
     SmtpModule* mod = (SmtpModule*)m;
     SMTP_PROTO_CONF* conf = mod->get_data();
+    Smtp* smtp = new Smtp(conf);
+
     unsigned i = 0;
-    SMTP_RegXtraDataFuncs(conf);
-    SMTP_InitCmds(conf);
 
     while ( const SmtpCmd* cmd = mod->get_cmd(i++) )
-        ProcessSmtpCmdsList(conf, cmd);
-
-    SMTP_CommandSearchInit(conf);
+        smtp->ProcessSmtpCmdsList(cmd);
 
-    return new Smtp(conf);
+    return smtp;
 }
 
 static void smtp_dtor(Inspector* p)
index b8bfe8581aa809fde9158c2a8a82f6598c8cfcbd..65198cf5581be505eadc2156f139fd148c4fb140 100644 (file)
@@ -162,10 +162,8 @@ struct SMTPData
 class SmtpFlowData : public FlowData
 {
 public:
-    SmtpFlowData() : FlowData(flow_id)
-    { memset(&session, 0, sizeof(session)); }
-
-    ~SmtpFlowData() { }
+    SmtpFlowData();
+    ~SmtpFlowData();
 
     static void init()
     { flow_id = FlowData::get_flow_id(); }
index 07121bd058616979a2d94284d51f86202ba8b62f..349a965bf29d70bdb67aedf8e8481c3c76ba39fe 100644 (file)
@@ -175,25 +175,13 @@ SmtpModule::~SmtpModule()
 {
     if ( config )
     {
-        if (config->cmds != NULL)
+        if ( config->cmds )
         {
-            SMTPToken* tmp = config->cmds;
-
-            for (; tmp->name != NULL; tmp++)
+            for ( SMTPToken* tmp = config->cmds; tmp->name; tmp++)
                 free((char *)tmp->name);
 
             free(config->cmds);
         }
-
-        if (config->cmd_config != NULL)
-            free(config->cmd_config);
-
-        if (config->cmd_search_mpse != NULL)
-            delete config->cmd_search_mpse;
-
-        if (config->cmd_search != NULL)
-            free(config->cmd_search);
-
         delete config;
     }
 
@@ -354,11 +342,6 @@ bool SmtpModule::begin(const char*, int, SnortConfig*)
         file_api->set_mime_decode_config_defauts(&(config->decode_conf));
         file_api->set_mime_log_config_defauts(&(config->log_config));
         config->log_config.email_hdrs_log_depth = 1464;
-        config->cmd_config = (SMTPCmdConfig*)calloc(CMD_LAST, sizeof(SMTPCmdConfig));
-        if (config->cmd_config == NULL)
-        {
-            FatalError("Failed to allocate memory for SMTP command structure\n");
-        }
     }
 
     return true;
index 1e3626484252a8288616f6a945daa3512381045e..31163f528eaf04750dc541d49bf290d25a70d581 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "snort_types.h"
 #include "stream/stream_api.h"
-#include "target_based/snort_protocols.h"
 #include "network_inspectors/normalize/norm.h"
 
 //#define DEBUG_STREAM DEBUG
@@ -76,7 +75,6 @@ struct StreamConfig
     class Stream* stream;
 
     struct StreamGlobalConfig* global_config;
-    uint8_t service_filter[MAX_PROTOCOL_ORDINAL];
 };
 
 // shared stream state
index ea298fe938f401755247c3d52fa04f2d91e6f886..b9ac60d283e6add846b93c9456cca8114d111c29 100644 (file)
@@ -343,7 +343,7 @@ static inline bool DataToFlush (const TcpTracker* st)
 {
     // needed by stream_reassemble:action disable; can fire on rebuilt
     // packets, yanking the splitter out from under us :(
-    if ( !st->flush_policy )
+    if ( !st->flush_policy or !st->splitter )
         return false;
 
     if (
index e3aba9a988cbc5528adcea3d7d351261406d1423..0cadcda7adf83c5c73453be5c9ab2d08b4c8ce6b 100644 (file)
@@ -43,6 +43,9 @@ struct SFTargetProtocolReference
 static SFGHASH* proto_reference_table = NULL;  // STATIC
 static int16_t protocol_number = 1;
 
+int16_t get_protocol_count()
+{ return protocol_number; }
+
 static vector<string> id_map;
 
 const char* get_protocol_name(uint16_t id)
@@ -101,22 +104,6 @@ int16_t AddProtocolReference(const char* protocol)
 
     reference = (SFTargetProtocolReference*)SnortAlloc(sizeof(SFTargetProtocolReference));
     reference->ordinal = protocol_number++;
-    if (protocol_number > MAX_PROTOCOL_ORDINAL)
-    {
-        /* XXX: If we see this warning message, should
-        * increase MAX_PROTOCOL_ORDINAL definition.  The ordinal is
-        * stored as a signed 16bit int, so it can be increased upto
-        * 32k without requiring a change in space.  It is currently
-        * defined as 8192.
-        */
-        LogMessage("WARNING: protocol_number wrapped.   This may result"
-            "in odd behavior and potential false positives.\n");
-
-        /* 1 is the first protocol id we use.
-           0 is not used
-           -1 means unknwon */
-        protocol_number = 1;
-    }
     SnortStrncpy(reference->name, protocol, SFAT_BUFSZ);
 
     sfghash_add(proto_reference_table, reference->name, reference);
@@ -157,22 +144,19 @@ void InitializeProtocolReferenceTable(void)
         FatalError("Failed to Initialize Target-Based Protocol Reference Table\n");
     }
 
-    int16_t proto;
-
-    proto = AddProtocolReference("ip");
-    assert(proto == SNORT_PROTO_IP);
-
-    proto = AddProtocolReference("icmp");
-    assert(proto == SNORT_PROTO_ICMP);
+    bool ok;
 
-    proto = AddProtocolReference("tcp");
-    assert(proto == SNORT_PROTO_TCP);
+    ok = ( AddProtocolReference("ip") == SNORT_PROTO_IP );
+    ok = ( AddProtocolReference("icmp") == SNORT_PROTO_ICMP ) and ok;
+    ok = ( AddProtocolReference("tcp") == SNORT_PROTO_TCP ) and ok;
+    ok = ( AddProtocolReference("udp") == SNORT_PROTO_UDP ) and ok;
+    ok = ( AddProtocolReference("user") == SNORT_PROTO_USER ) and ok;
+    ok = ( AddProtocolReference("file") == SNORT_PROTO_FILE ) and ok;
 
-    proto = AddProtocolReference("udp");
-    assert(proto == SNORT_PROTO_UDP);
+    assert(ok);
 
-    proto = AddProtocolReference("file");
-    assert(proto == SNORT_PROTO_FILE);
+    if ( !ok )
+        FatalError("standard protocol reference mismatch");
 }
 
 void FreeProtoocolReferenceTable(void)
index 95f92f21ca6ce6d5ed05a215229daaea118ebf64..abf24022f0a65caf04488ebce855294385287404 100644 (file)
 
 #include "snort_types.h"
 
-#define MAX_PROTOCOL_ORDINAL 8192  // FIXIT-L use std::vector and eliminate this
-
 // FIXIT-L use logical type instead of int16_t
 // for all reference protocols
 
 // these protocols are always defined because
 // they are used as consts in switch statements
 // other protos are added dynamically as used
-const int16_t SNORT_PROTO_IP   = 1;
-const int16_t SNORT_PROTO_ICMP = 2;
-const int16_t SNORT_PROTO_TCP  = 3;
-const int16_t SNORT_PROTO_UDP  = 4;
-const int16_t SNORT_PROTO_FILE = 5;
+enum SnortProtocols
+{
+    SNORT_PROTO_IP = 1,
+    SNORT_PROTO_ICMP,
+    SNORT_PROTO_TCP,
+    SNORT_PROTO_UDP,
+    SNORT_PROTO_USER,
+    SNORT_PROTO_FILE,
+    SNORT_PROTO_MAX
+};
 
 static inline bool is_network_protocol(int16_t proto)
-{ return (proto > 0 and proto < SNORT_PROTO_FILE); }
+{ return (proto >= SNORT_PROTO_IP and proto <= SNORT_PROTO_UDP); }
 
 static inline bool is_service_protocol(int16_t proto)
 { return !is_network_protocol(proto); }
@@ -47,6 +50,8 @@ static inline bool is_service_protocol(int16_t proto)
 void InitializeProtocolReferenceTable(void);
 void FreeProtoocolReferenceTable(void);
 
+int16_t get_protocol_count();
+
 const char* get_protocol_name(uint16_t id);
 const char* get_protocol_name_sorted(uint16_t id);
 
index e1ce6bd72aed99098c28771f4873db9afb12f14f..6f4183c493c5f0dae8b983d63c322e6be009c161 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "sf_email_attach_decode.h"
 
+#include <assert.h>
+
 #include "snort_types.h"
 #include "util.h"
 
@@ -90,7 +92,7 @@ int sf_qpdecode(char* src, uint32_t slen, char* dst, uint32_t dlen, uint32_t* by
                 return 0;
             }
         }
-        else if (isprint(ch) || isblank(ch))
+        else if ( isprint(ch) || isblank(ch) || ch == '\r' || ch == '\n' )
         {
             dst[*bytes_copied] = ch;
             *bytes_copied +=1;
@@ -234,8 +236,7 @@ int Base64Decode(const uint8_t* start, const uint8_t* end, Email_DecodeState* ds
 
     if (!(ds->b64_state.encode_depth))
     {
-        encode_avail = MAX_BUF;
-        decode_avail = MAX_BUF;
+        encode_avail = decode_avail = ds->buf_size;
     }
     else if ((ds->b64_state.encode_depth) < 0)
     {
@@ -245,6 +246,7 @@ int Base64Decode(const uint8_t* start, const uint8_t* end, Email_DecodeState* ds
     {
         encode_avail = ds->b64_state.encode_depth - ds->b64_state.encode_bytes_read;
         decode_avail = ds->b64_state.decode_depth - ds->b64_state.decode_bytes_read;
+        assert(decode_avail <= ds->buf_size);
     }
 
     encode_buf = ds->encodeBuf;
@@ -331,8 +333,7 @@ int QPDecode(const uint8_t* start, const uint8_t* end, Email_DecodeState* ds)
 
     if (!(ds->qp_state.encode_depth))
     {
-        encode_avail = MAX_BUF;
-        decode_avail = MAX_BUF;
+        encode_avail = decode_avail = ds->buf_size;
     }
     else if ((ds->qp_state.encode_depth) < 0)
     {
@@ -342,6 +343,7 @@ int QPDecode(const uint8_t* start, const uint8_t* end, Email_DecodeState* ds)
     {
         encode_avail = ds->qp_state.encode_depth - ds->qp_state.encode_bytes_read;
         decode_avail = ds->qp_state.decode_depth - ds->qp_state.decode_bytes_read;
+        assert(decode_avail <= ds->buf_size);
     }
 
     encode_buf = ds->encodeBuf;
@@ -424,8 +426,7 @@ int UUDecode(const uint8_t* start, const uint8_t* end, Email_DecodeState* ds)
 
     if (!(ds->uu_state.encode_depth))
     {
-        encode_avail = MAX_BUF;
-        decode_avail = MAX_BUF;
+        encode_avail = decode_avail = ds->buf_size;
     }
     else if ((ds->uu_state.encode_depth) < 0)
     {
@@ -436,6 +437,7 @@ int UUDecode(const uint8_t* start, const uint8_t* end, Email_DecodeState* ds)
     {
         encode_avail = ds->uu_state.encode_depth - ds->uu_state.encode_bytes_read;
         decode_avail = ds->uu_state.decode_depth - ds->uu_state.decode_bytes_read;
+        assert(decode_avail <= ds->buf_size);
     }
 
     encode_buf = ds->encodeBuf;
@@ -534,11 +536,15 @@ int BitEncExtract(const uint8_t* start, const uint8_t* end, Email_DecodeState* d
 
     ClearPrevEncodeBuf(ds);
 
+    if ( (start < ds->decodeBuf) or (start - ds->decodeBuf >= ds->buf_size) )
+        return DECODE_EXCEEDED;
+
     if (!(ds->bitenc_state.depth))
     {
-        bytes_avail = MAX_BUF;
+        bytes_avail = ds->buf_size;
     }
-    else if ((ds->bitenc_state.depth) < 0)
+    // FIXIT-L this check on start should be obviated by use better member functions
+    else if ( ds->bitenc_state.depth < 0 )
     {
         return DECODE_EXCEEDED;
     }
@@ -565,7 +571,6 @@ int BitEncExtract(const uint8_t* start, const uint8_t* end, Email_DecodeState* d
     }
 
     ds->decode_present = 1;
-    ds->decodePtr = (uint8_t*)start;
     ds->decoded_bytes = act_size;
     ds->bitenc_state.bytes_read += act_size;
 
index c47a53506aac9738d179beeb749850ec988ae447..e9834061c53606447b79c6605022ff475e383cec 100644 (file)
@@ -78,8 +78,9 @@ struct Email_DecodeState
     DecodeType decode_type;
     uint8_t decode_present;
     uint32_t prev_encoded_bytes;
-    unsigned char* prev_encoded_buf;
     uint32_t decoded_bytes;
+    uint32_t buf_size;
+    uint8_t* prev_encoded_buf;
     uint8_t* encodeBuf;
     uint8_t* decodeBuf;
     uint8_t* decodePtr;
@@ -111,13 +112,10 @@ static inline int getCodeDepth(int code_depth, int64_t file_depth)
         return code_depth;
 }
 
-static inline void SetEmailDecodeState(Email_DecodeState* ds, void* data, int max_depth,
+static inline void SetEmailDecodeState(Email_DecodeState* ds, void* data, int buf_size,
     int b64_depth, int qp_depth, int uu_depth, int bitenc_depth, int64_t file_depth)
 {
-    if ( max_depth & 7 )
-    {
-        max_depth += (8 - (max_depth & 7));
-    }
+    buf_size = buf_size & ~7; // FIXIT-L is this still required?
 
     ds->decode_type = DECODE_NONE;
     ds->decode_present = 0;
@@ -126,8 +124,8 @@ static inline void SetEmailDecodeState(Email_DecodeState* ds, void* data, int ma
     ds->decoded_bytes = 0;
 
     ds->encodeBuf = (uint8_t*)data;
-    ds->decodeBuf = (uint8_t*)data + max_depth;
-    ds->decodePtr = ds->decodeBuf;
+    ds->decodeBuf = (uint8_t*)data + buf_size;
+    ds->buf_size = buf_size;
 
     ds->b64_state.encode_depth = ds->b64_state.decode_depth = getCodeDepth(b64_depth, file_depth);
     ds->b64_state.encode_bytes_read = ds->b64_state.decode_bytes_read = 0;
@@ -149,13 +147,14 @@ static inline Email_DecodeState* NewEmailDecodeState(
     int uu_depth, int bitenc_depth, int64_t file_depth)
 {
     Email_DecodeState* ds = (Email_DecodeState*)calloc(1, sizeof(*ds) + (2*max_depth));
-    uint8_t* data = ((uint8_t*)ds) + sizeof(*ds);
 
     if ( ds )
+    {
+        uint8_t* data = ((uint8_t*)ds) + sizeof(*ds);
         SetEmailDecodeState(
             ds, data, max_depth, b64_depth, qp_depth,
             uu_depth, bitenc_depth, file_depth);
-
+    }
     return ds;
 }
 
@@ -194,7 +193,7 @@ static inline void ResetBytesRead(Email_DecodeState* ds)
 
 static inline void ResetDecodedBytes(Email_DecodeState* ds)
 {
-    ds->decodePtr = NULL;
+    ds->decodePtr = nullptr;
     ds->decoded_bytes = 0;
     ds->decode_present = 0;
 }
index 09a367cc59307421b17a87977bc95da774a4ef2d..0041043322995fade141cfe405119ebed972604c 100644 (file)
@@ -211,8 +211,11 @@ const PegInfo daq_names[] =
 const PegInfo pc_names[] =
 {
     { "analyzed", "packets sent to detection" },
+    { "slow searches", "non-fast pattern rule evaluations" },
     { "raw searches", "fast pattern searches in raw packet data" },
-    { "alt searches", "alt fast pattern searches in raw packet data" },
+    { "cooked searches", "fast pattern searches in cooked packet data" },
+    { "pkt searches", "fast pattern searches in packet data" },
+    { "alt searches", "alt fast pattern searches in packet data" },
     { "key searches", "fast pattern searches in key buffer" },
     { "header searches", "fast pattern searches in header buffer" },
     { "body searches", "fast pattern searches in body buffer" },
index 7d2b579ecb1bd0daa2d3a5969221af696726329b..5257a2b3964e4fb6c2cf688832dca5d819b06455 100644 (file)
 struct PacketCount
 {
     PegCount total_from_daq;
+    PegCount slow_searches;
     PegCount raw_searches;
+    PegCount cooked_searches;
+    PegCount pkt_searches;
     PegCount alt_searches;
     PegCount key_searches;
     PegCount header_searches;