From: Russ Combs Date: Sat, 24 May 2014 01:46:08 +0000 (-0400) Subject: removed pthread* (must use c++11 threads) and deleted side_channel/ since not support... X-Git-Tag: 3.0.0-233~1516 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=97cc6da25e48a6b617f62bf369cbdcea6d55261f;p=thirdparty%2Fsnort3.git removed pthread* (must use c++11 threads) and deleted side_channel/ since not supported yet --- diff --git a/src/Makefile.am b/src/Makefile.am index b9858ff5c..89d38ac72 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -101,10 +101,3 @@ snort_LDADD += test/libtest.a SUBDIRS += test endif -if BUILD_SIDE_CHANNEL -snort_LDADD += \ -side_channel/libsidechannel.a \ -side_channel/plugins/libsscm.a -SUBDIRS += side_channel -endif - diff --git a/src/log/messages.cc b/src/log/messages.cc index 1c86d0dbc..aa61514d0 100644 --- a/src/log/messages.cc +++ b/src/log/messages.cc @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -209,44 +208,6 @@ void ErrorMessageThrottled(ThrottleInfo *throttleInfo, const char *format,...) } -/* - * Function: SnortFatalExit(void) - * - * Purpose: When a fatal error occurs, this function cleanly - * shuts down the program - * - * Arguments: none - * - * Returns: void function - */ -NORETURN void SnortFatalExit(void) -{ - // ----------------------------- - // bail now if we are reentering - if ( already_fatal ) - exit(1); - else - already_fatal = 1; - - if (!snort_conf || (!ScDaemonMode() && !ScLogSyslog())) - fprintf(stderr,"Fatal Error, Quitting..\n"); - -#if 0 - // FIXIT need to stop analyzers / workers - // and they should handle the DAQ break / abort - if ( SnortIsInitializing() ) - { - DAQ_Abort(); - exit(1); - } - else -#endif - { - DAQ_BreakLoop(1); - pthread_exit(NULL); - } -} - /* * Function: FatalError(const char *, ...) * @@ -299,8 +260,6 @@ NORETURN void FatalError(const char *format,...) #endif { // FIXIT this makes no sense from main thread - //DAQ_BreakLoop(1); - // FIXIT pthread_exit() segfaults; use c++11 instead of pthread_*() // FIXIT exit() segfaults too; looks like something borked in dylib exit(EXIT_FAILURE); } diff --git a/src/log/messages.h b/src/log/messages.h index 478834f64..3280fb769 100644 --- a/src/log/messages.h +++ b/src/log/messages.h @@ -49,8 +49,8 @@ struct ThrottleInfo void ErrorMessageThrottled(ThrottleInfo*,const char*, ...) __attribute__((format (printf, 2, 3))); +// FIXIT do not call FatalError() during runtime NORETURN void FatalError(const char*, ...) __attribute__((format (printf, 1, 2))); -NORETURN void SnortFatalExit(void); void PrintPacketData(const uint8_t*, const uint32_t); char* ObfuscateIpToText(sfip_t*); diff --git a/src/main.cc b/src/main.cc index 26a860217..f0d8d0eec 100644 --- a/src/main.cc +++ b/src/main.cc @@ -62,10 +62,6 @@ using namespace std; #include "test/unit_test.h" #endif -#ifdef SIDE_CHANNEL -#include "side_channel/sidechannel.h" -#endif - #include "framework/so_rule.h" //------------------------------------------------------------------------- @@ -77,11 +73,6 @@ static bool paused = false; const struct timespec main_sleep = { 0, 100000000 }; // 0.1 sec -#ifdef SIDE_CHANNEL -pthread_mutex_t snort_process_lock; -static bool snort_process_lock_held = false; -#endif - static const char* prompt = "o\")~ "; //------------------------------------------------------------------------- @@ -434,19 +425,8 @@ static int signal_check() // FIXIT return true if something was done to avoid sleeping static bool house_keeping() { -#ifdef SIDE_CHANNEL - if (ScSideChannelEnabled() && !snort_process_lock_held) - { - pthread_mutex_lock(&snort_process_lock); - snort_process_lock_held = true; - } -#endif - signal_check(); -#ifdef SIDE_CHANNEL - SideChannelDrainRX(0); -#endif IdleProcessingExecute(); periodic_check(); diff --git a/src/main/snort.cc b/src/main/snort.cc index 75ab138fe..4898950a7 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -111,10 +111,6 @@ using namespace std; #include "stream/stream.h" #include "ips_options/replace.h" -#ifdef SIDE_CHANNEL -#include "side_channel/sidechannel.h" -#endif - #ifdef INTEL_SOFT_CPM #include "search/intel_soft_cpm.h" #endif @@ -128,7 +124,6 @@ static bool snort_initializing = true; static int snort_exiting = 0; static pid_t snort_main_thread_pid = 0; -static pthread_t snort_main_thread_id = 0; static int snort_argc = 0; static char** snort_argv = NULL; @@ -308,9 +303,6 @@ static void SnortInit(int argc, char **argv) #endif InitProtoNames(); -#ifdef SIDE_CHANNEL - pthread_mutex_init(&snort_process_lock, NULL); -#endif if (snort_cmd_line_conf != NULL) // FIXIT can this be deleted? { @@ -384,7 +376,7 @@ static void SnortInit(int argc, char **argv) OrderRuleLists(snort_conf, "activation dynamic drop sdrop reject alert pass log"); } if ( !InspectorManager::configure(snort_conf) ) - SnortFatalExit(); + FatalError("can't initialize inspectors\n"); InspectorManager::print_config(snort_conf); // FIXIT make optional @@ -440,14 +432,6 @@ static void SnortInit(int argc, char **argv) #endif EventManager::configure_outputs(snort_conf); - -#ifdef SIDE_CHANNEL - RegisterSideChannelModules(); - ConfigureSideChannelModules(snort_conf); - SideChannelConfigure(snort_conf); - SideChannelInit(); - SideChannelStartTXThread(); -#endif } // this function should only include initialization that must be done as a @@ -484,10 +468,6 @@ static void SnortUnprivilegedInit(void) /* Drop privileges if requested, when initialization is done */ SetUidGid(ScUid(), ScGid()); -#ifdef SIDE_CHANNEL - SideChannelPostInit(); -#endif - snort_initializing = false; } @@ -496,9 +476,6 @@ void snort_setup(int argc, char *argv[]) snort_argc = argc; snort_argv = argv; - // must be done now in case of fatal error - // and again after daemonization - snort_main_thread_id = pthread_self(); OpenLogger(); SnortInit(argc, argv); @@ -511,7 +488,6 @@ void snort_setup(int argc, char *argv[]) // this must follow daemonization snort_main_thread_pid = gettid(); - snort_main_thread_id = pthread_self(); /* Change groups */ InitGroups(ScUid(), ScGid()); @@ -577,10 +553,6 @@ static void SnortCleanup() snort_exiting = 1; snort_initializing = false; /* just in case we cut out early */ -#ifdef SIDE_CHANNEL - SideChannelStopTXThread(); - SideChannelCleanUp(); -#endif IdleProcessingCleanUp(); IpsManager::global_term(snort_conf); diff --git a/src/main/snort.h b/src/main/snort.h index 99aaebe57..b7deb1bab 100644 --- a/src/main/snort.h +++ b/src/main/snort.h @@ -169,10 +169,6 @@ typedef enum { /* E X T E R N S ************************************************************/ extern THREAD_LOCAL SnortConfig* snort_conf; -#ifdef SIDE_CHANNEL -extern pthread_mutex_t snort_process_lock; -#endif - /* P R O T O T Y P E S ******************************************************/ static inline int ScTestMode(void) @@ -499,13 +495,6 @@ static inline char * ScPcapLogFile(void) return snort_conf->pcap_log_file; } -#ifdef SIDE_CHANNEL -static inline int ScSideChannelEnabled(void) -{ - return snort_conf->side_channel_config.enabled; -} -#endif - // use of macro avoids depending on generators.h #define EventIsInternal(gid) (gid == GENERATOR_INTERNAL) diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index 5629d7820..2b8b393cc 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -34,7 +34,6 @@ #include "utils/strvec.h" #include "file_api/file_service.h" #include "target_based/sftarget_reader.h" -#include "side_channel/sidechannel.h" #include "parser/parser.h" #include "parser/config_file.h" #include "parser/vars.h" @@ -46,29 +45,6 @@ // private implementation //------------------------------------------------------------------------- -#ifdef SIDE_CHANNEL -static void FreeSideChannelModuleConfigs(SideChannelModuleConfig *head) -{ - while (head != NULL) - { - SideChannelModuleConfig *tmp = head; - - head = head->next; - - if (tmp->keyword != NULL) - free(tmp->keyword); - - if (tmp->opts != NULL) - free(tmp->opts); - - if (tmp->file_name != NULL) - free(tmp->file_name); - - free(tmp); - } -} -#endif - static void FreeRuleStateList(RuleState *head) { while (head != NULL) @@ -263,10 +239,6 @@ void SnortConfFree(SnortConfig *sc) free(sc->profile_preprocs.filename); #endif -#ifdef SIDE_CHANNEL - FreeSideChannelModuleConfigs(sc->side_channel_config.module_configs); -#endif - if (sc->base_version != NULL) free(sc->base_version); @@ -334,11 +306,6 @@ void SnortConfFree(SnortConfig *sc) free_file_config(sc->file_config); -#ifdef SIDE_CHANNEL - if (sc->side_channel_config.opts) - free(sc->side_channel_config.opts); -#endif - if ( sc->var_list ) FreeVarList(sc->var_list); @@ -812,14 +779,6 @@ int VerifyReload(SnortConfig *sc) return -1; } -#ifdef SIDE_CHANNEL - if (SideChannelVerifyConfig(sc) != 0) - { - ErrorMessage("Snort Reload: Changing the side channel configuration requires a restart.\n"); - return -1; - } -#endif - return 0; } diff --git a/src/main/snort_config.h b/src/main/snort_config.h index 560a81220..d95121645 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -61,24 +61,6 @@ typedef enum _PathType } PathType; -#ifdef SIDE_CHANNEL -typedef struct _SideChannelModuleConfig -{ - char *keyword; - char *opts; - char *file_name; - int file_line; - struct _SideChannelModuleConfig *next; -} SideChannelModuleConfig; - -typedef struct _SideChannelConfig -{ - bool enabled; - char *opts; - SideChannelModuleConfig *module_configs; -} SideChannelConfig; -#endif - // SnortState members are updated during runtime // an array in SnortConfig is used instead of thread_locals because these // must get changed on reload @@ -216,10 +198,6 @@ struct SnortConfig //------------------------------------------------------ // FIXIT non-module stuff - separate config from derived state? -#ifdef SIDE_CHANNEL - DynamicLibInfo *dyn_side_channels; // FIXIT needs redoing -#endif - char pid_filename[STD_BUF]; /* used with pid_path */ // FIXIT delete these char pidfile_suffix[MAX_PIDFILE_SUFFIX + 1]; /* -R */ @@ -287,9 +265,6 @@ struct SnortConfig char *output_dir; struct VarNode* var_list; -#ifdef SIDE_CHANNEL - SideChannelConfig side_channel_config; -#endif int max_threads; unsigned remote_control; diff --git a/src/parser/config_file.cc b/src/parser/config_file.cc index b3cb5325a..68ab32cd0 100644 --- a/src/parser/config_file.cc +++ b/src/parser/config_file.cc @@ -56,10 +56,6 @@ #include "file_api/file_service_config.h" #include "packet_io/sfdaq.h" -#ifdef SIDE_CHANNEL -# include "side_channel/sidechannel.h" -#endif - #include "target_based/sftarget_reader.h" // FIXIT defines should be avoided here - the actual option diff --git a/src/parser/keywords.h b/src/parser/keywords.h index 55dd05253..783b55412 100644 --- a/src/parser/keywords.h +++ b/src/parser/keywords.h @@ -28,14 +28,6 @@ #define SNORT_CONF_KEYWORD__FILE "file" #define SNORT_CONF_KEYWORD__INCLUDE "include" -/* Rest of the keywords */ -// FIXIT config_* keywords were config * but moved here temporarily -// until they are properly modularized -#ifdef SIDE_CHANNEL -#define SNORT_CONF_KEYWORD__CFG_SIDE_CHANNEL "config_sidechannel" -#define SNORT_CONF_KEYWORD__SIDE_CHANNEL "sidechannel" -#endif - /* Macros *********************************************************************/ #define ENABLE_ALL_RULES 1 #define ENABLE_RULE 1 diff --git a/src/parser/parse_conf.cc b/src/parser/parse_conf.cc index 5817b8ab7..41539adab 100644 --- a/src/parser/parse_conf.cc +++ b/src/parser/parse_conf.cc @@ -76,10 +76,6 @@ using namespace std; #include "keywords.h" #include "vars.h" -#ifdef SIDE_CHANNEL -# include "side_channel/sidechannel.h" -#endif - struct Location { string file; @@ -303,63 +299,6 @@ void AddRuleState(SnortConfig* sc, const RuleState& rs) } } -#ifdef SIDE_CHANNEL -static void ConfigSideChannel(SnortConfig *sc, const char *args) -{ - if (sc == NULL) - return; - sc->side_channel_config.enabled = true; - if (args != NULL) - sc->side_channel_config.opts = SnortStrdup(args); -} - -static void ParseSideChannelModule(SnortConfig *sc, const char *args) -{ - char **toks; - int num_toks; - char *opts = NULL; - SideChannelModuleConfig *config; - - toks = mSplit(args, ":", 2, &num_toks, '\\'); - - if (num_toks > 1) - opts = toks[1]; - - config = (SideChannelModuleConfig *) SnortAlloc(sizeof(SideChannelModuleConfig)); - - if (sc->side_channel_config.module_configs == NULL) - { - sc->side_channel_config.module_configs = config; - } - else - { - SideChannelModuleConfig *tmp = sc->side_channel_config.module_configs; - - while (tmp->next != NULL) - tmp = tmp->next; - - tmp->next = config; - } - - config->keyword = SnortStrdup(toks[0]); - if (opts != NULL) - config->opts = SnortStrdup(opts); - - /* This could come from parsing the command line (No, actually, I don't think that it could...) */ - const char* fname; - unsigned fline; - get_parse_location(fname, fline); - - if ( fname ) - { - config->file_name = SnortStrdup(fname); - config->file_line = fline; - } - - mSplitFree(&toks, num_toks); -} -#endif /* SIDE_CHANNEL */ - static void ParseFile(SnortConfig *sc, const char *args) { parse_file_rule(args, &(sc->file_config)); @@ -395,12 +334,6 @@ static const KeywordFunc snort_conf_keywords[] = { SNORT_CONF_KEYWORD__RULE_TYPE, KEYWORD_TYPE__ALL, 1, 0, ParseRuleTypeDeclaration }, #endif - // this stuff needs to be rewritten as a proper plugin -#ifdef SIDE_CHANNEL - { SNORT_CONF_KEYWORD__CFG_SIDE_CHANNEL, KEYWORD_TYPE__MAIN, 1, 1, ConfigSideChannel }, - { SNORT_CONF_KEYWORD__SIDE_CHANNEL, KEYWORD_TYPE__MAIN, 1, 1, ParseSideChannelModule }, -#endif - { NULL, KEYWORD_TYPE__ALL, 0, 0, NULL } /* Marks end of array */ }; diff --git a/src/parser/parse_otn.cc b/src/parser/parse_otn.cc index 3cf3b0b12..671b768a8 100644 --- a/src/parser/parse_otn.cc +++ b/src/parser/parse_otn.cc @@ -80,11 +80,6 @@ #include "keywords.h" #include "vars.h" #include "managers/ips_manager.h" - -#ifdef SIDE_CHANNEL -# include "side_channel/sidechannel.h" -#endif - #include "target_based/sftarget_reader.h" typedef void (*ParseRuleOptFunc)(SnortConfig *, RuleTreeNode *, OptTreeNode *, const char *); diff --git a/src/parser/parse_rule.cc b/src/parser/parse_rule.cc index 6149b2b70..bf0c08ff1 100644 --- a/src/parser/parse_rule.cc +++ b/src/parser/parse_rule.cc @@ -82,11 +82,6 @@ #include "managers/ips_manager.h" #include "config_file.h" #include "keywords.h" - -#ifdef SIDE_CHANNEL -# include "side_channel/sidechannel.h" -#endif - #include "target_based/sftarget_reader.h" #define SRC 0 diff --git a/src/parser/parser.cc b/src/parser/parser.cc index 8ebb02883..4f26a6352 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -86,11 +86,6 @@ #include "parse_conf.h" #include "parse_rule.h" #include "vars.h" - -#ifdef SIDE_CHANNEL -# include "side_channel/sidechannel.h" -#endif - #include "target_based/sftarget_reader.h" rule_index_map_t *ruleIndexMap = NULL; /* rule index -> sid:gid map */ @@ -631,26 +626,6 @@ SnortConfig * ParseSnortConf(VarNode* tmp) return sc; } -#ifdef SIDE_CHANNEL -void ConfigureSideChannelModules(SnortConfig *sc) -{ - SideChannelModuleConfig *config; - int rval; - - for (config = sc->side_channel_config.module_configs; config != NULL; config = config->next) - { - push_parse_location(config->file_name, config->file_line); - - rval = ConfigureSideChannelModule(config->keyword, config->opts); - if (rval == -ENOENT) - ParseError("Unknown side channel plugin: '%s'", config->keyword); - - pop_parse_location(); - } -} - -#endif /* SIDE_CHANNEL */ - void FreeRuleTreeNode(RuleTreeNode *rtn) { RuleFpList *idx, *tmp; diff --git a/src/parser/vars.cc b/src/parser/vars.cc index e6d87c3ba..2775278ce 100644 --- a/src/parser/vars.cc +++ b/src/parser/vars.cc @@ -76,11 +76,6 @@ #include "framework/ips_option.h" #include "config_file.h" #include "keywords.h" - -#ifdef SIDE_CHANNEL -# include "side_channel/sidechannel.h" -#endif - #include "target_based/sftarget_reader.h" //------------------------------------------------------------------------- diff --git a/src/side_channel/CMakeLists.txt b/src/side_channel/CMakeLists.txt deleted file mode 100644 index 1e6daf05c..000000000 --- a/src/side_channel/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ - -add_subdirectory(plugins) - -add_library ( sidechannel STATIC - dmq.cc - dmq.h - rbmq.cc - rbmq.h - sidechannel.cc - sidechannel.h - sidechannel_define.h -) - diff --git a/src/side_channel/Makefile.am b/src/side_channel/Makefile.am deleted file mode 100644 index db60a1be2..000000000 --- a/src/side_channel/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -AUTOMAKE_OPTIONS=foreign no-dependencies - -noinst_LIBRARIES = libsidechannel.a - -SUBDIRS = \ -plugins - -libsidechannel_a_SOURCES = \ -dmq.cc dmq.h \ -rbmq.cc rbmq.h \ -sidechannel.cc sidechannel.h \ -sidechannel_define.h - -AM_CXXFLAGS = @AM_CXXFLAGS@ - diff --git a/src/side_channel/dmq.cc b/src/side_channel/dmq.cc deleted file mode 100644 index 859f6e660..000000000 --- a/src/side_channel/dmq.cc +++ /dev/null @@ -1,280 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ - -#include "dmq.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef SIDE_CHANNEL -#include -#include "util.h" - -#ifdef SC_USE_DMQ -#define DMQ_NODE_FLAG_EXTERNAL 0x01 - -typedef struct _dmq_node -{ - struct _dmq_node *next; - uint32_t length; - uint32_t allocated; - uint8_t flags; - uint8_t *data; - SCMQMsgFreeFunc msgFreeFunc; -} DMQ_Node; - -typedef struct _dmq -{ - DMQ_Node *head; - DMQ_Node *tail; - DMQ_Node *free_list; - uint16_t user_header_size; - uint32_t length; - uint32_t internal_size; - uint32_t external_size; - uint32_t overhead_size; - uint32_t length_limit; - uint32_t internal_size_limit; - uint32_t max_length; - uint32_t max_internal_size; -} DMQ; - -DMQ *DMQ_Alloc(uint32_t msg_ring_entries, uint16_t msg_ring_header_size, uint32_t data_ring_size) -{ - DMQ_Node *node; - DMQ *mq; - uint32_t i; - - mq = (DMQ*)SnortAlloc(sizeof(DMQ)); - - mq->head = mq->tail = mq->free_list = NULL; - - mq->user_header_size = msg_ring_header_size; - - mq->length = 0; - mq->internal_size = 0; - mq->external_size = 0; - mq->overhead_size = 0; - - mq->length_limit = msg_ring_entries; - mq->internal_size_limit = data_ring_size; - - /* Preallocate the Queue nodes. */ - for (i = 0; i < mq->length_limit; i++) - { - node = (DMQ_Node*)SnortAlloc(sizeof(DMQ_Node) + mq->user_header_size); - node->next = mq->free_list; - mq->free_list = node; - mq->overhead_size += sizeof(DMQ_Node) + mq->user_header_size; - } - - LogMessage("%s: Preallocated %u bytes for queue node structures.\n", __FUNCTION__, mq->overhead_size); - - return mq; -} - -int DMQ_ReserveMsg(DMQ *mq, uint32_t length, void **hdr_ptr, uint8_t **msg_ptr, void **msg_handle) -{ - DMQ_Node *node; - - if (!mq->free_list) - return -ENOSPC; - - if (length > (mq->internal_size_limit - mq->internal_size)) - return -ENOMEM; - - node = mq->free_list; - mq->free_list = node->next; - - node->next = NULL; - node->length = length; - node->allocated = length; - node->flags = 0; - node->data = (uint8_t*)SnortAlloc(length); - node->msgFreeFunc = NULL; - - *hdr_ptr = (uint8_t *) node + sizeof(DMQ_Node); - *msg_ptr = node->data; - *msg_handle = (void *) node; - - mq->internal_size += length; - if (mq->internal_size > mq->max_internal_size) - mq->max_internal_size = mq->internal_size; - - return 0; -} - -int DMQ_CommitReservedMsg(DMQ *mq, void *msg_handle, uint32_t length, SCMQMsgFreeFunc msgFreeFunc) -{ - DMQ_Node *node = (DMQ_Node *) msg_handle; - - if (!node) - return -EINVAL; - - if (length > node->length) - { - ErrorMessage("%s: Attempted to commit illegally enlarged message! (%u vs %u)\n", __FUNCTION__, length, node->length); - return -EINVAL; - } - - node->length = length; - - if (mq->head) - { - mq->tail->next = node; - mq->tail = node; - } - else - mq->head = mq->tail = node; - - mq->length++; - if (mq->length > mq->max_length) - mq->max_length = mq->length; - - return 0; -} - -static void DMQ_DestroyNode(DMQ *mq, DMQ_Node *node) -{ - if (node->msgFreeFunc) - node->msgFreeFunc(node->data); - - if (!(node->flags & DMQ_NODE_FLAG_EXTERNAL)) - { - mq->internal_size -= node->allocated; - free(node->data); - } - else - mq->external_size -= node->length; - - node->next = mq->free_list; - mq->free_list = node; -} - -int DMQ_DiscardReservedMsg(DMQ *mq, void *msg_handle) -{ - DMQ_Node *node = (DMQ_Node *) msg_handle; - - if (!node) - return -EINVAL; - - DMQ_DestroyNode(mq, node); - - return 0; -} - -int DMQ_CommitExternalMsg(DMQ *mq, const void *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc) -{ - DMQ_Node *node; - - if (!mq->free_list) - return -ENOMEM; - - node = mq->free_list; - mq->free_list = node->next; - - if (mq->user_header_size) - { - if (!hdr) - return -EINVAL; - memcpy((uint8_t *) node + sizeof(DMQ_Node), hdr, mq->user_header_size); - } - - node->next = NULL; - node->length = length; - node->allocated = 0; - node->flags = DMQ_NODE_FLAG_EXTERNAL; - node->data = msg; - node->msgFreeFunc = msgFreeFunc; - - if (mq->head) - { - mq->tail->next = node; - mq->tail = node; - } - else - mq->head = mq->tail = node; - - mq->length++; - if (mq->length > mq->max_length) - mq->max_length = mq->length; - - mq->external_size += length; - - return 0; -} - -int DMQ_ReadMsg(DMQ *mq, const void **hdr_ptr, const uint8_t **msg_ptr, uint32_t *length, void **msg_handle) -{ - DMQ_Node *node; - - if (!mq->head) - return -ENOENT; - - node = mq->head; - mq->head = node->next; - if (!mq->head) - mq->tail = NULL; - node->next = NULL; - - if (mq->user_header_size) - *hdr_ptr = (uint8_t *) node + sizeof(DMQ_Node); - else - *hdr_ptr = NULL; - *msg_ptr = node->data; - *length = node->length; - *msg_handle = (void *) node; - - mq->length--; - - return 0; -} - -int DMQ_AckMsg(DMQ *mq, void *msg_handle) -{ - DMQ_Node *node = (DMQ_Node *) msg_handle; - - if (!node) - return -EINVAL; - - DMQ_DestroyNode(mq, node); - - return 0; -} - -int DMQ_IsEmpty(DMQ *mq) -{ - return (mq->head == NULL); -} - -void DMQ_Stats(DMQ_Ptr mq, const char *indent) -{ - LogMessage("%s Length: %u (%u max)\n", indent, mq->length, mq->max_length); - LogMessage("%s Size: %u internal (%u max), %u external, %u overhead\n", - indent, mq->internal_size, mq->max_internal_size, mq->external_size, mq->overhead_size); -} - -#endif /* SC_USE_DMQ */ - -#endif /* SIDE_CHANNEL */ diff --git a/src/side_channel/dmq.h b/src/side_channel/dmq.h deleted file mode 100644 index 7d253dcb6..000000000 --- a/src/side_channel/dmq.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ - -#ifndef DMQ_H -#define DMQ_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "sidechannel_define.h" - -#ifdef SC_USE_DMQ - -typedef struct _dmq *DMQ_Ptr; - -DMQ_Ptr DMQ_Alloc(uint32_t msg_ring_entries, uint16_t msg_ring_header_size, uint32_t data_ring_size); -int DMQ_ReserveMsg(DMQ_Ptr mq, uint32_t length, void **hdr_ptr, uint8_t **msg_ptr, void **msg_handle); -int DMQ_CommitReservedMsg(DMQ_Ptr mq, void *msg_handle, uint32_t length, SCMQMsgFreeFunc msgFreeFunc); -int DMQ_DiscardReservedMsg(DMQ_Ptr mq, void *msg_handle); -int DMQ_CommitExternalMsg(DMQ_Ptr mq, const void *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc); -int DMQ_ReadMsg(DMQ_Ptr mq, const void **hdr_ptr, const uint8_t **msg_ptr, uint32_t *length, void **msg_handle); -int DMQ_AckMsg(DMQ_Ptr mq, void *msg_handle); -int DMQ_IsEmpty(DMQ_Ptr mq); -void DMQ_Stats(DMQ_Ptr mq, const char *indent); - -#endif /* SC_USE_DMQ */ - -#endif /* DMQ_H */ diff --git a/src/side_channel/plugins/CMakeLists.txt b/src/side_channel/plugins/CMakeLists.txt deleted file mode 100644 index 4837eead0..000000000 --- a/src/side_channel/plugins/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ - - -add_library ( scm STATIC - sscm_logger.cc - sscm_logger.h -) diff --git a/src/side_channel/plugins/Makefile.am b/src/side_channel/plugins/Makefile.am deleted file mode 100644 index e1525e4a7..000000000 --- a/src/side_channel/plugins/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -## $Id -AUTOMAKE_OPTIONS=foreign no-dependencies - -noinst_LIBRARIES = libsscm.a - -libsscm_a_SOURCES = \ -sscm_logger.cc sscm_logger.h - -AM_CXXFLAGS = @AM_CXXFLAGS@ diff --git a/src/side_channel/plugins/sscm_logger.cc b/src/side_channel/plugins/sscm_logger.cc deleted file mode 100644 index f3a210397..000000000 --- a/src/side_channel/plugins/sscm_logger.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ -#include "sscm_logger.h" - -#include -#include -#include -#include -#include - -#include "side_channel/sidechannel.h" -#include "util.h" - -#define CONF_SEPARATORS " \t\n\r," -#define CONF_RX_FILE "rx-log-file" -#define CONF_TX_FILE "tx-log-file" -#define CONF_PRIMER_FILE "primer-file" - -enum ConfState -{ - STATE_START, - STATE_RX_FILE, - STATE_TX_FILE, - STATE_PRIMER_FILE -}; - -static char rx_log_file[PATH_MAX]; // FIXIT 1 / process -static int rx_log_fd = -1; -static char tx_log_file[PATH_MAX]; -static int tx_log_fd = -1; -static char primer_log_file[PATH_MAX]; - -static int LoggerRXHandler(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length) -{ - SideChannelWriteMsgToFile(rx_log_fd, hdr, msg, length); - return 0; -} - -static int LoggerTXHandler(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length) -{ - SideChannelWriteMsgToFile(tx_log_fd, hdr, msg, length); - return 0; -} - -static int ConfigLogger(char *args) -{ - char *token; - char* lasts = ""; - char *argcpy = args; - enum ConfState confState = STATE_START; - - for (token = strtok_r(argcpy, CONF_SEPARATORS, &lasts); - token; - token = strtok_r(NULL, CONF_SEPARATORS, &lasts)) - { - switch (confState) - { - case STATE_START: - if (strcmp(token, CONF_RX_FILE) == 0) - confState = STATE_RX_FILE; - else if (strcmp(token, CONF_TX_FILE) == 0) - confState = STATE_TX_FILE; - else if (strcmp(token, CONF_PRIMER_FILE) == 0) - confState = STATE_PRIMER_FILE; - else - FatalError("Invalid logger side channel configuration token: '%s'\n", token); - break; - case STATE_RX_FILE: - snprintf(rx_log_file, sizeof(rx_log_file), "%s", token); - confState = STATE_START; - break; - case STATE_TX_FILE: - snprintf(tx_log_file, sizeof(tx_log_file), "%s", token); - confState = STATE_START; - break; - case STATE_PRIMER_FILE: - snprintf(primer_log_file, sizeof(primer_log_file), "%s", token); - confState = STATE_START; - break; - default: - break; - } - } - - return 0; -} - -static int InitLogger(void) -{ - if (rx_log_file[0] != '\0') - { - LogMessage("Opening '%s' for side channel RX logging...\n", rx_log_file); - rx_log_fd = open(rx_log_file, O_WRONLY|O_CREAT|O_TRUNC, 0664); - if (rx_log_fd == -1) - FatalError("Could not open Logger SCM RX log file '%s': %s (%d)\n", rx_log_file, get_error(errno), errno); - SideChannelRegisterRXHandler(SC_MSG_TYPE_ANY, LoggerRXHandler, NULL); - } - if (tx_log_file[0] != '\0') - { - LogMessage("Opening '%s' for side channel TX logging...\n", tx_log_file); - tx_log_fd = open(tx_log_file, O_WRONLY|O_CREAT|O_TRUNC, 0664); - if (tx_log_fd == -1) - FatalError("Could not open Logger SCM TX log file '%s': %s (%d)\n", tx_log_file, get_error(errno), errno); - SideChannelRegisterTXHandler(SC_MSG_TYPE_ANY, LoggerTXHandler, NULL); - } - - return 0; -} - -static int PostInitLogger(void) -{ - SCMsgHdr hdr; - uint32_t length; - uint8_t *msg; - unsigned int messages; - int fd; - - if (primer_log_file[0] != '\0') - { - fd = open(primer_log_file, O_RDONLY, 0664); - if (fd == -1) - FatalError("Could not open Logger SCM Primer log file '%s': %s (%d)\n", primer_log_file, get_error(errno), errno); - messages = 0; - while (SideChannelReadMsgFromFile(fd, &hdr, &msg, &length) == 0) - { - if (length == 0) - msg = NULL; - SideChannelEnqueueDataRX(&hdr, msg, length, free); - messages++; - } - close(fd); - LogMessage("Primed the side channel with %u messages from '%s'...\n", messages, primer_log_file); - } - - return 0; -} - -static void ShutdownLogger(void) -{ - if (rx_log_fd != -1) - { - close(rx_log_fd); - rx_log_fd = -1; - SideChannelUnregisterRXHandler(SC_MSG_TYPE_ANY, LoggerRXHandler); - } - if (tx_log_fd) - { - close(tx_log_fd); - tx_log_fd = -1; - SideChannelUnregisterTXHandler(SC_MSG_TYPE_ANY, LoggerTXHandler); - } -} - -static const SCMFunctionBundle loggerFuncs = { // FIXIT 1 / process - ConfigLogger, - InitLogger, - PostInitLogger, - NULL, - NULL, - ShutdownLogger -}; - -int SetupLoggerSCM(void) -{ - RegisterSideChannelModule("logger", &loggerFuncs); - return 0; -} diff --git a/src/side_channel/plugins/sscm_logger.h b/src/side_channel/plugins/sscm_logger.h deleted file mode 100644 index 064d54fef..000000000 --- a/src/side_channel/plugins/sscm_logger.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ - -#ifndef SSCM_LOGGER_H -#define SSCM_LOGGER_H - -int SetupLoggerSCM(void); - -#endif diff --git a/src/side_channel/rbmq.cc b/src/side_channel/rbmq.cc deleted file mode 100644 index 0b206178a..000000000 --- a/src/side_channel/rbmq.cc +++ /dev/null @@ -1,424 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ - -#include "rbmq.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef SIDE_CHANNEL -#include -#include -#include "util.h" - -#ifndef SC_USE_DMQ -#define RBMQ_MSG_FLAG_EXTERNAL 0x01 - -enum { - RBMQ_MSG_STATE_UNUSED = 0, - RBMQ_MSG_STATE_RESERVED, - RBMQ_MSG_STATE_COMMITTED, - RBMQ_MSG_STATE_READ, - RBMQ_MSG_STATE_ACKED, - RBMQ_MSG_STATE_DISCARDED -}; - -typedef struct _rbmq_msg -{ - uint32_t length; - uint8_t flags; - uint8_t state; - uint8_t *data; - SCMQMsgFreeFunc msgFreeFunc; -} RBMQ_Msg; - -typedef struct _rmbq_internal_data_hdr -{ - uint32_t msg_index; - uint32_t prev_offset; -} RBMQ_InternalDataHdr; - -typedef struct _rbmq_msg_ring -{ - RBMQ_Msg *msgs; - uint8_t *headers; - uint32_t last_reserved; - uint32_t last_read; - uint32_t last_acked; - uint32_t entries; - uint16_t header_size; -} RBMQ_MsgRing; - -typedef struct _rbmq_data_ring -{ - uint8_t *data; - uint32_t read_offset; - uint32_t write_offset; - uint32_t size; -} RBMQ_DataRing; - -typedef struct _rbmq -{ - RBMQ_MsgRing msg_ring; - RBMQ_DataRing data_ring; -} RBMQ; - -static inline uint32_t IncrementMessageIndex(RBMQ *mq, uint32_t index) -{ - return (++index == mq->msg_ring.entries) ? 0 : index; -} - -static inline uint32_t DecrementMessageIndex(RBMQ *mq, uint32_t index) -{ - return (index == 0) ? (mq->msg_ring.entries - 1) : (index - 1); -} - -/* Returns 0 if the message handle is within bounds for the control ring, non-zero otherwise. */ -static inline int ValidateMsgHandle(RBMQ *mq, void *msg_handle) -{ - return (msg_handle < (void *)(&mq->msg_ring.msgs[0]) || msg_handle > (void *)(&mq->msg_ring.msgs[mq->msg_ring.entries - 1])); -} - -RBMQ *RBMQ_Alloc(uint32_t msg_ring_entries, uint16_t msg_ring_header_size, uint32_t data_ring_size) -{ - RBMQ *mq; - - mq = SnortAlloc(sizeof(RBMQ)); - memset(mq, 0, sizeof(RBMQ)); - - /* Initialize the control ring. */ - mq->msg_ring.msgs = SnortAlloc(msg_ring_entries * sizeof(RBMQ_Msg)); - mq->msg_ring.headers = SnortAlloc(msg_ring_entries * msg_ring_header_size); - mq->msg_ring.entries = msg_ring_entries; - mq->msg_ring.header_size = msg_ring_header_size; - memset(mq->msg_ring.msgs, 0, mq->msg_ring.entries * sizeof(RBMQ_Msg)); - mq->msg_ring.last_reserved = 0; - mq->msg_ring.last_read = 0; - mq->msg_ring.last_acked = 0; - - /* Initialize the data ring. */ - mq->data_ring.data = SnortAlloc(data_ring_size); - mq->data_ring.size = data_ring_size; - memset(mq->data_ring.data, 0, mq->data_ring.size); - - return mq; -} - -void RBMQ_Destroy(RBMQ *mq) -{ - RBMQ_Msg *msg_info; - uint32_t idx; - - /* Free the data for any unprocessed messages. */ - idx = mq->msg_ring.last_acked; - while (idx != mq->msg_ring.last_reserved) - { - idx++; - if (idx == mq->msg_ring.entries) - idx = 0; - msg_info = &mq->msg_ring.msgs[idx]; - if (msg_info->msgFreeFunc) - msg_info->msgFreeFunc(msg_info->data); - } - - /* Release all of our resources. */ - free(mq->data_ring.data); - free(mq->msg_ring.msgs); -} - -int RBMQ_ReserveMsg(RBMQ *mq, uint32_t length, void **hdr_ptr, uint8_t **msg_ptr, void **msg_handle) -{ - RBMQ_InternalDataHdr *idh; - RBMQ_Msg *msg_info; - uint32_t msg_index, msg_len, start_offset; - - /* Find the next entry in the message ring to reserve. */ - msg_index = IncrementMessageIndex(mq, mq->msg_ring.last_reserved); - msg_info = &mq->msg_ring.msgs[msg_index]; - - /* Bail if the entry is in use. */ - if (msg_info->state != RBMQ_MSG_STATE_UNUSED) - return -ENOMEM; - - /* Make sure that we can reserve the requested space in the data ring. */ - msg_len = length + sizeof(RBMQ_InternalDataHdr); - if (mq->data_ring.write_offset < mq->data_ring.read_offset) - { - if ((mq->data_ring.read_offset - mq->data_ring.write_offset) < msg_len) - return -ENOMEM; - start_offset = mq->data_ring.write_offset; - } - else if ((mq->data_ring.size - mq->data_ring.write_offset) < msg_len) - { - if (mq->data_ring.read_offset < msg_len) - return -ENOMEM; - start_offset = 0; - } - else - start_offset = mq->data_ring.write_offset; - - idh = (RBMQ_InternalDataHdr *) (mq->data_ring.data + start_offset); - idh->msg_index = msg_index; - idh->prev_offset = mq->data_ring.write_offset; - - /* Update the write offset in the data ring, wrapping as necessary. */ - mq->data_ring.write_offset = start_offset + msg_len; - if (mq->data_ring.write_offset == mq->data_ring.size) - mq->data_ring.write_offset = 0; - - msg_info->length = length; - /* Type is filled in during the commit. */ - msg_info->flags = 0; - msg_info->state = RBMQ_MSG_STATE_RESERVED; - msg_info->data = (uint8_t *) idh + sizeof(RBMQ_InternalDataHdr); - msg_info->msgFreeFunc = NULL; - - /* Update the last reservation index in the control ring. */ - mq->msg_ring.last_reserved = msg_index; - - if (mq->msg_ring.header_size) - *hdr_ptr = mq->msg_ring.headers + (msg_index * mq->msg_ring.header_size); - else - *hdr_ptr = NULL; - *msg_ptr = msg_info->data; - *msg_handle = (void *) msg_info; - - return 0; -} - -int RBMQ_CommitReservedMsg(RBMQ *mq, void *msg_handle, uint32_t length, SCMQMsgFreeFunc msgFreeFunc) -{ - RBMQ_Msg *msg_info; - - if (ValidateMsgHandle(mq, msg_handle)) - return -EINVAL; - - msg_info = (RBMQ_Msg *) msg_handle; - - /* Sanity checks... */ - if (msg_info->state != RBMQ_MSG_STATE_RESERVED) - { - ErrorMessage("%s: Attempted to commit an unreserved message! (State: %hhu)\n", __FUNCTION__, msg_info->state); - return -EINVAL; - } - - if (length > msg_info->length) - { - ErrorMessage("%s: Attempted to commit illegally enlarged message! (%u vs %u)\n", __FUNCTION__, length, msg_info->length); - return -EINVAL; - } - - /* If the committed length is less than the reserved length and it was the last message reserved, - truncate the internal data ring usage. */ - if (length < msg_info->length && msg_info == &mq->msg_ring.msgs[mq->msg_ring.last_reserved]) - { - if (mq->data_ring.write_offset != 0) - mq->data_ring.write_offset -= (msg_info->length - length); - else - mq->data_ring.write_offset = mq->data_ring.size - (msg_info->length - length); - msg_info->length = length; - } - - msg_info->state = RBMQ_MSG_STATE_COMMITTED; - msg_info->msgFreeFunc = msgFreeFunc; - - return 0; -} - -int RBMQ_DiscardReservedMsg(RBMQ *mq, void *msg_handle) -{ - RBMQ_InternalDataHdr *idh; - RBMQ_Msg *msg_info; - uint32_t idx; - - if (ValidateMsgHandle(mq, msg_handle)) - return -EINVAL; - - msg_info = (RBMQ_Msg *) msg_handle; - - /* Sanity checks... */ - if (msg_info->state != RBMQ_MSG_STATE_RESERVED) - { - ErrorMessage("%s: Attempted to discard an unreserved message! (State: %hhu)\n", __FUNCTION__, msg_info->state); - return -EINVAL; - } - - msg_info->state = RBMQ_MSG_STATE_DISCARDED; - - /* Working backward from the last entry reserved (in order), release discarded messages as allowed. - Any discarded messages that we can't release here will have to wait until something gets ACK'd. */ - idx = mq->msg_ring.last_reserved; - msg_info = &mq->msg_ring.msgs[idx]; - while (msg_info->state == RBMQ_MSG_STATE_DISCARDED) - { - /* Clean up the data ring state if this was internally allocated. Only internally allocated - messages can be discarded, so this should be safe. */ - idh = (RBMQ_InternalDataHdr *) (msg_info->data - sizeof(RBMQ_InternalDataHdr)); - mq->data_ring.write_offset = idh->prev_offset; - - /* Reset the state to unused so that it can be reserved again. */ - msg_info->state = RBMQ_MSG_STATE_UNUSED; - - /* Finally, update the last reserved index. */ - idx = DecrementMessageIndex(mq, idx); - mq->msg_ring.last_reserved = idx; - msg_info = &mq->msg_ring.msgs[idx]; - } - - return 0; -} - -int RBMQ_CommitExternalMsg(RBMQ *mq, const void *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc) -{ - RBMQ_Msg *msg_info; - uint32_t idx; - - /* V Reserve and commit the message all in one step. V */ - - /* Find the next entry in the message ring to reserve. */ - idx = IncrementMessageIndex(mq, mq->msg_ring.last_reserved); - msg_info = &mq->msg_ring.msgs[idx]; - - /* Bail if the entry is in use. */ - if (msg_info->state != RBMQ_MSG_STATE_UNUSED) - return -ENOMEM; - - /* Require a header if there is a header size specified for the control ring and copy it over. */ - if (mq->msg_ring.header_size) - { - if (!hdr) - return -EINVAL; - memcpy(mq->msg_ring.headers + (idx * mq->msg_ring.header_size), hdr, mq->msg_ring.header_size); - } - - msg_info->length = length; - msg_info->flags = RBMQ_MSG_FLAG_EXTERNAL; - msg_info->state = RBMQ_MSG_STATE_COMMITTED; - msg_info->data = msg; - msg_info->msgFreeFunc = msgFreeFunc; - - /* Update the last reservation index in the control ring. */ - mq->msg_ring.last_reserved = idx; - - return 0; -} - -int RBMQ_ReadMsg(RBMQ *mq, const void **hdr_ptr, const uint8_t **msg_ptr, uint32_t *length, void **msg_handle) -{ - RBMQ_Msg *msg_info; - uint32_t idx; - - /* Find the next entry in the message ring to read. */ - idx = IncrementMessageIndex(mq, mq->msg_ring.last_read); - msg_info = &mq->msg_ring.msgs[idx]; - - /* Skip over discarded messages -- the next ACK should clear them out. */ - while (msg_info->state == RBMQ_MSG_STATE_DISCARDED) - { - mq->msg_ring.last_read = idx; - idx = IncrementMessageIndex(mq, idx); - msg_info = &mq->msg_ring.msgs[idx]; - } - - /* Return an error if there is not a committed entry ready to be read. */ - if (msg_info->state != RBMQ_MSG_STATE_COMMITTED) - return -ENOENT; - - if (mq->msg_ring.header_size) - *hdr_ptr = mq->msg_ring.headers + (idx * mq->msg_ring.header_size); - else - *hdr_ptr = NULL; - *msg_ptr = msg_info->data; - *length = msg_info->length; - *msg_handle = msg_info; - - msg_info->state = RBMQ_MSG_STATE_READ; - mq->msg_ring.last_read = idx; - - return 0; -} - -int RBMQ_AckMsg(RBMQ *mq, void *msg_handle) -{ - RBMQ_Msg *msg_info; - uint32_t idx; - - /* Sanity checking... */ - if (ValidateMsgHandle(mq, msg_handle)) - return -EINVAL; - - msg_info = (RBMQ_Msg *) msg_handle; - if (msg_info->state != RBMQ_MSG_STATE_READ) - { - ErrorMessage("%s: Attempted to ACK an unread message! (State: %hhu)\n", __FUNCTION__, msg_info->state); - return -EINVAL; - } - - /* Call the user defined free function to release the message data if it exists. */ - if (msg_info->data && msg_info->msgFreeFunc) - msg_info->msgFreeFunc(msg_info->data); - - msg_info->state = RBMQ_MSG_STATE_ACKED; - - /* Working forward from the last entry ACK'd (in order), release ACK'd and discarded messages as allowed. */ - do { - idx = IncrementMessageIndex(mq, mq->msg_ring.last_acked); - msg_info = &mq->msg_ring.msgs[idx]; - if (msg_info->state != RBMQ_MSG_STATE_ACKED && msg_info->state != RBMQ_MSG_STATE_DISCARDED) - break; - - /* Clean up the data ring state if this was internally allocated. We are guaranteed that internal - allocations will be sequential in relation to sequential control entries.*/ - if (!(msg_info->flags & RBMQ_MSG_FLAG_EXTERNAL)) - mq->data_ring.read_offset = msg_info->data + msg_info->length - mq->data_ring.data; - - /* Reset the state to unused so it can be reserved again. */ - msg_info->state = RBMQ_MSG_STATE_UNUSED; - - /* Finally, update the last ACK'd index to accurately represent how far processing has gotten. */ - mq->msg_ring.last_acked = idx; - } while (mq->msg_ring.last_acked != mq->msg_ring.last_read); - - return 0; -} - -int RBMQ_IsEmpty(RBMQ *mq) -{ - RBMQ_Msg *msg_info; - uint32_t idx; - - /* Find the next entry in the message ring to read and return true if it's not committed. */ - idx = IncrementMessageIndex(mq, mq->msg_ring.last_read); - msg_info = &mq->msg_ring.msgs[idx]; - - return (msg_info->state != RBMQ_MSG_STATE_COMMITTED); -} - -void RBMQ_Stats(RBMQ_Ptr mq, const char *indent) -{ -} - -#endif /* !SC_USE_DMQ */ - -#endif /* SIDE_CHANNEL */ diff --git a/src/side_channel/rbmq.h b/src/side_channel/rbmq.h deleted file mode 100644 index 205b22ed0..000000000 --- a/src/side_channel/rbmq.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ - -#ifndef RBMQ_H -#define RBMQ_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "sidechannel_define.h" - -#ifndef SC_USE_DMQ - -typedef struct _rbmq *RBMQ_Ptr; - -RBMQ_Ptr RBMQ_Alloc(uint32_t msg_ring_entries, uint16_t msg_ring_header_size, uint32_t data_ring_size); -int RBMQ_ReserveMsg(RBMQ_Ptr mq, uint32_t length, void **hdr_ptr, uint8_t **msg_ptr, void **msg_handle); -int RBMQ_CommitReservedMsg(RBMQ_Ptr mq, void *msg_handle, uint32_t length, SCMQMsgFreeFunc msgFreeFunc); -int RBMQ_DiscardReservedMsg(RBMQ_Ptr mq, void *msg_handle); -int RBMQ_CommitExternalMsg(RBMQ_Ptr mq, const void *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc); -int RBMQ_ReadMsg(RBMQ_Ptr mq, const void **hdr_ptr, const uint8_t **msg_ptr, uint32_t *length, void **msg_handle); -int RBMQ_AckMsg(RBMQ_Ptr mq, void *msg_handle); -int RBMQ_IsEmpty(RBMQ_Ptr mq); -void RBMQ_Stats(RBMQ_Ptr mq, const char *indent); - -#endif /* !SC_USE_DMQ */ - -#endif /* RBMQ_H */ diff --git a/src/side_channel/sidechannel.cc b/src/side_channel/sidechannel.cc deleted file mode 100644 index c9f01b9d2..000000000 --- a/src/side_channel/sidechannel.cc +++ /dev/null @@ -1,975 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ - -#include "sidechannel.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef SIDE_CHANNEL -#include -#include - -#include "dmq.h" -#include "rbmq.h" -#include "plugins/sscm_logger.h" -#include "helpers/process.h" - -#define DEFAULT_RX_QUEUE_DEPTH 1024 -#define DEFAULT_RX_QUEUE_DATA_SIZE 10485760 -#define DEFAULT_TX_QUEUE_DEPTH 1024 -#define DEFAULT_TX_QUEUE_DATA_SIZE 10485760 - -#define CONF_SEPARATORS " \t\n\r," -#define CONF_RX_QUEUE_DATA_SIZE "rx-queue-data-size" -#define CONF_RX_QUEUE_DEPTH "rx-queue-depth" -#define CONF_TX_QUEUE_DATA_SIZE "tx-queue-data-size" -#define CONF_TX_QUEUE_DEPTH "tx-queue-depth" -#define CONF_DISABLE_TX_THREAD "disable-tx-thread" - -#ifdef SC_USE_DMQ -#define RBMQ_Ptr DMQ_Ptr -#define RBMQ_Alloc DMQ_Alloc -#define RBMQ_ReserveMsg DMQ_ReserveMsg -#define RBMQ_CommitReservedMsg DMQ_CommitReservedMsg -#define RBMQ_DiscardReservedMsg DMQ_DiscardReservedMsg -#define RBMQ_CommitExternalMsg DMQ_CommitExternalMsg -#define RBMQ_ReadMsg DMQ_ReadMsg -#define RBMQ_AckMsg DMQ_AckMsg -#define RBMQ_IsEmpty DMQ_IsEmpty -#define RBMQ_Stats DMQ_Stats -#endif - -enum ConfState -{ - STATE_START, - STATE_RX_QUEUE_DATA_SIZE, - STATE_RX_QUEUE_DEPTH, - STATE_TX_QUEUE_DATA_SIZE, - STATE_TX_QUEUE_DEPTH -}; - -typedef struct _SC_CONFIG -{ - uint32_t rx_queue_max_data_size; - uint32_t rx_queue_max_depth; - uint32_t tx_queue_max_data_size; - uint32_t tx_queue_max_depth; - bool disable_tx_thread; - bool enabled; -} SCConfig; - -typedef struct _SC_MODULE -{ - struct _SC_MODULE *next; - char *keyword; - SCMFunctionBundle funcs; - bool enabled; -} SCModule; - -typedef struct _SC_HANDLER -{ - struct _SC_HANDLER *next; - uint16_t type; - SCMProcessMsgFunc processMsgFunc; - void *data; -} SCHandler; - -typedef struct _SC_MESSAGE_QUEUE -{ - RBMQ_Ptr queue; - pthread_mutex_t mutex; - pthread_cond_t cond; - uint32_t max_data_size; - uint32_t max_depth; -} SCMessageQueue; - -static struct { // FIXIT 1 / process - uint64_t rx_messages_total; - uint64_t rx_messages_processed_ib; - uint64_t rx_messages_processed_oob; - uint64_t tx_messages_total; - uint64_t tx_messages_processed; -} Side_Channel_Stats; - -static volatile int stop_processing = 0; -static volatile int tx_thread_running = 0; - -static pid_t tx_thread_pid; -static pthread_t tx_thread_id; -static pthread_t *p_tx_thread_id; - -static SCConfig sc_config; - -static SCMessageQueue rx_queue; -static SCMessageQueue tx_queue; - -static SCModule *modules; -static SCHandler *rx_handlers; -static SCHandler *tx_handlers; - -#ifdef PERF_PROFILING -//static THREAD_LOCAL PreprocStats sideChannelRxPerfStats; // FIXIT not in use -#endif - -void RegisterSideChannelModules(void) -{ - if (!ScSideChannelEnabled()) - return; - - SetupLoggerSCM(); -} - -void RegisterSideChannelModule(const char *keyword, SCMFunctionBundle *funcs) -{ - SCModule *module, *tmp, *last = NULL; - - if (!ScSideChannelEnabled()) - return; - - if (!keyword) - FatalError("No keyword given while registering a side channel module!\n"); - - if (!funcs) - FatalError("No function bundle given while registering side channel '%s'!\n", keyword); - - for (tmp = modules; tmp; tmp = tmp->next) - { - if (strcasecmp(tmp->keyword, keyword) == 0) - FatalError("Duplicate side channel keyword: %s\n", keyword); - last = tmp; - } - module = (SCModule*)SnortAlloc(sizeof(SCModule)); - - module->next = NULL; - module->keyword = SnortStrdup(keyword); - module->funcs = *funcs; - module->enabled = 0; - - LogMessage("Register SCM '%s' with configFunc=%p, initFunc=%p, postInitFunc=%p, idleFunc=%p, statsFunc=%p, shutdownFunc=%p\n", - keyword, module->funcs.configFunc, module->funcs.initFunc, module->funcs.postInitFunc, - module->funcs.idleFunc, module->funcs.statsFunc, module->funcs.shutdownFunc); - - if (last) - last->next = module; - else - modules = module; -} - -int ConfigureSideChannelModule(const char *keyword, char *opts) -{ - SCModule *module; - - for (module = modules; module; module = module->next) - { - if (strcasecmp(module->keyword, keyword) == 0) - break; - } - if (!module) - return -ENOENT; - - module->funcs.configFunc(opts); - module->enabled = 1; - - return 0; -} - -static int SCRegisterHandler(SCHandler **handlers, uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data) -{ - SCHandler *handler; - - if (!ScSideChannelEnabled()) - return 0; - - handler = (SCHandler*)SnortAlloc(sizeof(SCHandler)); - - handler->next = NULL; - handler->type = type; - handler->processMsgFunc = processMsgFunc; - handler->data = data; - - handler->next = *handlers; - *handlers = handler; - - return 0; -} - -int SideChannelRegisterRXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data) -{ - return SCRegisterHandler(&rx_handlers, type, processMsgFunc, data); -} - -int SideChannelRegisterTXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data) -{ - return SCRegisterHandler(&tx_handlers, type, processMsgFunc, data); -} - -static void SCUnregisterHandler(SCHandler **handlers, uint16_t type, SCMProcessMsgFunc processMsgFunc) -{ - SCHandler *handler, *prev; - - if (!ScSideChannelEnabled()) - return; - - for (prev = NULL, handler = *handlers; handler; prev = handler, handler = handler->next) - { - if (handler->type == type && handler->processMsgFunc == processMsgFunc) - break; - } - - if (handler) - { - if (!prev) - *handlers = handler->next; - else - prev->next = handler->next; - - free(handler); - } -} - -void SideChannelUnregisterRXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc) -{ - SCUnregisterHandler(&rx_handlers, type, processMsgFunc); -} - -void SideChannelUnregisterTXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc) -{ - SCUnregisterHandler(&tx_handlers, type, processMsgFunc); -} - -static int SCPreallocMessage(SCMessageQueue *mq, uint32_t length, SCMsgHdr **hdr_ptr, uint8_t **msg_ptr, void **msg_handle) -{ - int rval; - - pthread_mutex_lock(&mq->mutex); - rval = RBMQ_ReserveMsg(mq->queue, length, (void **) hdr_ptr, msg_ptr, msg_handle); - pthread_mutex_unlock(&mq->mutex); - - return rval; -} - -int SideChannelPreallocMessageRX(uint32_t length, SCMsgHdr **hdr_ptr, uint8_t **msg_ptr, void **msg_handle) -{ - return SCPreallocMessage(&rx_queue, length, hdr_ptr, msg_ptr, msg_handle); -} - -int SideChannelPreallocMessageTX(uint32_t length, SCMsgHdr **hdr_ptr, uint8_t **msg_ptr, void **msg_handle) -{ - return SCPreallocMessage(&tx_queue, length, hdr_ptr, msg_ptr, msg_handle); -} - -static int SCDiscardMessage(SCMessageQueue *mq, void *msg_handle) -{ - int rval; - - pthread_mutex_lock(&mq->mutex); - rval = RBMQ_DiscardReservedMsg(mq->queue, msg_handle); - pthread_mutex_unlock(&mq->mutex); - - return rval; -} - -int SideChannelDiscardMessageRX(void *msg_handle) -{ - return SCDiscardMessage(&rx_queue, msg_handle); -} - -int SideChannelDiscardMessageTX(void *msg_handle) -{ - return SCDiscardMessage(&tx_queue, msg_handle); -} - -static int SCEnqueueMessage(SCMessageQueue *mq, SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc) -{ - int rval; - - if (!msg_handle) - { - SCMsgHdr *hdr_ptr; - uint8_t *msg_ptr; - - rval = RBMQ_ReserveMsg(mq->queue, length, (void **) &hdr_ptr, &msg_ptr, &msg_handle); - if (rval != 0) - { - ErrorMessage("%s: Could not reserve message: %d\n", __FUNCTION__, rval); - return rval; - } - memcpy(msg_ptr, msg, length); - memcpy(hdr_ptr, hdr, sizeof(SCMsgHdr)); - rval = RBMQ_CommitReservedMsg(mq->queue, msg_handle, length, msgFreeFunc); - if (rval != 0) - { - ErrorMessage("%s: Could not commit reserved message: %d\n", __FUNCTION__, rval); - return rval; - } - } - else - rval = RBMQ_CommitReservedMsg(mq->queue, msg_handle, length, msgFreeFunc); - - return rval; -} - -static inline void SCProcessMessage(SCHandler *handlers, SCMsgHdr *hdr, const uint8_t *msg, uint32_t length) -{ - SCHandler *handler; - - for (handler = handlers; handler; handler = handler->next) - { - if (hdr->type == handler->type || handler->type == SC_MSG_TYPE_ANY) - handler->processMsgFunc(hdr, msg, length); - } -} - -static int SCDrainAndProcess(SCMessageQueue *mq, SCHandler *handlers) -{ - SCHandler *handler; - SCMsgHdr *hdr; - uint32_t length; - const uint8_t *msg; - void *msg_handle; - int rval; - - /* Read a message from the queue. */ - pthread_mutex_lock(&mq->mutex); - rval = RBMQ_ReadMsg(mq->queue, (const void **) &hdr, &msg, &length, &msg_handle); - pthread_mutex_unlock(&mq->mutex); - if (rval != 0) - return 1; - - /* Handle it. */ - SCProcessMessage(handlers, hdr, msg, length); - - /* And, finally, acknowledge it. */ - pthread_mutex_lock(&mq->mutex); - rval = RBMQ_AckMsg(mq->queue, msg_handle); - pthread_mutex_unlock(&mq->mutex); - if (rval != 0) - WarningMessage("Error ACK'ing message %p!\n", msg_handle); - - return 0; -} - -/* Called by an out-of-band thread (probably a Side Channel Module). */ -int SideChannelEnqueueMessageRX(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc) -{ - int rval; - - /* - * Because the Snort main thread relinquishes control to DAQ_Acquire for up to a second, - * we potentially need to preempt it and process RX messages as they are being enqueued - * to avoid backups and overruns. - * This should be safe since the main thread holds the snort_process_lock mutex while it - * is not in DAQ_Acquire(). - */ - while (pthread_mutex_trylock(&snort_process_lock) == 0) - { - /* If there are no more messages in the RX queue, process the new message without enqueuing it and return. */ - if (SCDrainAndProcess(&rx_queue, rx_handlers) != 0) - { - SCProcessMessage(rx_handlers, hdr, msg, length); - if (msgFreeFunc) - msgFreeFunc((uint8_t *) msg); - if (msg_handle) - { - pthread_mutex_lock(&rx_queue.mutex); - RBMQ_DiscardReservedMsg(rx_queue.queue, msg_handle); - pthread_mutex_unlock(&rx_queue.mutex); - } - Side_Channel_Stats.rx_messages_total++; - Side_Channel_Stats.rx_messages_processed_oob++; - - pthread_mutex_unlock(&snort_process_lock); - return 0; - } - else - Side_Channel_Stats.rx_messages_processed_oob++; - - pthread_mutex_unlock(&snort_process_lock); - } - - /* Finally, enqueue the message if we really have to. */ - pthread_mutex_lock(&rx_queue.mutex); - rval = SCEnqueueMessage(&rx_queue, hdr, msg, length, msg_handle, msgFreeFunc); - /* TODO: Error check the above call. */ - Side_Channel_Stats.rx_messages_total++; - pthread_mutex_unlock(&rx_queue.mutex); - - return rval; -} - -/* Called in the Snort main thread. */ -int SideChannelEnqueueMessageTX(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc) -{ - int rval, empty; - - /* Only bother queuing if the TX thread is running, otherwise just immediately process. */ - if (tx_thread_running) - { - pthread_mutex_lock(&tx_queue.mutex); - empty = RBMQ_IsEmpty(tx_queue.queue); - rval = SCEnqueueMessage(&tx_queue, hdr, msg, length, msg_handle, msgFreeFunc); - /* TODO: Error check the above call. */ - Side_Channel_Stats.tx_messages_total++; - /* If the queue was empty, signal any waiters. */ - if (empty) - pthread_cond_signal(&tx_queue.cond); - pthread_mutex_unlock(&tx_queue.mutex); - } - else - { - SCProcessMessage(tx_handlers, hdr, msg, length); - Side_Channel_Stats.tx_messages_total++; - Side_Channel_Stats.tx_messages_processed++; - if (msgFreeFunc) - msgFreeFunc((uint8_t *) msg); - if (msg_handle) - { - pthread_mutex_lock(&tx_queue.mutex); - RBMQ_DiscardReservedMsg(tx_queue.queue, msg_handle); - pthread_mutex_unlock(&tx_queue.mutex); - } - rval = 0; - } - - return rval; -} - -static int SCEnqueueData(SCMessageQueue *mq, SCMsgHdr *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc) -{ - return RBMQ_CommitExternalMsg(mq->queue, hdr, msg, length, msgFreeFunc); -} - -/* Called by an out-of-band thread (probably a Side Channel Module). */ -int SideChannelEnqueueDataRX(SCMsgHdr *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc) -{ - int rval; - - pthread_mutex_lock(&rx_queue.mutex); - rval = SCEnqueueData(&rx_queue, hdr, msg, length, msgFreeFunc); - /* TODO: Error check the above call. */ - Side_Channel_Stats.rx_messages_total++; - pthread_mutex_unlock(&rx_queue.mutex); - - return rval; -} - -/* Called in the Snort main thread. */ -int SideChannelEnqueueDataTX(SCMsgHdr *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc) -{ - int rval, empty; - - /* Only bother queuing if the TX thread is running, otherwise just immediately process. */ - if (tx_thread_running) - { - pthread_mutex_lock(&tx_queue.mutex); - empty = RBMQ_IsEmpty(tx_queue.queue); - rval = SCEnqueueData(&tx_queue, hdr, msg, length, msgFreeFunc); - /* TODO: Error check the above call. */ - Side_Channel_Stats.tx_messages_total++; - /* If the queue was empty, signal any waiters. */ - if (empty) - pthread_cond_signal(&tx_queue.cond); - pthread_mutex_unlock(&tx_queue.mutex); - } - else - { - SCProcessMessage(tx_handlers, hdr, msg, length); - Side_Channel_Stats.tx_messages_total++; - Side_Channel_Stats.tx_messages_processed++; - msgFreeFunc(msg); - rval = 0; - } - - return rval; -} - -/* Called in the Snort main thread. */ -uint32_t SideChannelDrainRX(unsigned max_msgs) -{ - uint32_t processed = 0; - - if (!ScSideChannelEnabled()) - return 0; - - if (RBMQ_IsEmpty(rx_queue.queue)) - return 0; - - while (!max_msgs || processed < max_msgs) - { - if (stop_processing || SCDrainAndProcess(&rx_queue, rx_handlers) != 0) - break; - - Side_Channel_Stats.rx_messages_processed_ib++; - processed++; - } - - return processed; -} - -static void *SideChannelThread(void *arg) -{ - struct timespec ts; - struct timeval tv; - SCHandler *handler; - SCModule *module; - SCMsgHdr *hdr; - uint32_t length; - const uint8_t *msg; - void *msg_handle; - int rval; - - tx_thread_pid = gettid(); - tx_thread_running = 1; - - pthread_mutex_lock(&tx_queue.mutex); - while (!stop_processing) - { - /* If the message queue is empty, we will stop without unlocking it so we can immediately start a timed wait. */ - while ((rval = RBMQ_ReadMsg(tx_queue.queue, (const void **) &hdr, &msg, &length, &msg_handle)) == 0) - { - pthread_mutex_unlock(&tx_queue.mutex); - - for (handler = tx_handlers; handler; handler = handler->next) - { - if (hdr->type == handler->type || handler->type == SC_MSG_TYPE_ANY) - handler->processMsgFunc(hdr, msg, length); - } - - pthread_mutex_lock(&tx_queue.mutex); - rval = RBMQ_AckMsg(tx_queue.queue, msg_handle); - if (rval != 0) - WarningMessage("Error ACK'ing message %p!\n", msg_handle); - /* Again, not unlocking so that we're already locked for the three places we can go - from here, which are all expecting it (dequeue, timed wait, or done). */ - - Side_Channel_Stats.tx_messages_processed++; - if (stop_processing) - goto done; - } - gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec + 10; - ts.tv_nsec = tv.tv_usec * 1000; - rval = pthread_cond_timedwait(&tx_queue.cond, &tx_queue.mutex, &ts); - /* If we timed out waiting for new output messages to process, run the registered idle routines. */ - if (rval == ETIMEDOUT && !stop_processing) - { - for (module = modules; module; module = module->next) - { - if (module->enabled && module->funcs.idleFunc) - module->funcs.idleFunc(); - } - } - } -done: - pthread_mutex_unlock(&tx_queue.mutex); - - LogMessage("Side Channel thread exiting...\n"); - - return NULL; -} - -static void SCParseConfiguration(SnortConfig *sc, SCConfig *config) -{ - long int value; - char *token, *argcpy, *endptr; - enum ConfState confState = STATE_START; - - memset(config, 0, sizeof(SCConfig)); - - config->enabled = sc->side_channel_config.enabled; - if (!config->enabled) - return; - - config->rx_queue_max_data_size = DEFAULT_RX_QUEUE_DATA_SIZE; - config->rx_queue_max_depth = DEFAULT_RX_QUEUE_DEPTH; - config->tx_queue_max_data_size = DEFAULT_TX_QUEUE_DATA_SIZE; - config->tx_queue_max_depth = DEFAULT_TX_QUEUE_DEPTH; - config->disable_tx_thread = false; - - if (!sc->side_channel_config.opts) - return; - - argcpy = sc->side_channel_config.opts; - char* lasts = ""; - - for (token = strtok_r(argcpy, CONF_SEPARATORS, &lasts); - token; - token = strtok_r(NULL, CONF_SEPARATORS, &lasts)) - { - switch (confState) - { - case STATE_START: - if (strcmp(token, CONF_RX_QUEUE_DATA_SIZE) == 0) - confState = STATE_RX_QUEUE_DATA_SIZE; - else if (strcmp(token, CONF_RX_QUEUE_DEPTH) == 0) - confState = STATE_RX_QUEUE_DEPTH; - else if (strcmp(token, CONF_TX_QUEUE_DATA_SIZE) == 0) - confState = STATE_TX_QUEUE_DATA_SIZE; - else if (strcmp(token, CONF_TX_QUEUE_DEPTH) == 0) - confState = STATE_TX_QUEUE_DEPTH; - else if (strcmp(token, CONF_DISABLE_TX_THREAD) == 0) - config->disable_tx_thread = true; - else - FatalError("Invalid side channel configuration token: '%s'\n", token); - break; - case STATE_RX_QUEUE_DATA_SIZE: - confState = STATE_START; - value = SnortStrtoul(token, &endptr, 0); - if (errno != 0 || *endptr != '\0') - FatalError("Invalid argument for side channel RX queue data size: '%s'\n", token); - config->rx_queue_max_data_size = value; - break; - case STATE_RX_QUEUE_DEPTH: - confState = STATE_START; - value = SnortStrtoul(token, &endptr, 0); - if (errno != 0 || *endptr != '\0') - FatalError("Invalid argument for side channel RX queue depth: '%s'\n", token); - config->rx_queue_max_depth = value; - break; - case STATE_TX_QUEUE_DATA_SIZE: - confState = STATE_START; - value = SnortStrtoul(token, &endptr, 0); - if (errno != 0 || *endptr != '\0') - FatalError("Invalid argument for side channel TX queue data size: '%s'\n", token); - config->tx_queue_max_data_size = value; - break; - case STATE_TX_QUEUE_DEPTH: - confState = STATE_START; - value = SnortStrtoul(token, &endptr, 0); - if (errno != 0 || *endptr != '\0') - FatalError("Invalid argument for side channel TX queue depth: '%s'\n", token); - config->tx_queue_max_depth = value; - break; - default: - break; - } - } -} - -int SideChannelVerifyConfig(SnortConfig *sc) -{ - SCConfig config; - - SCParseConfiguration(sc, &config); - - return memcmp(&config, &sc_config, sizeof(SCConfig)); -} - -void SideChannelConfigure(SnortConfig *sc) -{ - if (!sc->side_channel_config.enabled) - return; - - SCParseConfiguration(sc, &sc_config); - - rx_queue.max_data_size = sc_config.rx_queue_max_data_size; - rx_queue.max_depth = sc_config.rx_queue_max_depth; - tx_queue.max_data_size = sc_config.tx_queue_max_data_size; - tx_queue.max_depth = sc_config.tx_queue_max_depth; - - LogMessage("Side Channel config:\n"); - LogMessage(" RX Queue Max Data Size: %u\n", sc_config.rx_queue_max_data_size); - LogMessage(" RX Queue Max Depth: %u\n", sc_config.rx_queue_max_depth); - LogMessage(" TX Queue Max Data Size: %u\n", sc_config.tx_queue_max_data_size); - LogMessage(" RX Queue Max Depth: %u\n", sc_config.tx_queue_max_depth); -} - -void SideChannelInit(void) -{ - SCModule *module; - - if (!ScSideChannelEnabled()) - return; - - pthread_mutex_init(&rx_queue.mutex, NULL); - pthread_cond_init(&rx_queue.cond, NULL); - rx_queue.queue = RBMQ_Alloc(rx_queue.max_depth, sizeof(SCMsgHdr), rx_queue.max_data_size); - - pthread_cond_init(&tx_queue.cond, NULL); - pthread_mutex_init(&tx_queue.mutex, NULL); - tx_queue.queue = RBMQ_Alloc(tx_queue.max_depth, sizeof(SCMsgHdr), tx_queue.max_data_size); - - for (module = modules; module; module = module->next) - { - if (module->enabled && module->funcs.initFunc) - module->funcs.initFunc(); - } -} - -void SideChannelStartTXThread(void) -{ - const struct timespec thread_sleep = { 0, 100 }; - SCModule *module; - sigset_t mask; - int found, rval; - - if (!ScSideChannelEnabled()) - return; - - if (sc_config.disable_tx_thread) - return; - - /* Avoid starting the TX thread if there are no TX handlers or TX idle tasks registered. */ - found = 0; - for (module = modules; module; module = module->next) - { - if (module->enabled && module->funcs.idleFunc) - { - found = 1; - break; - } - } - if (!found && !tx_handlers) - { - LogMessage("Not starting unnecessary Side Channel TX thread.\n"); - return; - } - - /* Spin off the Side Channel handler thread. */ - sigemptyset(&mask); - sigaddset(&mask, SIGTERM); - sigaddset(&mask, SIGQUIT); - sigaddset(&mask, SIGPIPE); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGNAL_SNORT_RELOAD); - sigaddset(&mask, SIGNAL_SNORT_DUMP_STATS); - sigaddset(&mask, SIGUSR1); - sigaddset(&mask, SIGUSR2); - sigaddset(&mask, SIGNAL_SNORT_ROTATE_STATS); - sigaddset(&mask, SIGNAL_SNORT_CHILD_READY); - sigaddset(&mask, SIGNAL_SNORT_READ_ATTR_TBL); - sigaddset(&mask, SIGVTALRM); - pthread_sigmask(SIG_SETMASK, &mask, NULL); - - if ((rval = pthread_create(&tx_thread_id, NULL, &SideChannelThread, NULL)) != 0) - { - sigemptyset(&mask); - pthread_sigmask(SIG_SETMASK, &mask, NULL); - FatalError("Side Channel: Unable to create thread: %s\n", get_error(rval)); - } - while (!tx_thread_running) - nanosleep(&thread_sleep, NULL); - - p_tx_thread_id = &tx_thread_id; - sigemptyset(&mask); - pthread_sigmask(SIG_SETMASK, &mask, NULL); - LogMessage("Side Channel TX thread started tid=%p (pid=%u)\n", (void *) tx_thread_id, tx_thread_pid); -} - -void SideChannelStopTXThread(void) -{ - int rval; - - if (!ScSideChannelEnabled()) - return; - - if (p_tx_thread_id != NULL) - { - stop_processing = 1; - pthread_mutex_lock(&tx_queue.mutex); - pthread_cond_signal(&tx_queue.cond); - pthread_mutex_unlock(&tx_queue.mutex); - if ((rval = pthread_join(*p_tx_thread_id, NULL)) != 0) - WarningMessage("Side channel TX thread termination returned an error: %s\n", get_error(rval)); - } -} - -int SideChannelPostInit(void) -{ - SCModule *module; - - if (!ScSideChannelEnabled()) - return 0; - - for (module = modules; module; module = module->next) - { - if (module->enabled && module->funcs.postInitFunc) - module->funcs.postInitFunc(); - } - - return 0; -} - -void SideChannelStats(const char *separator) -{ - SCModule *module; - - if (!ScSideChannelEnabled()) - return; - - LogMessage("%s\n", separator); - LogMessage("Side Channel:\n"); - LogMessage(" RX Messages Total: %" PRIu64 "\n", Side_Channel_Stats.rx_messages_total); - LogMessage(" RX Messages Processed (IB): %" PRIu64 "\n", Side_Channel_Stats.rx_messages_processed_ib); - LogMessage(" RX Messages Processed (OOB): %" PRIu64 "\n", Side_Channel_Stats.rx_messages_processed_oob); - LogMessage(" TX Messages Total: %" PRIu64 "\n", Side_Channel_Stats.tx_messages_total); - LogMessage(" TX Messages Processed: %" PRIu64 "\n", Side_Channel_Stats.tx_messages_processed); - - for (module = modules; module; module = module->next) - { - if (module->enabled && module->funcs.statsFunc) - { - LogMessage("%s\n", separator); - module->funcs.statsFunc(0); - } - } - - LogMessage(" RX Queue Stats:\n"); - RBMQ_Stats(rx_queue.queue, " "); - - LogMessage(" TX Queue Stats:\n"); - RBMQ_Stats(tx_queue.queue, " "); -} - -void SideChannelCleanUp(void) -{ - SCModule *module; - - if (!ScSideChannelEnabled()) - return; - - while ((module = modules)) - { - if (module->enabled) - { - if (module->funcs.statsFunc) - module->funcs.statsFunc(1); - - if (module->funcs.shutdownFunc) - module->funcs.shutdownFunc(); - } - modules = module->next; - free(module->keyword); - free(module); - } - pthread_cond_destroy(&tx_queue.cond); - pthread_mutex_destroy(&tx_queue.mutex); - pthread_cond_destroy(&rx_queue.cond); - pthread_mutex_destroy(&rx_queue.mutex); -} - -/* - * WARNING: Messages are being written in and read assuming host byte order. - */ - -static inline ssize_t Write(int fd, const void *buf, size_t count) -{ - ssize_t n; - errno = 0; - - while ((n = write(fd, buf, count)) <= (ssize_t) count) - { - if (n == (ssize_t) count) - return 0; - - if (n > 0) - count -= n; - else if (errno != EINTR) - break; - } - - return -1; -} - -int SideChannelWriteMsgToFile(int fd, SCMsgHdr *hdr, const uint8_t *msg, uint32_t length) -{ - if (Write(fd, &hdr->type, sizeof(hdr->type)) != 0) - return -1; - - if (Write(fd, &hdr->timestamp, sizeof(hdr->timestamp)) != 0) - return -1; - - if (Write(fd, &length, sizeof(length)) != 0) - return -1; - - if (Write(fd, msg, length) != 0) - return -1; - - return 0; -} - -static inline ssize_t Read(int fd, void *buf, size_t count) -{ - ssize_t n; - errno = 0; - - while ((n = read(fd, buf, count)) <= (ssize_t) count) - { - if (n == (ssize_t) count) - return 0; - - if (n > 0) - { - count -= n; - buf = (uint8_t *) buf + n; - } - else if (n == 0) - break; - else if (errno != EINTR) - { - ErrorMessage("Error reading Logger SCM log file: %s (%d)\n", get_error(errno), errno); - break; - } - } - return -1; -} - -int SideChannelReadMsgFromFile(int fd, SCMsgHdr *hdr, uint8_t **msg_ptr, uint32_t *length_ptr) -{ - uint64_t timestamp; - uint32_t length; - uint16_t type; - uint8_t *msg; - - if (Read(fd, &type, sizeof(type)) != 0) - return -1; - - if (Read(fd, ×tamp, sizeof(timestamp)) != 0) - return -1; - - if (Read(fd, &length, sizeof(length)) != 0) - return -1; - - if (length > 0) - { - msg = (uint8_t*)SnortAlloc(length); - if (Read(fd, msg, length) != 0) - { - free(msg); - return -1; - } - } - else - msg = NULL; - - hdr->type = type; - hdr->timestamp = timestamp; - *length_ptr = length; - *msg_ptr = msg; - - return 0; -} - -#endif /* SIDE_CHANNEL */ diff --git a/src/side_channel/sidechannel.h b/src/side_channel/sidechannel.h deleted file mode 100644 index 0c0bc3f45..000000000 --- a/src/side_channel/sidechannel.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ - -#ifndef SIDECHANNEL_H -#define SIDECHANNEL_H - -#include "sidechannel_define.h" -#include "snort.h" - -void SideChannelConfigure(SnortConfig *sc); -void SideChannelInit(void); -void SideChannelStartTXThread(void); -void SideChannelStopTXThread(void); -void SideChannelCleanUp(void); - -void RegisterSideChannelModule(const char *keyword, SCMFunctionBundle *funcs); -void RegisterSideChannelModules(void); -int SideChannelRegisterRXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data); -int SideChannelRegisterTXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data); -void SideChannelUnregisterRXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc); -void SideChannelUnregisterTXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc); - -/* RX Functions */ -int SideChannelPreallocMessageRX(uint32_t length, SCMsgHdr **hdr_ptr, uint8_t **msg_ptr, void **msg_handle); -int SideChannelDiscardMessageRX(void *msg_handle); -int SideChannelEnqueueMessageRX(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc); -int SideChannelEnqueueDataRX(SCMsgHdr *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc); -uint32_t SideChannelDrainRX(unsigned max_msgs); - -/* TX Functions */ -int SideChannelPreallocMessageTX(uint32_t length, SCMsgHdr **hdr_ptr, uint8_t **msg_ptr, void **msg_handle); -int SideChannelDiscardMessageTX(void *msg_handle); -int SideChannelEnqueueMessageTX(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc); -int SideChannelEnqueueDataTX(SCMsgHdr *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc); - -/* I/O Functions */ -int SideChannelWriteMsgToFile(int fd, SCMsgHdr *hdr, const uint8_t *msg, uint32_t length); -int SideChannelReadMsgFromFile(int fd, SCMsgHdr *hdr, uint8_t **msg_ptr, uint32_t *length_ptr); - -int SideChannelVerifyConfig(SnortConfig *sc); - -int ConfigureSideChannelModule(const char *keyword, char *opts); -void SideChannelStats(const char *separator); -int SideChannelPostInit(void); - -#endif diff --git a/src/side_channel/sidechannel_define.h b/src/side_channel/sidechannel_define.h deleted file mode 100644 index d06030056..000000000 --- a/src/side_channel/sidechannel_define.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. You may not use, modify or - * distribute this program under any other version of the GNU General - * Public License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. - * Copyright (C) 2012-2013 Sourcefire, Inc. - * - * Author: Michael Altizer - * - */ - -#ifndef SIDECHANNEL_DEFINE_H -#define SIDECHANNEL_DEFINE_H - -#include - -#define SC_USE_DMQ 1 - -/* You get 16 bits worth of types. Use them wisely. */ -enum -{ - SC_MSG_TYPE_NONE = 0, - SC_MSG_TYPE_FLOW_STATE_TRACKING, - SC_MSG_TYPE_ANY = 0xFFFF -}; - -typedef struct _SC_MESSAGE_HEADER -{ - uint16_t type; - uint64_t timestamp; -} SCMsgHdr; - -typedef struct _SC_MESSAGE_QUEUE_NODE *SCMessageQueueNodePtr; - -typedef void (*SCMQMsgFreeFunc)(void *); - -typedef int (*SCMConfigFunc)(char *); -typedef int (*SCMInitFunc)(void); -typedef int (*SCMPostInitFunc)(void); -typedef void (*SCMStatsFunc)(int exiting); -typedef void (*SCMIdleFunc)(void); -typedef int (*SCMProcessMsgFunc)(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length); -typedef void (*SCMShutdownFunc)(void); - -typedef struct _SCM_FUNCTION_BUNDLE { - SCMConfigFunc configFunc; - SCMInitFunc initFunc; - SCMPostInitFunc postInitFunc; - SCMIdleFunc idleFunc; - SCMStatsFunc statsFunc; - SCMShutdownFunc shutdownFunc; -} SCMFunctionBundle; - -#endif /* SIDECHANNEL_DEFINE_H */ diff --git a/src/utils/stats.cc b/src/utils/stats.cc index 96ee33726..f88606550 100644 --- a/src/utils/stats.cc +++ b/src/utils/stats.cc @@ -35,10 +35,6 @@ #include "managers/inspector_manager.h" #include "managers/packet_manager.h" -#ifdef SIDE_CHANNEL -#include "side_channel/sidechannel.h" -#endif - #define STATS_SEPARATOR \ "--------------------------------------------------" @@ -316,10 +312,6 @@ void DropStats() show_stats((PegCount*)&gpc, pc_names, array_size(pc_names), "detection"); -#ifdef SIDE_CHANNEL - SideChannelStats(STATS_SEPARATOR); -#endif - proc_stats.attribute_table_hosts = SFAT_NumberOfHosts(); show_stats((PegCount*)&proc_stats, proc_names, array_size(proc_names), "process"); } diff --git a/src/utils/util.cc b/src/utils/util.cc index a0aae8f02..2a9c07279 100644 --- a/src/utils/util.cc +++ b/src/utils/util.cc @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -63,15 +62,11 @@ #include "target_based/sftarget_reader.h" #include "stream/stream.h" -#ifdef SIDE_CHANNEL -#include "side_channel/sidechannel.h" -#endif - #ifdef PATH_MAX #define PATH_MAX_UTIL PATH_MAX #else #define PATH_MAX_UTIL 1024 -#endif /* PATH_MAX */ +#endif // You may need to adjust this on the systems which don't have standard paths // defined. diff --git a/src/utils/util.h b/src/utils/util.h index a61736c5a..b2946aa43 100644 --- a/src/utils/util.h +++ b/src/utils/util.h @@ -135,6 +135,7 @@ static inline void* SnortAlloc (unsigned long size) if ( pv ) return pv; + // FIXIT do not FatalError() on runtime allocation failures FatalError("Unable to allocate memory! (%lu requested)\n", size); return NULL;