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
# 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)
{ 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 } } },
{ 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 } } },
{ 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 } } },
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 */
}
}
{
memset(this, 0, sizeof(*this));
- inspect_stream_insert = 1;
+ inspect_stream_insert = false;
max_queue_events = 5;
bleedover_port_limit = 1024;
}
FastPatternConfig::~FastPatternConfig()
-{
-}
+{ }
int FastPatternConfig::set_detect_search_method(const char* method)
{
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
#include "search/intel_soft_cpm.h"
#endif
+static unsigned mpse_count = 0;
+
static void fpDeletePMX(void* data);
static int fpGetFinalPattern(FastPatternConfig*, PatternMatchData* pmd,
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)
if ( ofl->type != RULE_OPTION_TYPE_CONTENT )
continue;
+ content = true;
PatternMatchData* tmp = get_pmd(ofl);
assert(tmp);
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)
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);
}
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;
}
free(sc->prmUdpRTNX);
sc->prmUdpRTNX = NULL;
}
-
- if (sc->prmSvcRTNX != NULL)
- {
- free(sc->prmSvcRTNX);
- sc->prmUdpRTNX = NULL;
- }
}
static int fpGetFinalPattern(
*
*/
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;
n=sfghash_findnext(srm) )
{
list = (SF_LIST*)n->data;
+
if (!list)
continue;
srvc = (char*)n->key;
+
if (!srvc)
continue;
/* 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;
}
}
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");
+ }
}
/*
}
}
-static void fpPrintServiceRuleMapTable(SFGHASH* p, const char* msg)
+static void fpPrintServiceRuleMapTable(SFGHASH* p, const char* proto, const char* dir)
{
SFGHASH_NODE* n;
return;
std::string label = "service rule counts - ";
- label += msg;
+ label += proto;
+ label += " ";
+ label += dir;
LogLabel(label.c_str());
for ( n = sfghash_findfirst(p);
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)
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])
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;
*/
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());
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);
ServiceMapFree(sc->srmmTable);
ServicePortGroupMapFree(sc->spgmmTable);
- if (sc->sopgTable != NULL)
- free(sc->sopgTable);
+
+ if ( sc->sopgTable )
+ delete sc->sopgTable;
}
/*
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;
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");
LogMessage(" Final pattern\n");
LogMessage(" %s\n", PatternRawToContent(pattern, pattern_length));
+#endif
}
void fpDeletePortGroup(void*);
bool set_fp_content(struct OptTreeNode*);
-const char* PatternRawToContent(const char* pattern, int pattern_len);
#endif
** 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;
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;
}
/*
MODULE_PROFILE_START(ruleRTNEvalPerfStats);
- if (rtn == NULL)
+ if ( !rtn )
{
MODULE_PROFILE_END(ruleRTNEvalPerfStats);
return 0;
* 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;
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,
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
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 )
{
if (o->matchInfo[i].MatchArray[k] == otn)
{
- otn = NULL;
+ otn = nullptr;
break;
}
}
}
/* 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;
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
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
**
*/
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;
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();
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;
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 */
}
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;
}
/*
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)
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;
}
#include "fp_create.h"
#include "snort_config.h"
-#define ANYPORT -1
-
/*
**
** NAME
#include "protocols/packet.h"
#include "ports/port_group.h"
+#define ANYPORT (-1)
+
struct PORT_RULE_MAP
{
int prmNumDstRules;
#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.
*
*/
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);
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");
}
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;
}
#ifndef SERVICE_MAP_H
#define SERVICE_MAP_H
+#include <vector>
+
#include "detection/pcrm.h"
#include "target_based/snort_protocols.h"
// 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();
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
{
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,
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);
}
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*/
File_Verdict verdict = FILE_VERDICT_UNKNOWN;
if (!pkt)
+ {
+ finish_signature_lookup(context);
return;
+ }
if (file_signature_cb)
{
int i;
uint64_t processed_total[2];
uint64_t processed_data_total[2];
- uint64_t verdicts_total;
if (!file_stats.files_total)
return;
if ( !check_total )
return;
- LogLabel("file type stats (files):");
+ LogLabel("file type stats (files)");
LogMessage(" Type Download Upload \n");
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");
if ( !check_total )
return;
- LogLabel("file signature stats:\n");
+ LogLabel("file signature stats");
LogMessage(" Type Download Upload \n");
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];
"-10") " \n", file_stats.files_sig_depth);
file_capture_mem_usage();
+#endif
}
#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;
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;
}
{
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;
int eval(Cursor&, Packet*) override;
-private:
+//private: // FIXTHIS-L privatize
FlowCheckData config;
};
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;
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;
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;
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;
{ "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",
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 */
{
handler->set_api(&p.api);
handler->add_ref();
+
+ if ( p.api.service )
+ handler->set_service(AddProtocolReference(p.api.service));
}
}
{
PHGlobal* g = new PHGlobal(*api);
s_handlers.push_back(g);
-
- if ( api->service )
- AddProtocolReference(api->service);
}
static const InspectApi* get_plugin(const char* keyword)
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);
}
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));
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 )
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;
/* For all protocols-add to the any any group */
PortObjectAddRule(aaObject, rim_index);
prc->any++;
+ rtn->flags = orig_flags;
return 0; /* done */
}
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");
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 );
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 )
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,
{ 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 },
(!s->type || type == s->type) &&
(!s->match || tok == s->match) )
{
- return fsm + i;
+ return s;
}
}
ParseError("syntax error");
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;
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 )
poi =(PortObjectItem*)sflist_next(&lpos) )
{
poinew = PortObjectItemDup(poi);
+
if (!poinew)
- return 0;
+ {
+ free(ponew);
+ return NULL;
+ }
PortObjectAddItem( (PortObject*)ponew, poinew, NULL);
}
prule = (int*)calloc(1,sizeof(int));
if (!prule)
{
+ free(ponew);
return NULL;
}
*prule = *prid;
FailState[ k ] = fs;
}
}
-#ifdef DEBUG
+#if 0
if ( cnt)
LogMessage("ac-bnfa: %d nfa optimizations found in %d states\n",cnt,bnfa->bnfaNumStates);
#endif
rpc_decode
smtp
ssh
+ ssl
wizard
)
endif()
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);
}
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 )
#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;
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)
{
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(); }
IMAPData session;
};
-#endif /* IMAP_H */
+#endif
#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;
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)
{
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(); }
POPData session;
};
-#endif /* POP_H */
+#endif
#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;
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)
{
}
}
-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;
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;
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;
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 */
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;
StreamSplitter* get_splitter(bool c2s) override
{ return new SmtpSplitter(c2s); }
+ void ProcessSmtpCmdsList(const SmtpCmd*);
+
private:
SMTP_PROTO_CONF* config;
};
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*)
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
//-------------------------------------------------------------------------
{
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)
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(); }
{
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;
}
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;
#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
class Stream* stream;
struct StreamGlobalConfig* global_config;
- uint8_t service_filter[MAX_PROTOCOL_ORDINAL];
};
// shared stream state
{
// 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 (
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)
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);
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)
#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); }
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);
#include "sf_email_attach_decode.h"
+#include <assert.h>
+
#include "snort_types.h"
#include "util.h"
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;
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)
{
{
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;
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)
{
{
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;
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)
{
{
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;
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;
}
}
ds->decode_present = 1;
- ds->decodePtr = (uint8_t*)start;
ds->decoded_bytes = act_size;
ds->bitenc_state.bytes_read += act_size;
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;
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;
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;
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;
}
static inline void ResetDecodedBytes(Email_DecodeState* ds)
{
- ds->decodePtr = NULL;
+ ds->decodePtr = nullptr;
ds->decoded_bytes = 0;
ds->decode_present = 0;
}
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" },
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;