"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/dynamic-plugins/sf_dynamic_plugins.c" (16 Oct 2020, 102498 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sf_dynamic_plugins.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 /* $Id: */
    2 /*
    3  * sf_dynamic_plugins.c
    4  *
    5  * This program is free software; you can redistribute it and/or modify
    6  * it under the terms of the GNU General Public License Version 2 as
    7  * published by the Free Software Foundation.  You may not use, modify or
    8  * distribute this program under any other version of the GNU General
    9  * Public License.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   19  *
   20  * Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
   21  * Copyright (C) 2005-2013 Sourcefire, Inc.
   22  *
   23  * Author: Steven Sturges
   24  *
   25  * Dynamic Library Loading for Snort
   26  *
   27  */
   28 #ifdef HAVE_CONFIG_H
   29 #include "config.h"
   30 #endif
   31 
   32 #ifndef WIN32
   33 #include <unistd.h>
   34 #include <stdlib.h>
   35 #include <string.h>
   36 #include <sys/types.h>
   37 #include <limits.h>
   38 #include <dirent.h>
   39 #include <dlfcn.h>
   40 #include <fnmatch.h>
   41 #if defined(HPUX)
   42 #define MODULE_EXT "*.sl"
   43 #else
   44 #define MODULE_EXT "*.so*"
   45 #endif
   46 typedef void * PluginHandle;
   47 #else /* !WIN32 */
   48 #include <windows.h>
   49 #define MODULE_EXT "dll"
   50 typedef HANDLE PluginHandle;
   51 /* Of course, WIN32 couldn't do things the unix way...
   52  * Define a few of these to get around portability issues.
   53  */
   54 #define getcwd _getcwd
   55 #ifndef PATH_MAX
   56 #define PATH_MAX MAX_PATH
   57 #endif
   58 #endif /* !WIN32 */
   59 
   60 #include <errno.h>
   61 #include <stdarg.h>
   62 
   63 #if defined(FEAT_OPEN_APPID)
   64 #include <pthread.h>
   65 #endif
   66 
   67 #include "config.h"
   68 #include "decode.h"
   69 #include "encode.h"
   70 #include "snort_debug.h"
   71 #include "detect.h"
   72 #include "util.h"
   73 #include "snort.h"
   74 #include "memory_stats.h"
   75 #include "sf_dynamic_engine.h"
   76 #include "sf_dynamic_detection.h"
   77 #include "sf_dynamic_preprocessor.h"
   78 #include "sf_dynamic_decompression.h"
   79 #include "sp_dynamic.h"
   80 #include "sp_preprocopt.h"
   81 #include "sp_pcre.h"
   82 #include "util.h"
   83 #include "event_queue.h"
   84 #include "plugbase.h"
   85 #include "sfthreshold.h"
   86 #include "active.h"
   87 #include "mstring.h"
   88 #include "sfsnprintfappend.h"
   89 #include "session_api.h"
   90 #include "stream_api.h"
   91 #include "sf_iph.h"
   92 #include "fpdetect.h"
   93 #include "sfportobject.h"
   94 #include <pcre.h>
   95 #include "parser.h"
   96 #include "event_wrapper.h"
   97 #include "util.h"
   98 #include "detection_util.h"
   99 #include "sfcontrol_funcs.h"
  100 #include "idle_processing_funcs.h"
  101 #include "../dynamic-output/plugins/output.h"
  102 #include "file_api.h"
  103 #include "packet_time.h"
  104 #include "perf_indicators.h"
  105 #include "reload.h"
  106 #include "so_rule_mem_adjust.h"
  107 
  108 #ifdef SNORT_RELOAD
  109 #include "appdata_adjuster.h"
  110 #endif
  111 
  112 #if defined(FEAT_OPEN_APPID)
  113 #include "appIdApi.h"
  114 #endif /* defined(FEAT_OPEN_APPID) */
  115 
  116 #ifdef TARGET_BASED
  117 #include "target-based/sftarget_protocol_reference.h"
  118 #include "target-based/sftarget_reader.h"
  119 #endif
  120 
  121 #ifdef SIDE_CHANNEL
  122 #include "sidechannel.h"
  123 #include "sf_dynamic_side_channel.h"
  124 #endif
  125 
  126 #ifndef DEBUG_MSGS
  127 char *no_file = "unknown";
  128 int no_line = 0;
  129 #endif
  130 
  131 #ifdef SNORT_RELOAD
  132 static APPDATA_ADJUSTER *ada;
  133 #endif
  134 
  135 /* Predeclare this */
  136 void VerifySharedLibUniqueness();
  137 typedef int (*LoadLibraryFunc)(SnortConfig *sc, const char * const path, int indent);
  138 
  139 typedef struct _DynamicEnginePlugin
  140 {
  141     PluginHandle handle;
  142     DynamicPluginMeta metaData;
  143     InitEngineLibFunc initFunc;
  144     CompatibilityFunc versCheck;
  145     struct _DynamicEnginePlugin *next;
  146     struct _DynamicEnginePlugin *prev;
  147 } DynamicEnginePlugin;
  148 
  149 static DynamicEnginePlugin *loadedEngines = NULL;
  150 
  151 typedef struct _DynamicPreprocessorPlugin
  152 {
  153     PluginHandle handle;
  154     DynamicPluginMeta metaData;
  155     InitPreprocessorLibFunc initFunc;
  156     struct _DynamicPreprocessorPlugin *next;
  157     struct _DynamicPreprocessorPlugin *prev;
  158 } DynamicPreprocessorPlugin;
  159 
  160 static DynamicPreprocessorPlugin *loadedPreprocessorPlugins = NULL;
  161 
  162 typedef struct _LoadableModule
  163 {
  164     char *prefix;
  165     char *name;
  166     struct _LoadableModule *next;
  167 
  168 } LoadableModule;
  169 
  170 void CloseDynamicLibrary(PluginHandle handle)
  171 {
  172 #ifndef WIN32
  173 # ifndef DISABLE_DLCLOSE_FOR_VALGRIND_TESTING
  174     dlclose(handle);
  175 # endif
  176 #else
  177     FreeLibrary(handle);
  178 #endif
  179 }
  180 
  181 #define NONFATAL 0
  182 #define FATAL 1
  183 
  184 typedef void (*dlsym_func)(void);
  185 
  186 static dlsym_func getSymbol(
  187     PluginHandle handle, char *symbol, DynamicPluginMeta *meta, int fatal)
  188 {
  189     dlsym_func symbolPtr = NULL;
  190 
  191     if (!handle)
  192         return symbolPtr;
  193 
  194 #ifndef WIN32
  195     symbolPtr = (dlsym_func)dlsym(handle, symbol);
  196 #else
  197     symbolPtr = (dlsym_func)GetProcAddress(handle, symbol);
  198 #endif
  199 
  200     if (!symbolPtr)
  201     {
  202         if (fatal)
  203         {
  204 #ifndef WIN32
  205             FatalError("Failed to find %s() function in %s: %s\n",
  206                 symbol, meta->libraryPath, dlerror());
  207 #else
  208             FatalError("Failed to find %s() function in %s: %d\n",
  209                 symbol, meta->libraryPath, GetLastError());
  210 #endif
  211         }
  212         else
  213         {
  214 #ifndef WIN32
  215             ErrorMessage("Failed to find %s() function in %s: %s\n",
  216                 symbol, meta->libraryPath, dlerror());
  217 #else
  218             ErrorMessage("Failed to find %s() function in %s: %d\n",
  219                 symbol, meta->libraryPath, GetLastError());
  220 #endif
  221         }
  222     }
  223 
  224     return symbolPtr;
  225 }
  226 
  227 void GetPluginVersion(PluginHandle handle, DynamicPluginMeta* meta)
  228 {
  229     LibVersionFunc libVersionFunc = NULL;
  230 
  231     libVersionFunc = (LibVersionFunc)getSymbol(handle, "LibVersion", meta, FATAL);
  232 
  233     if (libVersionFunc != NULL)
  234     {
  235         libVersionFunc(meta);
  236     }
  237 }
  238 
  239 PluginHandle openDynamicLibrary(const char * const library_name, int useGlobal)
  240 {
  241     PluginHandle handle;
  242 #ifndef WIN32
  243     handle = dlopen(library_name, RTLD_NOW | (useGlobal ? RTLD_GLOBAL : RTLD_LOCAL));
  244 #else
  245     handle = LoadLibrary(library_name);
  246 #endif
  247     if (handle == NULL)
  248     {
  249 #ifndef WIN32
  250         FatalError("Failed to load %s: %s\n", library_name, dlerror());
  251 #else
  252         FatalError("Failed to load %s: %d\n", library_name, GetLastError());
  253 #endif
  254     }
  255     return handle;
  256 }
  257 
  258 void LoadAllLibs(struct _SnortConfig *sc, const char * const path, LoadLibraryFunc loadFunc)
  259 {
  260 #ifndef WIN32
  261     char path_buf[PATH_MAX];
  262     struct dirent *dir_entry;
  263     DIR *directory;
  264     int  count = 0;
  265     LoadableModule *modules = NULL;
  266 
  267     directory = opendir(path);
  268     if (directory != NULL)
  269     {
  270         dir_entry = readdir(directory);
  271         while (dir_entry != NULL)
  272         {
  273             if (fnmatch(MODULE_EXT, dir_entry->d_name, FNM_PATHNAME | FNM_PERIOD) == 0)
  274             {
  275                 /* Get the string up until the first dot.  This will be
  276                  * considered the file prefix. */
  277                 char *dot = strchr(dir_entry->d_name, '.');
  278 
  279                 if (dot != NULL)
  280                 {
  281                     size_t len = (size_t)(dot - dir_entry->d_name);  // len >= 0
  282                     LoadableModule *tmp = modules;
  283                     LoadableModule *prev = NULL;
  284 
  285                     while (tmp != NULL)
  286                     {
  287                         /* Make sure the prefix lengths are the same */
  288                         if (strlen(tmp->prefix) == len)
  289                         {
  290                             /* And make sure they are the same string */
  291                             if (strncmp(tmp->prefix, dir_entry->d_name, len) == 0)
  292                             {
  293                                 /* Take the shorter, since the longer probably
  294                                  * has version information and the shorter ones
  295                                  * are generally links to the most recent
  296                                  * version, e.g.
  297                                  * libsf_engine.so.0.0.0
  298                                  * libsf_engine.so.0 -> libsf_engine.so.0.0.0
  299                                  * libsf_engine.so   -> libsf_engine.so.0.0.0
  300                                  * Mac seems to do
  301                                  * libsf_engine.0.so
  302                                  * libsf_engine.0.0.0.so -> libsf_engine.0.so
  303                                  * libsf_engine.so       -> libsf_engine.0.so
  304                                  * We don't want to load the same same thing
  305                                  * more than once. */
  306                                 if (strlen(dir_entry->d_name) < strlen(tmp->name))
  307                                 {
  308                                     /* There will be enough space since at
  309                                      * least the longer of the two will have
  310                                      * been allocated */
  311                                     strcpy(tmp->name, dir_entry->d_name);
  312                                 }
  313 
  314                                 break;
  315                             }
  316                         }
  317 
  318                         prev = tmp;
  319                         tmp = tmp->next;
  320                     }
  321 
  322                     if (tmp == NULL)
  323                     {
  324                         tmp = SnortAlloc(sizeof(LoadableModule));
  325 
  326                         /* include NULL byte */
  327                         tmp->prefix = SnortAlloc(len + 1);
  328                         /* will be NULL terminated because SnortAlloc uses calloc */
  329                         strncpy(tmp->prefix, dir_entry->d_name, len);
  330 
  331                         /* include NULL byte */
  332                         tmp->name = SnortAlloc(strlen(dir_entry->d_name) + 1);
  333                         /* will be NULL terminated because SnortAlloc uses calloc */
  334                         strncpy(tmp->name, dir_entry->d_name, strlen(dir_entry->d_name));
  335 
  336                         tmp->next = NULL;
  337 
  338                         if (modules == NULL)
  339                             modules = tmp;
  340                         else if (prev != NULL)
  341                             prev->next = tmp;
  342                     }
  343                 }
  344             }
  345 
  346             dir_entry = readdir(directory);
  347         }
  348 
  349         closedir(directory);
  350 
  351         while (modules != NULL)
  352         {
  353             LoadableModule *tmp = modules;
  354 
  355             SnortSnprintf(path_buf, PATH_MAX, "%s%s%s", path, "/", modules->name);
  356             loadFunc(sc, path_buf, 1);
  357             count++;
  358 
  359             modules = modules->next;
  360 
  361             /* These will all have been allocated together */
  362             free(tmp->prefix);
  363             free(tmp->name);
  364             free(tmp);
  365         }
  366 
  367         if ( count == 0 )
  368         {
  369             LogMessage("WARNING: No dynamic libraries found in directory %s.\n", path);
  370         }
  371     }
  372     else
  373     {
  374         LogMessage("WARNING: Directory %s does not exist.\n", path);
  375     }
  376 #else
  377     /* Find all shared library files in path */
  378     char path_buf[PATH_MAX];
  379     char dyn_lib_name[PATH_MAX];
  380     char drive[_MAX_DRIVE];
  381     char dir[_MAX_DIR];
  382     char fname[_MAX_FNAME];
  383     char ext[_MAX_EXT];
  384     HANDLE fSearch;
  385     WIN32_FIND_DATA FindFileData;
  386     int pathLen = 0;
  387     const char *directory;
  388     int useDrive = 0;
  389 
  390     if (SnortStrncpy(path_buf, path, PATH_MAX) != SNORT_STRNCPY_SUCCESS)
  391         FatalError("Path is too long: %s\n", path);
  392 
  393     pathLen = SnortStrnlen(path_buf, PATH_MAX);
  394     if ((path_buf[pathLen - 1] == '\\') ||
  395         (path_buf[pathLen - 1] == '/'))
  396     {
  397         /* A directory was specified with trailing dir character */
  398         _splitpath(path_buf, drive, dir, fname, ext);
  399         _makepath(path_buf, drive, dir, "*", MODULE_EXT);
  400         directory = &dir[0];
  401         useDrive = 1;
  402     }
  403     else /* A directory was specified */
  404     {
  405         _splitpath(path_buf, drive, dir, fname, ext);
  406         if (strcmp(ext, ""))
  407         {
  408             FatalError("Improperly formatted directory name: %s\n", path);
  409         }
  410         _makepath(path_buf, "", path_buf, "*", MODULE_EXT);
  411         directory = path;
  412     }
  413 
  414     fSearch = FindFirstFile(path_buf, &FindFileData);
  415     while (fSearch != NULL && fSearch != (HANDLE)-1)
  416     {
  417         if (useDrive)
  418             _makepath(dyn_lib_name, drive, directory, FindFileData.cFileName, NULL);
  419         else
  420             _makepath(dyn_lib_name, NULL, directory, FindFileData.cFileName, NULL);
  421 
  422         loadFunc(dyn_lib_name, 1);
  423 
  424         if (!FindNextFile(fSearch, &FindFileData))
  425         {
  426             break;
  427         }
  428     }
  429     FindClose(fSearch);
  430 #endif
  431 }
  432 
  433 void AddEnginePlugin(PluginHandle handle,
  434                      InitEngineLibFunc initFunc,
  435                      CompatibilityFunc compatFunc,
  436                      DynamicPluginMeta *meta)
  437 {
  438     DynamicEnginePlugin *newPlugin;
  439     newPlugin = (DynamicEnginePlugin *)SnortAlloc(sizeof(DynamicEnginePlugin));
  440     newPlugin->handle = handle;
  441 
  442     if (!loadedEngines)
  443     {
  444         loadedEngines = newPlugin;
  445     }
  446     else
  447     {
  448         newPlugin->next = loadedEngines;
  449         loadedEngines->prev = newPlugin;
  450         loadedEngines = newPlugin;
  451     }
  452 
  453     memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
  454     newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
  455     newPlugin->initFunc = initFunc;
  456     newPlugin->versCheck = compatFunc;
  457 }
  458 
  459 void RemoveEnginePlugin(DynamicEnginePlugin *plugin)
  460 {
  461     if (!plugin)
  462         return;
  463 
  464     if (plugin == loadedEngines)
  465     {
  466         loadedEngines = loadedEngines->next;
  467         loadedEngines->prev = NULL;
  468     }
  469     else
  470     {
  471         if (plugin->prev)
  472             plugin->prev->next = plugin->next;
  473         if (plugin->next)
  474             plugin->next->prev = plugin->prev;
  475     }
  476     CloseDynamicLibrary(plugin->handle);
  477     if (plugin->metaData.libraryPath != NULL)
  478         free(plugin->metaData.libraryPath);
  479     free(plugin);
  480 }
  481 
  482 int ValidateDynamicEngines(SnortConfig *sc)
  483 {
  484     int testNum = 0;
  485     DynamicEnginePlugin *curPlugin = loadedEngines;
  486     CompatibilityFunc versFunc = NULL;
  487 
  488     while( curPlugin != NULL)
  489     {
  490         versFunc = (CompatibilityFunc)curPlugin->versCheck;
  491         /* if compatibility checking func is absent, skip validating */
  492         if( versFunc != NULL)
  493         {
  494             DynamicDetectionPlugin *lib = sc->loadedDetectionPlugins;
  495             while( lib != NULL)
  496             {
  497                 if (lib->metaData.type == TYPE_DETECTION)
  498                 {
  499                     RequiredEngineLibFunc engineFunc;
  500                     DynamicPluginMeta reqEngineMeta;
  501 
  502                     engineFunc = (RequiredEngineLibFunc) getSymbol(lib->handle, "EngineVersion", &(lib->metaData), 1);
  503                     if( engineFunc != NULL)
  504                     {
  505                         engineFunc(&reqEngineMeta);
  506                     }
  507                     testNum = versFunc(&curPlugin->metaData, &reqEngineMeta);
  508                     if( testNum )
  509                     {
  510                         FatalError("The dynamic detection library \"%s\" version "
  511                                 "%d.%d compiled with dynamic engine library "
  512                                 "version %d.%d isn't compatible with the current "
  513                                 "dynamic engine library \"%s\" version %d.%d.\n",
  514                                 lib->metaData.libraryPath, lib->metaData.major,
  515                                 lib->metaData.minor, reqEngineMeta.major,
  516                                 reqEngineMeta.minor, curPlugin->metaData.libraryPath,
  517                                 curPlugin->metaData.major, curPlugin->metaData.minor);
  518                     }
  519 
  520                 }
  521                 lib = lib->next;
  522             }
  523         }
  524         if( testNum ) break;
  525         curPlugin = curPlugin->next;
  526     }
  527 
  528     return(testNum);
  529 }
  530 
  531 int LoadDynamicEngineLib(SnortConfig *sc, const char * const library_name, int indent)
  532 {
  533     /* Presume here, that library name is full path */
  534     InitEngineLibFunc engineInit;
  535     CompatibilityFunc compatFunc;
  536     DynamicPluginMeta metaData;
  537     PluginHandle handle;
  538 
  539 #if 0
  540     LogMessage("%sDynamic engine will not be loaded since dynamic detection "
  541                  "libraries are not yet supported with IPv6.\n",
  542                 indent?"  ":"");
  543     return 0;
  544 #endif
  545 
  546     LogMessage("%sLoading dynamic engine %s... ",
  547                indent ? "  " : "", library_name);
  548 
  549     handle = openDynamicLibrary(library_name, 1);
  550     metaData.libraryPath = (char *) library_name;
  551 
  552     GetPluginVersion(handle, &metaData);
  553 
  554     /* Just to ensure that the function exists */
  555     engineInit = (InitEngineLibFunc)getSymbol(handle, "InitializeEngine", &metaData, FATAL);
  556     compatFunc = (CompatibilityFunc)getSymbol(handle, "CheckCompatibility", &metaData, NONFATAL);
  557 
  558     if (metaData.type != TYPE_ENGINE)
  559     {
  560         CloseDynamicLibrary(handle);
  561         LogMessage("failed, not an Engine\n");
  562         return 0;
  563     }
  564 
  565     AddEnginePlugin(handle, engineInit, compatFunc, &metaData);
  566 
  567     LogMessage("done\n");
  568     return 0;
  569 }
  570 
  571 void LoadAllDynamicEngineLibs(SnortConfig *sc, const char * const path)
  572 {
  573     LogMessage("Loading all dynamic engine libs from %s...\n", path);
  574     LoadAllLibs(sc, path, LoadDynamicEngineLib);
  575     LogMessage("  Finished Loading all dynamic engine libs from %s\n", path);
  576 }
  577 
  578 void CloseDynamicEngineLibs(void)
  579 {
  580     DynamicEnginePlugin *tmpplugin, *plugin = loadedEngines;
  581     while (plugin)
  582     {
  583         tmpplugin = plugin->next;
  584         //if (!(plugin->metaData.type & TYPE_DETECTION))
  585         //{
  586             CloseDynamicLibrary(plugin->handle);
  587             free(plugin->metaData.libraryPath);
  588             free(plugin);
  589         //}
  590         //else
  591         //{
  592         //  HUH?
  593         //    /* NOP, handle will be closed when we close the DetectionLib */
  594         //    ;
  595         //}
  596         plugin = tmpplugin;
  597     }
  598     loadedEngines = NULL;
  599 #ifdef SNORT_RELOAD
  600     ada_delete(ada);
  601     ada = NULL;
  602 #endif
  603 }
  604 
  605 void RemovePreprocessorPlugin(DynamicPreprocessorPlugin *plugin)
  606 {
  607     if (!plugin)
  608         return;
  609 
  610     if (plugin == loadedPreprocessorPlugins)
  611     {
  612         loadedPreprocessorPlugins = loadedPreprocessorPlugins->next;
  613         loadedPreprocessorPlugins->prev = NULL;
  614     }
  615     else
  616     {
  617         if (plugin->prev)
  618             plugin->prev->next = plugin->next;
  619         if (plugin->next)
  620             plugin->next->prev = plugin->prev;
  621     }
  622     CloseDynamicLibrary(plugin->handle);
  623     if (plugin->metaData.libraryPath != NULL)
  624         free(plugin->metaData.libraryPath);
  625     free(plugin);
  626 }
  627 
  628 void AddPreprocessorPlugin(PluginHandle handle,
  629                         InitPreprocessorLibFunc initFunc,
  630                         DynamicPluginMeta *meta)
  631 {
  632     DynamicPreprocessorPlugin *newPlugin = NULL;
  633     newPlugin = (DynamicPreprocessorPlugin *)SnortAlloc(sizeof(DynamicPreprocessorPlugin));
  634     newPlugin->handle = handle;
  635 
  636     if (!loadedPreprocessorPlugins)
  637     {
  638         loadedPreprocessorPlugins = newPlugin;
  639     }
  640     else
  641     {
  642         newPlugin->next = loadedPreprocessorPlugins;
  643         loadedPreprocessorPlugins->prev = newPlugin;
  644         loadedPreprocessorPlugins = newPlugin;
  645     }
  646 
  647     memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
  648     newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
  649     newPlugin->initFunc = initFunc;
  650 }
  651 
  652 void AddDetectionPlugin(SnortConfig *sc, PluginHandle handle,
  653                         InitDetectionLibFunc initFunc,
  654                         DynamicPluginMeta *meta)
  655 {
  656     DynamicDetectionPlugin *newPlugin = NULL;
  657     newPlugin = (DynamicDetectionPlugin *)SnortAlloc(sizeof(DynamicDetectionPlugin));
  658     newPlugin->handle = handle;
  659 
  660     if (!sc->loadedDetectionPlugins)
  661     {
  662         sc->loadedDetectionPlugins = newPlugin;
  663     }
  664     else
  665     {
  666         newPlugin->next = sc->loadedDetectionPlugins;
  667         sc->loadedDetectionPlugins->prev = newPlugin;
  668         sc->loadedDetectionPlugins = newPlugin;
  669     }
  670 
  671     memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
  672     newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
  673     newPlugin->initFunc = initFunc;
  674 }
  675 
  676 void RemoveDetectionPlugin(SnortConfig *sc, DynamicDetectionPlugin *plugin)
  677 {
  678     if (!plugin)
  679         return;
  680 
  681     if (plugin == sc->loadedDetectionPlugins)
  682     {
  683         sc->loadedDetectionPlugins = sc->loadedDetectionPlugins->next;
  684         sc->loadedDetectionPlugins->prev = NULL;
  685     }
  686     else
  687     {
  688         if (plugin->prev)
  689             plugin->prev->next = plugin->next;
  690         if (plugin->next)
  691             plugin->next->prev = plugin->prev;
  692     }
  693     LogMessage("Unloading dynamic detection library %s version %d.%d.%d\n",
  694             plugin->metaData.uniqueName,
  695             plugin->metaData.major,
  696             plugin->metaData.minor,
  697             plugin->metaData.build);
  698     CloseDynamicLibrary(plugin->handle);
  699     if (plugin->metaData.libraryPath != NULL)
  700         free(plugin->metaData.libraryPath);
  701     free(plugin);
  702 }
  703 
  704 int LoadDynamicDetectionLib(SnortConfig *sc, const char * const library_name, int indent)
  705 {
  706     DynamicPluginMeta metaData;
  707     /* Presume here, that library name is full path */
  708     InitDetectionLibFunc detectionInit;
  709     PluginHandle handle;
  710 
  711 #if 0
  712     LogMessage("%sDynamic detection library \"%s\" will not be loaded. Not "
  713                  "supported with IPv6.\n", indent ? "  " : "", library_name);
  714     return 0;
  715 #endif
  716 
  717     LogMessage("%sLoading dynamic detection library %s... ",
  718                indent ? "  " : "", library_name);
  719 
  720     handle = openDynamicLibrary(library_name, 0);
  721     metaData.libraryPath = (char *) library_name;
  722 
  723     GetPluginVersion(handle, &metaData);
  724 
  725     /* Just to ensure that the function exists */
  726     detectionInit = (InitDetectionLibFunc)getSymbol(handle, "InitializeDetection", &metaData, FATAL);
  727 
  728     if (!(metaData.type & TYPE_DETECTION))
  729     {
  730         CloseDynamicLibrary(handle);
  731         LogMessage("failed, not a detection library\n");
  732         return 0;
  733     }
  734 
  735     if (metaData.type & TYPE_ENGINE)
  736     {
  737         /* Do the engine initialization as well */
  738         InitEngineLibFunc engineInit = (InitEngineLibFunc)getSymbol(handle, "InitializeEngine", &metaData, FATAL);
  739         CompatibilityFunc compatFunc = (CompatibilityFunc)getSymbol(handle, "CheckCompatibility", &metaData, NONFATAL);
  740 
  741         AddEnginePlugin(handle, engineInit, compatFunc, &metaData);
  742     }
  743 
  744     AddDetectionPlugin(sc, handle, detectionInit, &metaData);
  745 
  746     LogMessage("done\n");
  747     return 0;
  748 }
  749 
  750 void CloseDynamicDetectionLibs(SnortConfig *sc)
  751 {
  752     DynamicDetectionPlugin *tmpplugin, *plugin = sc->loadedDetectionPlugins;
  753     while (plugin)
  754     {
  755         tmpplugin = plugin->next;
  756 #ifndef SNORT_RELOAD
  757         CloseDynamicLibrary(plugin->handle);
  758 #else
  759         /*
  760          * Even if DISABLE_DLCLOSE_FOR_VALGRIND_TESTING is set
  761          * we have to do dlclose() for Dynamic detection libs
  762          * during reloading.
  763          */
  764 #ifndef WIN32
  765         dlclose(plugin->handle);
  766 #else
  767         FreeLibrary(plugin->handle);
  768 #endif
  769 #endif
  770         free(plugin->metaData.libraryPath);
  771         free(plugin);
  772         plugin = tmpplugin;
  773     }
  774     sc->loadedDetectionPlugins = NULL;
  775 }
  776 
  777 void LoadAllDynamicDetectionLibs(SnortConfig *sc, const char * const path)
  778 {
  779     LogMessage("Loading all dynamic detection libs from %s...\n", path);
  780     LoadAllLibs(sc, path, LoadDynamicDetectionLib);
  781     LogMessage("  Finished Loading all dynamic detection libs from %s\n", path);
  782 }
  783 
  784 void RemoveDuplicateEngines(void)
  785 {
  786     int removed = 0;
  787     DynamicEnginePlugin *engine1;
  788     DynamicEnginePlugin *engine2;
  789     DynamicPluginMeta *meta1;
  790     DynamicPluginMeta *meta2;
  791 
  792     /* First the Detection Engines */
  793     do
  794     {
  795         removed = 0;
  796         engine1 = loadedEngines;
  797         while (engine1 != NULL)
  798         {
  799             engine2 = loadedEngines;
  800             while (engine2 != NULL)
  801             {
  802                 /* Obviously, the same ones will be the same */
  803                 if (engine1 != engine2)
  804                 {
  805                     meta1 = &engine1->metaData;
  806                     meta2 = &engine2->metaData;
  807                     if (!strcmp(meta1->uniqueName, meta2->uniqueName))
  808                     {
  809                         /* Uh, same uniqueName. */
  810                         if ((meta1->major > meta2->major) ||
  811                             ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
  812                             ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
  813                         {
  814                             /* Lib1 is newer */
  815                             RemoveEnginePlugin(engine2);
  816                             removed = 1;
  817                         }
  818                         else if ((meta2->major > meta1->major) ||
  819                             ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
  820                             ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
  821                         {
  822                             /* Lib2 is newer */
  823                             RemoveEnginePlugin(engine1);
  824                             removed = 1;
  825                         }
  826                         else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
  827                         {
  828                             /* Duplicate */
  829                             RemoveEnginePlugin(engine2);
  830                             removed = 1;
  831                         }
  832                     }
  833                 }
  834                 /* If we removed anything, start back at the beginning */
  835                 if (removed)
  836                     break;
  837                 engine2 = engine2->next;
  838             }
  839             /* If we removed anything, start back at the beginning */
  840             if (removed)
  841                 break;
  842             engine1 = engine1->next;
  843         }
  844     } while (removed);
  845 }
  846 
  847 void RemoveDuplicateDetectionPlugins(SnortConfig *sc)
  848 {
  849     int removed = 0;
  850     DynamicDetectionPlugin *lib1 = NULL;
  851     DynamicDetectionPlugin *lib2 = NULL;
  852     DynamicPluginMeta *meta1;
  853     DynamicPluginMeta *meta2;
  854 
  855     /* Detection Plugins */
  856     do
  857     {
  858         removed = 0;
  859         lib1 = sc->loadedDetectionPlugins;
  860         while (lib1 != NULL)
  861         {
  862             lib2 = sc->loadedDetectionPlugins;
  863             while (lib2 != NULL)
  864             {
  865                 /* Obviously, the same ones will be the same */
  866                 if (lib1 != lib2)
  867                 {
  868                     meta1 = &lib1->metaData;
  869                     meta2 = &lib2->metaData;
  870                     if (!strcmp(meta1->uniqueName, meta2->uniqueName))
  871                     {
  872                         /* Uh, same uniqueName. */
  873                         if ((meta1->major > meta2->major) ||
  874                             ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
  875                             ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
  876                         {
  877                             /* Lib1 is newer */
  878                             RemoveDetectionPlugin(sc, lib2);
  879                             removed = 1;
  880                         }
  881                         else if ((meta2->major > meta1->major) ||
  882                             ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
  883                             ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
  884                         {
  885                             /* Lib2 is newer */
  886                             RemoveDetectionPlugin(sc, lib1);
  887                             removed = 1;
  888                         }
  889                         else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
  890                         {
  891                             /* Duplicate */
  892                             RemoveDetectionPlugin(sc, lib2);
  893                             removed = 1;
  894                         }
  895                     }
  896                 }
  897                 /* If we removed anything, start back at the beginning */
  898                 if (removed)
  899                     break;
  900                 lib2 = lib2->next;
  901             }
  902             /* If we removed anything, start back at the beginning */
  903             if (removed)
  904                 break;
  905             lib1 = lib1->next;
  906         }
  907     } while (removed);
  908 }
  909 
  910 void RemoveDuplicatePreprocessorPlugins(void)
  911 {
  912     int removed = 0;
  913     DynamicPreprocessorPlugin *pp1 = NULL;
  914     DynamicPreprocessorPlugin *pp2 = NULL;
  915     DynamicPluginMeta *meta1;
  916     DynamicPluginMeta *meta2;
  917 
  918     /* The Preprocessor Plugins */
  919     do
  920     {
  921         removed = 0;
  922         pp1 = loadedPreprocessorPlugins;
  923         while (pp1 != NULL)
  924         {
  925             pp2 = loadedPreprocessorPlugins;
  926             while (pp2 != NULL)
  927             {
  928                 /* Obviously, the same ones will be the same */
  929                 if (pp1 != pp2)
  930                 {
  931                     meta1 = &pp1->metaData;
  932                     meta2 = &pp2->metaData;
  933                     if (!strcmp(meta1->uniqueName, meta2->uniqueName))
  934                     {
  935                         /* Uh, same uniqueName. */
  936                         if ((meta1->major > meta2->major) ||
  937                             ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
  938                             ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
  939                         {
  940                             /* Lib1 is newer */
  941                             RemovePreprocessorPlugin(pp2);
  942                             removed = 1;
  943                         }
  944                         else if ((meta2->major > meta1->major) ||
  945                             ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
  946                             ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
  947                         {
  948                             /* Lib2 is newer */
  949                             RemovePreprocessorPlugin(pp1);
  950                             removed = 1;
  951                         }
  952                         else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
  953                         {
  954                             /* Duplicate */
  955                             RemovePreprocessorPlugin(pp2);
  956                             removed = 1;
  957                         }
  958                     }
  959                 }
  960                 /* If we removed anything, start back at the beginning */
  961                 if (removed)
  962                     break;
  963                 pp2 = pp2->next;
  964             }
  965             /* If we removed anything, start back at the beginning */
  966             if (removed)
  967                 break;
  968             pp1 = pp1->next;
  969         }
  970     } while (removed);
  971 }
  972 
  973 void VerifyDetectionPluginRequirements(SnortConfig *sc)
  974 {
  975     DynamicDetectionPlugin *lib1 = NULL;
  976 
  977     /* Remove all the duplicates */
  978     RemoveDuplicateDetectionPlugins(sc);
  979 
  980     /* Cycle through all of them, and ensure that the required
  981      * detection engine is loaded.
  982      */
  983     lib1 = sc->loadedDetectionPlugins;
  984     while (lib1 != NULL)
  985     {
  986         /* Do this check if this library is a DETECTION plugin only.
  987          * If it also has an internal engine, we're fine.
  988          */
  989         if (lib1->metaData.type == TYPE_DETECTION)
  990         {
  991             RequiredEngineLibFunc engineFunc;
  992             DynamicPluginMeta reqEngineMeta;
  993             DynamicEnginePlugin *plugin = loadedEngines;
  994             int detectionLibOkay = 0;
  995 
  996             engineFunc = (RequiredEngineLibFunc) getSymbol(lib1->handle, "EngineVersion", &(lib1->metaData), FATAL);
  997 
  998             engineFunc(&reqEngineMeta);
  999             while (plugin != NULL)
 1000             {
 1001                 /* Exact match.  Yes! */
 1002                 if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) &&
 1003                     plugin->metaData.major == reqEngineMeta.major &&
 1004                     plugin->metaData.minor == reqEngineMeta.minor)
 1005                 {
 1006                     detectionLibOkay = 1;
 1007                     break;
 1008                 }
 1009 
 1010                 /* Major match, minor must be >= */
 1011                 if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) &&
 1012                     plugin->metaData.major == reqEngineMeta.major &&
 1013                     plugin->metaData.minor >= reqEngineMeta.minor)
 1014                 {
 1015                     detectionLibOkay = 1;
 1016                     break;
 1017                 }
 1018 
 1019                 /* Major must be >= -- this assumes newer engine is
 1020                  * bass-ackwards compatabile */
 1021                 if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) &&
 1022                     plugin->metaData.major > reqEngineMeta.major)
 1023                 {
 1024                     detectionLibOkay = 1;
 1025                     break;
 1026                 }
 1027 
 1028                 plugin = plugin->next;
 1029             }
 1030             if (!detectionLibOkay)
 1031             {
 1032                 FatalError("Loaded dynamic detection plugin %s (version %d:%d:%d) "
 1033                            "could not find required engine plugin %s(version %d:%d)\n",
 1034                             lib1->metaData.uniqueName, lib1->metaData.major, lib1->metaData.minor, lib1->metaData.build,
 1035                             reqEngineMeta.uniqueName, reqEngineMeta.major, reqEngineMeta.minor);
 1036             }
 1037         }
 1038 
 1039         lib1 = lib1->next;
 1040     }
 1041 }
 1042 
 1043 int InitDynamicEnginePlugins(DynamicEngineData *info)
 1044 {
 1045     DynamicEnginePlugin *plugin;
 1046     RemoveDuplicateEngines();
 1047 
 1048     plugin = loadedEngines;
 1049     while (plugin)
 1050     {
 1051         if (plugin->initFunc(info))
 1052         {
 1053             FatalError("Failed to initialize dynamic engine: %s version %d.%d.%d\n",
 1054                        plugin->metaData.uniqueName, plugin->metaData.major,
 1055                        plugin->metaData.minor, plugin->metaData.build);
 1056             //return -1;
 1057         }
 1058 
 1059         plugin = plugin->next;
 1060     }
 1061     return 0;
 1062 }
 1063 
 1064 typedef struct _DynamicRuleSessionData
 1065 {
 1066     uint32_t sid;
 1067     uint32_t revision;
 1068     void *data;
 1069     void *compression_data;
 1070     struct _DynamicRuleSessionData *next;
 1071 
 1072 } DynamicRuleSessionData;
 1073 
 1074 static uint32_t so_rule_memory = 0;
 1075 
 1076 static size_t SoRuleMemInUse()
 1077 {
 1078     return (size_t) so_rule_memory;
 1079 }
 1080 /*Only only message will be logged within 60 seconds*/
 1081 static ThrottleInfo error_throttleInfo = {0,60,0};
 1082 
 1083 static void * DynamicRuleDataAlloc(size_t size)
 1084 {
 1085     size_t alloc_size = size + sizeof(size_t);
 1086     size_t *ret;
 1087 
 1088     if ((ScSoRuleMemcap() > 0)
 1089             && (so_rule_memory + alloc_size) > ScSoRuleMemcap())
 1090     {
 1091         ErrorMessageThrottled(&error_throttleInfo,"SO rule memcap exceeded: Wanted to allocate "
 1092                 "%u bytes (and %d overhead) with memcap: %u and "
 1093                 "current memory: %u\n", (uint32_t)size,
 1094                 (int)sizeof(size_t), ScSoRuleMemcap(), so_rule_memory);
 1095         return NULL;
 1096     }
 1097 
 1098     ret = (size_t *)SnortAlloc(alloc_size);
 1099     ret[0] = alloc_size;
 1100     so_rule_memory += alloc_size;
 1101     return (void *)&ret[1];
 1102 }
 1103 
 1104 static void DynamicRuleDataFree(void *data)
 1105 {
 1106     if (data != NULL)
 1107     {
 1108         size_t *alloc_data = (size_t *)data - 1;
 1109         size_t size = alloc_data[0];
 1110 
 1111         /* Just in case of an an imbalance of DynamicRuleDataAlloc
 1112          * and this function are used */
 1113         if (size >= so_rule_memory)
 1114             so_rule_memory = 0;
 1115         else
 1116             so_rule_memory -= size;
 1117         free(alloc_data);
 1118     }
 1119 }
 1120 
 1121 static void DynamicRuleDataFreeSession(void *data)
 1122 {
 1123     DynamicRuleSessionData *drsd = (DynamicRuleSessionData *)data;
 1124 
 1125     while (drsd != NULL)
 1126     {
 1127         DynamicRuleSessionData *tmp = drsd;
 1128         drsd = drsd->next;
 1129 
 1130         DynamicRuleDataFree(tmp->data);
 1131 
 1132 #ifdef SNORT_RELOAD
 1133         ada_appdata_freed(ada, tmp);
 1134 #endif
 1135         if (tmp->compression_data)
 1136         {
 1137             DynamicDecompressDestroy(tmp->compression_data);
 1138         }
 1139         DynamicRuleDataFree(tmp);
 1140     }
 1141 }
 1142 
 1143 int DynamicSetRuleData(void *p, const RuleInformation *info, void *data, void *compression_data)
 1144 {
 1145     Packet *pkt = (Packet *)p;
 1146     if (stream_api && pkt && pkt->ssnptr)
 1147     {
 1148         DynamicRuleSessionData *head =
 1149             (DynamicRuleSessionData *)session_api->get_application_data(pkt->ssnptr, PP_SHARED_RULES);
 1150         DynamicRuleSessionData *tmp = head;
 1151         DynamicRuleSessionData *tail = NULL;
 1152 
 1153         /* Can't reset head without setting application data again which
 1154          * will free what's there already, so have to iterate to end of list
 1155          * Also need to iterate for duplicates */
 1156         while (tmp != NULL)
 1157         {
 1158             if (tmp->sid == info->sigID)
 1159             {
 1160                 /* Not the same data */
 1161                 if (tmp->data != data)
 1162                 {
 1163                     /* Cleanup the old and replace with the new */
 1164                     DynamicRuleDataFree(tmp->data);
 1165                     tmp->data = data;
 1166                 }
 1167                 /* Not the same data */
 1168                 if (tmp->compression_data && tmp->compression_data != compression_data)
 1169                 {
 1170                     /* Cleanup the old */
 1171                     DynamicDecompressDestroy(tmp->compression_data);
 1172                 }
 1173                 tmp->compression_data = compression_data;
 1174 
 1175                 tmp->revision = info->revision;
 1176                 return 0;
 1177             }
 1178 
 1179             tail = tmp;
 1180             tmp = tmp->next;
 1181         }
 1182 
 1183         tmp = (DynamicRuleSessionData *)DynamicRuleDataAlloc(sizeof(DynamicRuleSessionData));
 1184         if (tmp == NULL)
 1185             return -1;
 1186 
 1187         tmp->data = data;
 1188         tmp->sid = info->sigID;
 1189         tmp->revision = info->revision;
 1190 
 1191         if (head == NULL)
 1192         {
 1193             if (session_api->set_application_data(pkt->ssnptr, PP_SHARED_RULES,
 1194                         (void *)tmp, DynamicRuleDataFreeSession) != 0)
 1195             {
 1196                 DynamicRuleDataFree(tmp);
 1197                 return -1;
 1198             }
 1199 #ifdef SNORT_RELOAD
 1200             ada_add( ada, (void *)tmp, pkt->ssnptr );
 1201 #endif
 1202         }
 1203         else
 1204         {
 1205             tail->next = tmp;
 1206         }
 1207 
 1208         return 0;
 1209     }
 1210 
 1211     return -1;
 1212 }
 1213 
 1214 void DynamicGetRuleData(void *p, const RuleInformation *info, void **p_data, void **p_compression_data)
 1215 {
 1216     Packet *pkt = (Packet *)p;
 1217     void *compression_data;
 1218 
 1219     if (!p_compression_data)
 1220         p_compression_data = &compression_data;
 1221     *p_data = NULL;
 1222     *p_compression_data = NULL;
 1223     if (stream_api && pkt && pkt->ssnptr)
 1224     {
 1225         DynamicRuleSessionData *head =
 1226             (DynamicRuleSessionData *)session_api->get_application_data(pkt->ssnptr, PP_SHARED_RULES);
 1227 
 1228         while (head != NULL)
 1229         {
 1230             if (head->sid == info->sigID)
 1231             {
 1232                 if (head->revision != info->revision)
 1233                 {
 1234                     DynamicRuleDataFree(head->data);
 1235                     head->data = NULL;
 1236                     if (head->compression_data)
 1237                     {
 1238                         DynamicDecompressDestroy(head->compression_data);
 1239                         head->compression_data = NULL;
 1240                     }
 1241                 }
 1242                 *p_data = head->data;
 1243                 *p_compression_data = head->compression_data;
 1244                 return;
 1245             }
 1246 
 1247             head = head->next;
 1248         }
 1249     }
 1250 }
 1251 
 1252 void *pcreCompile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr)
 1253 {
 1254     options &= ~SNORT_PCRE_OVERRIDE_MATCH_LIMIT;
 1255     return (void *)pcre_compile(pattern, options, errptr, erroffset, tableptr);
 1256 }
 1257 
 1258 void *pcreStudy(struct _SnortConfig *sc, const void *code, int options, const char **errptr)
 1259 {
 1260     pcre_extra *extra_extra;
 1261     int snort_options = options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT;
 1262 
 1263     extra_extra = pcre_study((const pcre*)code, 0, errptr);
 1264 
 1265     if (extra_extra)
 1266     {
 1267         if ((ScPcreMatchLimitNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT))
 1268         {
 1269             if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT)
 1270             {
 1271                 extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
 1272             }
 1273             else
 1274             {
 1275                 extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
 1276                 extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
 1277             }
 1278         }
 1279 
 1280 #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
 1281         if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT))
 1282         {
 1283             if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION)
 1284             {
 1285                 extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
 1286             }
 1287             else
 1288             {
 1289                 extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
 1290                 extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
 1291             }
 1292         }
 1293 #endif
 1294     }
 1295     else
 1296     {
 1297         if (!(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT) &&
 1298             ((ScPcreMatchLimitNewConf(sc) != -1) || (ScPcreMatchLimitRecursionNewConf(sc) != -1)))
 1299         {
 1300             extra_extra = (pcre_extra *)SnortAlloc(sizeof(pcre_extra));
 1301             if (ScPcreMatchLimitNewConf(sc) != -1)
 1302             {
 1303                 extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
 1304                 extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
 1305             }
 1306 
 1307 #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
 1308             if (ScPcreMatchLimitRecursionNewConf(sc) != -1)
 1309             {
 1310                 extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
 1311                 extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
 1312             }
 1313 #endif
 1314         }
 1315     }
 1316 
 1317     return extra_extra;
 1318 }
 1319 
 1320 /* pcreOvectorInfo
 1321  *
 1322  * Get the Ovector configuration for PCRE from the snort.conf
 1323  */
 1324 void pcreOvectorInfo(int **ovector, int *ovector_size)
 1325 {
 1326     *ovector = snort_conf->pcre_ovector;
 1327     *ovector_size = snort_conf->pcre_ovector_size;
 1328 }
 1329 
 1330 int pcreExec(const void *code, const void *extra, const char *subj,
 1331              int len, int start, int options, int *ovec, int ovecsize)
 1332 {
 1333     return pcre_exec((const pcre *)code, (const pcre_extra *)extra, subj, len, start, options, ovec, ovecsize);
 1334 }
 1335 
 1336 static int setFlowId(const void* p, uint32_t id)
 1337 {
 1338     return DAQ_ModifyFlowOpaque(p, id);
 1339 }
 1340 
 1341 #ifdef DAQ_MODFLOW_TYPE_PRESERVE_FLOW
 1342 static int setPreserveFlow(const void* p)
 1343 {
 1344     DAQ_ModFlow_t mod;
 1345     int value = 1;
 1346 
 1347     if ( Active_GetTunnelBypass() )
 1348         return -1;
 1349 
 1350     mod.type = DAQ_MODFLOW_TYPE_PRESERVE_FLOW;
 1351     mod.length = sizeof(value);
 1352     mod.value = (void*)&value;
 1353     DAQ_ModifyFlow(p, &mod);
 1354 
 1355     return 0;
 1356 }
 1357 #endif
 1358 
 1359 static const uint8_t* getHttpBuffer (HTTP_BUFFER hb_type, unsigned* len)
 1360 {
 1361     const HttpBuffer* hb = GetHttpBuffer(hb_type);
 1362     if ( !hb )
 1363         return NULL;
 1364 
 1365     *len = hb->length;
 1366     return hb->buf;
 1367 }
 1368 
 1369 int InitDynamicEngines(char *dynamic_rules_path)
 1370 {
 1371     DynamicEngineData engineData;
 1372 
 1373     engineData.version = ENGINE_DATA_VERSION;
 1374     engineData.altBuffer = (SFDataBuffer *)&DecodeBuffer;
 1375     engineData.altDetect = (SFDataPointer *)&DetectBuffer;
 1376     engineData.fileDataBuf = (SFDataPointer *)&file_data_ptr;
 1377 
 1378     /* This is defined in dynamic-plugins/sp_dynamic.h */
 1379     engineData.ruleRegister = &RegisterDynamicRule;
 1380     engineData.flowbitRegister = &DynamicFlowbitRegister;
 1381     engineData.flowbitCheck = &DynamicFlowbitCheck;
 1382     engineData.asn1Detect = &DynamicAsn1Detect;
 1383 
 1384     if (dynamic_rules_path != NULL)
 1385         engineData.dataDumpDirectory = SnortStrdup(dynamic_rules_path);
 1386     else
 1387         engineData.dataDumpDirectory = NULL;
 1388 
 1389     engineData.logMsg = &LogMessage;
 1390     engineData.errMsg = &ErrorMessage;
 1391     engineData.fatalMsg = &FatalError;
 1392 
 1393     engineData.preprocRuleOptInit = &DynamicPreprocRuleOptInit;
 1394 
 1395     engineData.setRuleData = &DynamicSetRuleData;
 1396     engineData.getRuleData = &DynamicGetRuleData;
 1397 
 1398     engineData.sfUnfold = &DynamicsfUnfold;
 1399     engineData.sfbase64decode = &Dynamicsfbase64decode;
 1400     engineData.GetAltDetect = &DynamicGetAltDetect;
 1401     engineData.SetAltDetect = &DynamicSetAltDetect;
 1402     engineData.Is_DetectFlag = &DynamicIsDetectFlag;
 1403     engineData.DetectFlag_Disable = &DynamicDetectFlagDisable;
 1404 
 1405     engineData.debugMsg = &DebugMessageFunc;
 1406 #ifdef SF_WCHAR
 1407     engineData.debugWideMsg = &DebugWideMessageFunc;
 1408 #endif
 1409 #ifdef DEBUG_MSGS
 1410     engineData.debugMsgFile = &DebugMessageFile;
 1411     engineData.debugMsgLine = &DebugMessageLine;
 1412 #else
 1413     engineData.debugMsgFile = &no_file;
 1414     engineData.debugMsgLine = &no_line;
 1415 #endif
 1416 
 1417     engineData.pcreStudy = &pcreStudy;
 1418     engineData.pcreCompile = &pcreCompile;
 1419     engineData.pcreExec = &pcreExec;
 1420 
 1421     engineData.allocRuleData = &DynamicRuleDataAlloc;
 1422     engineData.freeRuleData = &DynamicRuleDataFree;
 1423 
 1424     engineData.flowbitUnregister = &DynamicFlowbitUnregister;
 1425 
 1426     engineData.pcreCapture = &PcreCapture;
 1427     engineData.pcreOvectorInfo = &pcreOvectorInfo;
 1428     engineData.getHttpBuffer = getHttpBuffer;
 1429 
 1430     engineData.decompressInit = &DynamicDecompressInit;
 1431     engineData.decompressDestroy = &DynamicDecompressDestroy;
 1432     engineData.decompress = &DynamicDecompress;
 1433 
 1434     return InitDynamicEnginePlugins(&engineData);
 1435 }
 1436 
 1437 int InitDynamicPreprocessorPlugins(DynamicPreprocessorData *info)
 1438 {
 1439     DynamicPreprocessorPlugin *plugin;
 1440     RemoveDuplicatePreprocessorPlugins();
 1441 
 1442     plugin = loadedPreprocessorPlugins;
 1443     while (plugin)
 1444     {
 1445         int i = plugin->initFunc(info);
 1446         if (i)
 1447         {
 1448             FatalError("Failed to initialize dynamic preprocessor: %s version %d.%d.%d (%d)\n",
 1449                        plugin->metaData.uniqueName, plugin->metaData.major,
 1450                        plugin->metaData.minor, plugin->metaData.build, i);
 1451             //return -1;
 1452         }
 1453 
 1454         plugin = plugin->next;
 1455     }
 1456 #ifdef SNORT_RELOAD
 1457     if (!ada) {
 1458         ada = ada_init(SoRuleMemInUse, PP_SHARED_RULES, (size_t) ScSoRuleMemcap());
 1459         if (!ada) {
 1460             FatalError("Failed to initialize so_rule session cache. \n");
 1461         }
 1462     }
 1463 #endif
 1464     return 0;
 1465 }
 1466 
 1467 /* Do this to avoid exposing Packet & PreprocessFuncNode from
 1468  * snort to non-GPL code */
 1469 typedef void (*SnortPacketProcessFunc)(Packet *, void *);
 1470 void *AddPreprocessor(struct _SnortConfig *sc, void (*pp_func)(void *, void *), uint16_t priority,
 1471                       uint32_t preproc_id, uint32_t proto_mask)
 1472 {
 1473     SnortPacketProcessFunc preprocessorFunc = (SnortPacketProcessFunc)pp_func;
 1474     return (void *)AddFuncToPreprocList(sc, preprocessorFunc, priority, preproc_id, proto_mask);
 1475 }
 1476 
 1477 void *AddPreprocessorAllPolicies(struct _SnortConfig *sc, void (*pp_func)(void *, void *),
 1478                                  uint16_t priority, uint32_t preproc_id, uint32_t proto_mask)
 1479 {
 1480     SnortPacketProcessFunc preprocessorFunc = (SnortPacketProcessFunc)pp_func;
 1481     AddFuncToPreprocListAllNapPolicies(sc, preprocessorFunc, priority, preproc_id, proto_mask);
 1482     return NULL;
 1483 }
 1484 
 1485 typedef void (*MetadataProcessFunc)(int, const uint8_t *);
 1486 void *AddMetaEval(struct _SnortConfig *sc, void (*meta_eval_func)(int, const uint8_t *), uint16_t priority,
 1487                       uint32_t preproc_id)
 1488 {
 1489     MetadataProcessFunc metaEvalFunc = (MetadataProcessFunc)meta_eval_func;
 1490     return (void *)AddFuncToPreprocMetaEvalList(sc, metaEvalFunc, priority, preproc_id);
 1491 }
 1492 
 1493 void *AddDetection(struct _SnortConfig *sc, void (*det_func)(void *, void *), uint16_t priority,
 1494                       uint32_t det_id, uint32_t proto_mask)
 1495 {
 1496     SnortPacketProcessFunc detectionFunc = (SnortPacketProcessFunc)det_func;
 1497     return (void *)AddFuncToDetectionList(sc, detectionFunc, priority, det_id, proto_mask);
 1498 }
 1499 
 1500 void AddPreprocessorCheck(struct _SnortConfig *sc, int (*pp_chk_func)(struct _SnortConfig *sc))
 1501 {
 1502     AddFuncToConfigCheckList(sc, pp_chk_func);
 1503 }
 1504 
 1505 void DynamicDisableDetection( void *p )
 1506 {
 1507     DisableDetect( ( Packet * ) p );
 1508 }
 1509 
 1510 void DynamicDisableAllDetection( void *p )
 1511 {
 1512     DisableAllDetect( ( Packet * ) p );
 1513 }
 1514 
 1515 void DynamicEnableContentDetection( void )
 1516 {
 1517     EnableContentDetect();
 1518 }
 1519 
 1520 void DynamicDisablePacketAnalysis( void *p )
 1521 {
 1522     DisablePacketAnalysis( ( Packet * ) p );
 1523 }
 1524 
 1525 int DynamicDetect(void *p)
 1526 {
 1527     return Detect((Packet *)p);
 1528 }
 1529 
 1530 int DynamicEnablePreprocessor(void *p, uint32_t preprocId)
 1531 {
 1532     return EnablePreprocessor((Packet *)p, preprocId);
 1533 }
 1534 
 1535 #ifdef ACTIVE_RESPONSE
 1536 void DynamicActiveSetEnabled(int on_off)
 1537 {
 1538      Active_SetEnabled(on_off);
 1539 }
 1540 #endif
 1541 
 1542 void *DynamicGetRuleClassByName(char *name)
 1543 {
 1544     return (void *)ClassTypeLookupByType(snort_conf, name);
 1545 }
 1546 
 1547 void *DynamicGetRuleClassById(int id)
 1548 {
 1549     return (void *)ClassTypeLookupById(snort_conf, id);
 1550 }
 1551 
 1552 void DynamicRegisterPreprocessorProfile(const char *keyword, void *stats, int layer, void *parent, PreprocStatsNodeFreeFunc freefn)
 1553 {
 1554 #ifdef PERF_PROFILING
 1555     RegisterPreprocessorProfile(keyword, (PreprocStats *)stats, layer, (PreprocStats *)parent, freefn);
 1556 #endif
 1557 }
 1558 
 1559 int DynamicProfilingPreprocs(void)
 1560 {
 1561 #ifdef PERF_PROFILING
 1562     return ScProfilePreprocs();
 1563 #else
 1564     return 0;
 1565 #endif
 1566 }
 1567 
 1568 int DynamicPreprocess(void *packet)
 1569 {
 1570     return Preprocess( ( Packet * ) packet );
 1571 }
 1572 
 1573 void DynamicDisablePreprocessors(void *p)
 1574 {
 1575     DisableAppPreprocessors( ( Packet * ) p );
 1576 }
 1577 
 1578 void DynamicIP6Build(void *p, const void *hdr, int family)
 1579 {
 1580     sfiph_build((Packet *)p, hdr, family);
 1581 }
 1582 
 1583 static inline void DynamicIP6SetCallbacks(void *p, int family, char orig)
 1584 {
 1585     set_callbacks((Packet *)p, family, orig);
 1586 }
 1587 
 1588 int DynamicSnortEventqLog(void *p)
 1589 {
 1590     return SnortEventqLog(snort_conf->event_queue, (Packet *)p);
 1591 }
 1592 
 1593 tSfPolicyId DynamicGetParserPolicy(struct _SnortConfig *sc)
 1594 {
 1595     return getParserPolicy(sc);
 1596 }
 1597 
 1598 tSfPolicyId DynamicGetNapRuntimePolicy(void)
 1599 {
 1600     return getNapRuntimePolicy();
 1601 }
 1602 
 1603 tSfPolicyId DynamicGetIpsRuntimePolicy(void)
 1604 {
 1605     return getIpsRuntimePolicy();
 1606 }
 1607 
 1608 tSfPolicyId DynamicGetDefaultPolicy(void)
 1609 {
 1610     return getDefaultPolicy();
 1611 }
 1612 
 1613 tSfPolicyId DynamicGetPolicyFromId(uint16_t id)
 1614 {
 1615     return sfPolicyIdGetBinding(snort_conf->policy_config, id);
 1616 }
 1617 
 1618 void DynamicChangeNapRuntimePolicy(tSfPolicyId new_id, void *scb)
 1619 {
 1620     session_api->set_runtime_policy( scb, SNORT_NAP_POLICY, new_id );
 1621     setNapRuntimePolicy(new_id);
 1622 }
 1623 
 1624 void DynamicChangeIpsRuntimePolicy(tSfPolicyId new_id, void *p)
 1625 {
 1626     Packet *pkt = (Packet *) p;
 1627 
 1628     session_api->set_runtime_policy( pkt->ssnptr, SNORT_IPS_POLICY, new_id );
 1629     setIpsRuntimePolicy(new_id);
 1630     pkt->configPolicyId = snort_conf->targeted_policies[new_id]->configPolicyId;
 1631 }
 1632 
 1633 static void DynamicAddPktTraceData(int module, int strLen)
 1634 {
 1635     addPktTraceData(module, strLen);
 1636 }
 1637 
 1638 static const char* DynamicGetPktTraceActionMsg()
 1639 {
 1640     return getPktTraceActMsg();
 1641 }
 1642 
 1643 static void* DynamicEncodeNew (void)
 1644 {
 1645     return (void*)Encode_New();
 1646 }
 1647 
 1648 static void DynamicEncodeDelete (void *p)
 1649 {
 1650     Encode_Delete((Packet*)p);
 1651 }
 1652 
 1653 static void *DynamicNewGrinderPkt(void *p, void *phdr, uint8_t *pkt)
 1654 {
 1655     return (void*)NewGrinderPkt((Packet *)p, (DAQ_PktHdr_t *)phdr, pkt);
 1656 }
 1657 
 1658 static void DynamicDeleteGrinderPkt(void *p)
 1659 {
 1660     DeleteGrinderPkt((Packet*)p);
 1661 }
 1662 
 1663 static int DynamicEncodeFormat (uint32_t f, const void* p, void *c, int t)
 1664 {
 1665     return Encode_Format(f, (Packet*)p, (Packet*)c, (PseudoPacketType)t);
 1666 }
 1667 
 1668 static void DynamicEncodeUpdate (void* p)
 1669 {
 1670     Encode_Update((Packet*)p);
 1671 }
 1672 
 1673 #ifdef ACTIVE_RESPONSE
 1674 void DynamicSendBlockResponseMsg(void *p, const uint8_t* buffer, uint32_t buffer_len, unsigned flags)
 1675 {
 1676     Packet *packet = (Packet *)p;
 1677     EncodeFlags df = (packet->packet_flags & PKT_FROM_SERVER) ? ENC_FLAG_FWD:0;
 1678 
 1679     if ( !packet->data || packet->dsize == 0 )
 1680         return;
 1681 
 1682     if (flags & SND_BLK_RESP_FLAG_DO_CLIENT)
 1683         df |= ENC_FLAG_RST_CLNT;
 1684     if (flags & SND_BLK_RESP_FLAG_DO_SERVER)
 1685         df |= ENC_FLAG_RST_SRVR;
 1686     if (packet->packet_flags & PKT_STREAM_EST)
 1687         Active_SendData(packet, df, buffer, buffer_len);
 1688 }
 1689 
 1690 void DynamicActiveResponseMsg(void *p, const uint8_t* buf, uint32_t blen, unsigned flags)
 1691 {
 1692     EncodeFlags df = (SND_BLK_RESP_FLAG_DO_CLIENT) ? 0: ENC_FLAG_FWD;
 1693 
 1694     Active_UDPInjectData((Packet *)p, df , buf, blen);
 1695 }
 1696 void DynamicActiveInjectData(void *p, uint32_t flags, const uint8_t *buf, uint32_t blen)
 1697 {
 1698     Active_InjectData((Packet *)p, (EncodeFlags)flags, buf, blen);
 1699 }
 1700 
 1701 void DynamicActiveSendForwardReset(void *p)
 1702 {
 1703     Active_SendReset((Packet *)p, ENC_FLAG_FWD);
 1704 }
 1705 
 1706 int DynamicActiveQueueResponse( Active_ResponseFunc cb, void *data )
 1707 {
 1708     return Active_QueueResponse( cb, data );
 1709 }
 1710 
 1711 #endif
 1712 
 1713 void DynamicDropPacket(void *p)
 1714 {
 1715     Active_DropPacket((Packet*)p);
 1716 }
 1717 
 1718 bool DynamicRetryPacket(void *p)
 1719 {
 1720     return Active_DAQRetryPacket( ( Packet * ) p );
 1721 }
 1722 
 1723 bool DynamicActivePacketWasDropped(void)
 1724 {
 1725     return Active_PacketWasDropped();
 1726 }
 1727 
 1728 void DynamicForceDropPacket(void *p)
 1729 {
 1730     Active_ForceDropPacket( );
 1731 }
 1732 
 1733 void DynamicDropSessionAndReset(void *p)
 1734 {
 1735     Active_DropSession((Packet*)p);
 1736 }
 1737 
 1738 void DynamicForceDropSession(void *p)
 1739 {
 1740     Active_ForceDropSession();
 1741 }
 1742 
 1743 void DynamicForceDropSessionAndReset(void *p)
 1744 {
 1745     Active_ForceDropResetAction((Packet *)p);
 1746 }
 1747 
 1748 
 1749 void DynamicSetParserPolicy(SnortConfig *sc, tSfPolicyId id)
 1750 {
 1751     setParserPolicy(sc, id);
 1752 }
 1753 
 1754 void DynamicSetFileDataPtr(uint8_t *ptr, uint16_t decode_size)
 1755 {
 1756     setFileDataPtr((const uint8_t*)ptr, decode_size);
 1757 }
 1758 
 1759 void DynamicDetectResetPtr(uint8_t *ptr, uint16_t decode_size)
 1760 {
 1761     DetectReset(ptr, decode_size);
 1762 }
 1763 
 1764 
 1765 void DynamicSetAltDecode(uint16_t altLen)
 1766 {
 1767     SetAltDecode(altLen);
 1768 }
 1769 
 1770 int DynamicGetNapInlineMode(void)
 1771 {
 1772     return ScNapInlineMode();
 1773 }
 1774 
 1775 int DynamicGetIpsInlineMode(void)
 1776 {
 1777     return ScIpsInlineMode();
 1778 }
 1779 
 1780 long DynamicSnortStrtol(const char *nptr, char **endptr, int base)
 1781 {
 1782     return SnortStrtol(nptr,endptr,base);
 1783 }
 1784 
 1785 unsigned long DynamicSnortStrtoul(const char *nptr, char **endptr, int base)
 1786 {
 1787     return SnortStrtoul(nptr,endptr,base);
 1788 }
 1789 
 1790 const char *DynamicSnortStrnStr(const char *s, int slen, const char *accept)
 1791 {
 1792     return SnortStrnStr(s, slen, accept);
 1793 }
 1794 
 1795 
 1796 const char *DynamicSnortStrcasestr(const char *s, int slen, const char *accept)
 1797 {
 1798     return SnortStrcasestr(s, slen, accept);
 1799 }
 1800 
 1801 int DynamicSnortStrncpy(char *dst, const char *src, size_t dst_size)
 1802 {
 1803     return SnortStrncpy(dst, src, dst_size);
 1804 }
 1805 
 1806 const char *DynamicSnortStrnPbrk(const char *s, int slen, const char *accept)
 1807 {
 1808     return SnortStrnPbrk(s, slen, accept);
 1809 }
 1810 
 1811 int DynamicEvalRTN(void *rtn, void *p, int check_ports)
 1812 {
 1813     return fpEvalRTN((RuleTreeNode *)rtn, (Packet *)p, check_ports);
 1814 }
 1815 
 1816 char *DynamicGetLogDirectory(void)
 1817 {
 1818     return SnortStrdup(snort_conf->log_dir);
 1819 }
 1820 
 1821 uint32_t DynamicGetSnortInstance(void)
 1822 {
 1823     return (snort_conf->event_log_id >> 16);
 1824 }
 1825 
 1826 bool DynamicIsPafEnabled(void)
 1827 {
 1828     return ScPafEnabled();
 1829 }
 1830 
 1831 bool DynamicIsReadMode(void)
 1832 {
 1833     return ScReadMode();
 1834 }
 1835 
 1836 time_t DynamicPktTime(void)
 1837 {
 1838     return packet_time();
 1839 }
 1840 
 1841 void DynamicGetPktTimeOfDay(struct timeval *tv)
 1842 {
 1843     packet_gettimeofday(tv);
 1844 }
 1845 
 1846 #ifdef SIDE_CHANNEL
 1847 bool DynamicIsSCEnabled(void)
 1848 {
 1849     return ScSideChannelEnabled();
 1850 }
 1851 
 1852 int DynamicSCRegisterRXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data)
 1853 {
 1854     return SideChannelRegisterRXHandler(type, processMsgFunc, data);
 1855 }
 1856 
 1857 int DynamicSCPreallocMessageTX(uint32_t length, SCMsgHdr **hdr_ptr, uint8_t **msg_ptr, void **msg_handle)
 1858 {
 1859     return SideChannelPreallocMessageTX(length, hdr_ptr, msg_ptr, msg_handle);
 1860 }
 1861 
 1862 int DynamicSCEnqueueMessageTX(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc)
 1863 {
 1864     return SideChannelEnqueueMessageTX(hdr, msg, length, msg_handle, msgFreeFunc);
 1865 }
 1866 #endif
 1867 
 1868 int DynamicCanWhitelist(void)
 1869 {
 1870     return DAQ_CanWhitelist();
 1871 }
 1872 
 1873 #if defined(DAQ_CAPA_CST_TIMEOUT)
 1874 bool DynamicCanGetTimeout(void)
 1875 {
 1876      return Daq_Capa_Timeout;
 1877 }
 1878 #endif
 1879 
 1880 int DynamicSnortIsStrEmpty(const char *s)
 1881 {
 1882     return IsEmptyStr((char*)s);
 1883 }
 1884 
 1885 static void DynamicDisableAllPolicies(struct _SnortConfig *sc)
 1886 {
 1887     DisableAllPolicies(sc);
 1888 }
 1889 
 1890 static int DynamicReenablePreprocBitFunc(struct _SnortConfig *sc, unsigned int preproc_id)
 1891 {
 1892     return ReenablePreprocBit(sc, preproc_id);
 1893 }
 1894 
 1895 #ifdef SIDE_CHANNEL
 1896 static sigset_t DynamicSnortSignalMask(void)
 1897 {
 1898     sigset_t mask;
 1899 
 1900     sigemptyset(&mask);
 1901     sigaddset(&mask, SIGTERM);
 1902     sigaddset(&mask, SIGQUIT);
 1903     sigaddset(&mask, SIGPIPE);
 1904     sigaddset(&mask, SIGINT);
 1905     sigaddset(&mask, SIGNAL_SNORT_RELOAD);
 1906     sigaddset(&mask, SIGNAL_SNORT_DUMP_STATS);
 1907     sigaddset(&mask, SIGUSR1);
 1908     sigaddset(&mask, SIGUSR2);
 1909     sigaddset(&mask, SIGNAL_SNORT_ROTATE_STATS);
 1910     sigaddset(&mask, SIGNAL_SNORT_CHILD_READY);
 1911 #ifdef TARGET_BASED
 1912     sigaddset(&mask, SIGNAL_SNORT_READ_ATTR_TBL);
 1913     sigaddset(&mask, SIGVTALRM);
 1914 #endif
 1915     pthread_sigmask(SIG_SETMASK, &mask, NULL);
 1916 
 1917     return mask;
 1918 }
 1919 #endif
 1920 
 1921 static SslAppIdLookupFunc sslAppIdLookupFnPtr;
 1922 
 1923 static void registerSslAppIdLookup(SslAppIdLookupFunc fnptr)
 1924 {
 1925     sslAppIdLookupFnPtr = fnptr;
 1926 }
 1927 
 1928 static int sslAppIdLookup(void *ssnptr, const char * serverName, const char * commonName, int32_t *serviceAppId, int32_t *clientAppId, int32_t *payloadAppId)
 1929 {
 1930     if (sslAppIdLookupFnPtr)
 1931         return (sslAppIdLookupFnPtr)(ssnptr, serverName, commonName, serviceAppId, clientAppId, payloadAppId);
 1932     return 0;
 1933 }
 1934 
 1935 static SetTlsHostAppIdFunc setTlsHostAppIdFnPtr;
 1936 
 1937 static void registerSetTlsHostAppId(SetTlsHostAppIdFunc fnptr)
 1938 {
 1939     setTlsHostAppIdFnPtr = fnptr;
 1940 }
 1941 
 1942 static void setTlsHostAppId(void *ssnptr, const char *serverName, const char *commonName,
 1943                         const char *orgName, const char *subjectAltName, bool isSniMismatch,
 1944                         int32_t *serviceAppId, int32_t *clientAppId, int32_t *payloadAppId)
 1945 {
 1946     if (setTlsHostAppIdFnPtr)
 1947         (setTlsHostAppIdFnPtr)(ssnptr, serverName, commonName, orgName, subjectAltName, isSniMismatch, serviceAppId, clientAppId, payloadAppId);
 1948 }
 1949 
 1950 static GetAppIdFunc getAppIdFnPtr = NULL;
 1951 
 1952 static void registerGetAppId(GetAppIdFunc fnptr)
 1953 {
 1954     getAppIdFnPtr = fnptr;
 1955 }
 1956 
 1957 static int32_t getAppId(void *ssnptr)
 1958 {
 1959     if(getAppIdFnPtr)
 1960         return (getAppIdFnPtr)(ssnptr);
 1961     return 0;
 1962 }
 1963 
 1964 
 1965 static UrlQueryCreateFunc urlQueryCreateFnPtr;
 1966 static UrlQueryDestroyFunc urlQueryDestroyFnPtr;
 1967 static UrlQueryMatchFunc urlQueryMatchFnPtr;
 1968 static UserGroupIdGetFunc userGroupIdGetFnPtr;
 1969 static GeoIpAddressLookupFunc geoIpAddressLookupFnPtr;
 1970 static UpdateSSLSSnLogDataFunc updateSSLSSnLogDataFnPtr;
 1971 static EndSSLSSnLogDataFunc endSSLSSnLogDataFnPtr;
 1972 static GetSSLActualActionFunc getSSLActualActionFnPtr;
 1973 static GetIntfDataFunc getIntfDataFnPtr;
 1974 static ReputationProcessExternalIpFunc reputationProcessExternalIpFnPtr;
 1975 static ReputationGetEntryCountFunc reputatinGetEntryCountFnPtr;
 1976 
 1977 void registerReputationGetEntryCount(ReputationGetEntryCountFunc entryCountFn)
 1978 {
 1979     reputatinGetEntryCountFnPtr = entryCountFn;
 1980 }
 1981 
 1982 void registerReputationProcessExternal(ReputationProcessExternalIpFunc extProcessFn)
 1983 {
 1984     reputationProcessExternalIpFnPtr = extProcessFn;
 1985 }
 1986 
 1987 static int _reputation_get_entry_count(void)
 1988 {
 1989     if(reputatinGetEntryCountFnPtr)
 1990         return (reputatinGetEntryCountFnPtr());
 1991     return 0;
 1992 }
 1993 
 1994 static bool _reputation_process_external_ip(void *p, sfaddr_t* ip)
 1995 {
 1996     if(reputationProcessExternalIpFnPtr)
 1997     {
 1998         return ((reputationProcessExternalIpFnPtr)(p,ip));
 1999     }
 2000     return false;
 2001 }
 2002 
 2003 void registerUrlQuery(UrlQueryCreateFunc createFn, UrlQueryDestroyFunc destroyFn, UrlQueryMatchFunc matchFn)
 2004 {
 2005     urlQueryCreateFnPtr = createFn;
 2006     urlQueryDestroyFnPtr = destroyFn;
 2007     urlQueryMatchFnPtr = matchFn;
 2008 }
 2009 static struct urlQueryContext* urlQueryCreate(const char *url)
 2010 {
 2011     if (urlQueryCreateFnPtr)
 2012     {
 2013         return ((urlQueryCreateFnPtr)(url));
 2014     }
 2015 
 2016     return NULL;
 2017 }
 2018 static void urlQueryDestroy(struct urlQueryContext *context)
 2019 {
 2020     if (urlQueryDestroyFnPtr)
 2021         (urlQueryDestroyFnPtr)(context);
 2022 }
 2023 static int urlQueryMatch(void *ssnptr, struct urlQueryContext *context, uint16_t inUrlCat, uint16_t inUrlMinRep, uint16_t inUrlMaxRep)
 2024 {
 2025     if (urlQueryMatchFnPtr)
 2026         return (urlQueryMatchFnPtr)(ssnptr, context, inUrlCat, inUrlMinRep, inUrlMaxRep);
 2027     return -1;
 2028 }
 2029 
 2030 #if defined DAQ_CAPA_CST_TIMEOUT
 2031 void RegisterGetDaqCapaTimeout(GetDaqCapaTimeOutFunc timeoutFn)
 2032 {
 2033      getDaqCapaTimeoutFnPtr = timeoutFn;
 2034 }
 2035 #endif
 2036 
 2037 static void registerUserGroupIdGet(UserGroupIdGetFunc userIdFn)
 2038 {
 2039     userGroupIdGetFnPtr = userIdFn;
 2040 }
 2041 
 2042 static int userGroupIdGet(void *ssnptr, uint32_t *userId, uint32_t *realmId, unsigned *groupIdArray, unsigned groupIdArrayLen)
 2043 {
 2044     if (userGroupIdGetFnPtr)
 2045         return (userGroupIdGetFnPtr)(ssnptr, userId, realmId, groupIdArray, groupIdArrayLen);
 2046     return -1;
 2047 }
 2048 
 2049 static void registerGeoIpAddressLookup(GeoIpAddressLookupFunc fn)
 2050 {
 2051     geoIpAddressLookupFnPtr = fn;
 2052 }
 2053 static int geoIpAddressLookup(const sfaddr_t *snortIp, uint16_t* geo)
 2054 {
 2055     if (geoIpAddressLookupFnPtr)
 2056         return (geoIpAddressLookupFnPtr)(snortIp, geo);
 2057     return -1;
 2058 }
 2059 
 2060 static void registerGetIntfData(GetIntfDataFunc fn)
 2061 {
 2062     getIntfDataFnPtr = fn;
 2063 }
 2064 
 2065 static void getIntfData(void *ssnptr, int32_t *ingressIntfIndex, int32_t *egressIntfIndex,
 2066                 int32_t *ingressZoneIndex, int32_t *egressZoneIndex)
 2067 {
 2068     if (getIntfDataFnPtr)
 2069     {
 2070         (getIntfDataFnPtr)(ssnptr, ingressIntfIndex, egressIntfIndex, ingressZoneIndex, egressZoneIndex);
 2071     }
 2072 }
 2073 
 2074 static void registerUpdateSSLSSnLogData(UpdateSSLSSnLogDataFunc fn)
 2075 {
 2076     updateSSLSSnLogDataFnPtr = fn;
 2077 }
 2078 
 2079 static void updateSSLSSnLogData(void *ssnptr, uint8_t logging_on, uint8_t action_is_block, const char *ssl_cert_fingerprint,
 2080     uint32_t ssl_cert_fingerprint_len, uint32_t ssl_cert_status, uint8_t *ssl_policy_id,
 2081     uint32_t ssl_policy_id_len, uint32_t ssl_rule_id, uint16_t ssl_cipher_suite, uint8_t ssl_version,
 2082     uint16_t ssl_actual_action, uint16_t ssl_expected_action, uint32_t ssl_url_category,
 2083     uint16_t ssl_flow_status, uint32_t ssl_flow_error, uint32_t ssl_flow_messages,
 2084     uint64_t ssl_flow_flags, char *ssl_server_name, uint8_t *ssl_session_id, uint8_t session_id_len,
 2085     uint8_t *ssl_ticket_id, uint8_t ticket_id_len)
 2086 {
 2087     if (updateSSLSSnLogDataFnPtr)
 2088     {
 2089         (updateSSLSSnLogDataFnPtr)(ssnptr, logging_on, action_is_block, ssl_cert_fingerprint,
 2090                 ssl_cert_fingerprint_len, ssl_cert_status, ssl_policy_id,
 2091                 ssl_policy_id_len, ssl_rule_id, ssl_cipher_suite, ssl_version,
 2092                 ssl_actual_action, ssl_expected_action, ssl_url_category,
 2093                 ssl_flow_status, ssl_flow_error, ssl_flow_messages,
 2094                 ssl_flow_flags, ssl_server_name, ssl_session_id, session_id_len, ssl_ticket_id, ticket_id_len);
 2095     }
 2096 }
 2097 
 2098 static void registerGetSSLActualAction(GetSSLActualActionFunc fn)
 2099 {
 2100     getSSLActualActionFnPtr = fn;
 2101 }
 2102 
 2103 static int getSSLActualAction(void *ssnptr, uint16_t *action)
 2104 {
 2105     if (getSSLActualActionFnPtr)
 2106     {
 2107         return (getSSLActualActionFnPtr)(ssnptr, action);
 2108     }
 2109 
 2110     return -1;
 2111 }
 2112 
 2113 
 2114 static void registerEndSSLSSnLogData(EndSSLSSnLogDataFunc fn)
 2115 {
 2116     endSSLSSnLogDataFnPtr = fn;
 2117 }
 2118 
 2119 static void endSSLSSnLogData(void *ssnptr, uint32_t ssl_flow_messages, uint64_t ssl_flow_flags)
 2120 {
 2121     if (endSSLSSnLogDataFnPtr)
 2122     {
 2123         (endSSLSSnLogDataFnPtr)(ssnptr, ssl_flow_messages, ssl_flow_flags);
 2124     }
 2125 }
 2126 static inline bool DynamicReadyForProcess (void* pkt)
 2127 {
 2128     Packet *p = (Packet *)pkt;
 2129 
 2130     if ( ScPafEnabled() )
 2131         return PacketHasPAFPayload(p);
 2132 
 2133     return !(p->packet_flags & PKT_STREAM_INSERT);
 2134 }
 2135 
 2136 void DynamicSetSSLCallback(void *p)
 2137 {
 2138     SetSSLCallback(p);
 2139 }
 2140 
 2141 void *DynamicGetSSLCallback(void)
 2142 {
 2143     return GetSSLCallback();
 2144 }
 2145 
 2146 /*
 2147    DynamicIsSSLPolicyEnabled( struct _SnortConfig * )
 2148 
 2149    Notes: Durring reload/init SnortConfig MUST be provided.
 2150           Durring runtime/packet processing, NULL MUST be provided.
 2151 
 2152    Arguments: (struct _SnortConfig*) sc
 2153    Returns: (bool) true || false
 2154 */
 2155 bool DynamicIsSSLPolicyEnabled( struct _SnortConfig *sc )
 2156 {
 2157     tSfPolicyId policy;
 2158     if (sc)
 2159     {
 2160         policy = getParserPolicy(sc);
 2161         return (sc->targeted_policies[ policy ]->ssl_policy_enabled);
 2162     }
 2163 
 2164     policy = getNapRuntimePolicy();
 2165     return (snort_conf->targeted_policies[ policy ]->ssl_policy_enabled );
 2166 }
 2167 
 2168 void DynamicSetSSLPolicyEnabled(struct _SnortConfig *sc, tSfPolicyId policy, bool value)
 2169 {
 2170     sc->targeted_policies[policy]->ssl_policy_enabled = value;
 2171 }
 2172 
 2173 static ftpGetModefunc ftpGetDataModefnptr;
 2174 void registerFtpModeQuery(ftpGetModefunc fnptr)
 2175 {
 2176     if (!ftpGetDataModefnptr)
 2177         ftpGetDataModefnptr = fnptr;
 2178 }
 2179 
 2180 static bool ftpGetDataSessionMode(void *ssnptr)
 2181 {
 2182     if (ftpGetDataModefnptr)
 2183     {
 2184         return ((ftpGetDataModefnptr)(ssnptr));
 2185     }
 2186     return 0;
 2187 }
 2188 
 2189 #ifdef SNORT_RELOAD
 2190 int DynamicReloadAdjustRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId,
 2191                                 ReloadAdjustFunc raFunc, void* raUserData,
 2192                                 ReloadAdjustUserFreeFunc raUserFreeFunc)
 2193 {
 2194     return ReloadAdjustRegister(sc, raName, raPolicyId, raFunc, raUserData, raUserFreeFunc);
 2195 }
 2196 #endif
 2197 
 2198 #if defined(FEAT_OPEN_APPID)
 2199 typedef struct _IsAppIdRequiredFuncNode
 2200 {
 2201     IsAppIdRequiredFunc               fn;
 2202     struct _IsAppIdRequiredFuncNode * next;
 2203 }
 2204 IsAppIdRequiredFuncNode;
 2205 
 2206 static IsAppIdRequiredFuncNode * isAppIdRequiredFuncList = NULL;
 2207 static pthread_mutex_t isAppIdRequiredFuncListMutex = PTHREAD_MUTEX_INITIALIZER;
 2208 
 2209 static void registerIsAppIdRequired(IsAppIdRequiredFunc fn)
 2210 {
 2211     IsAppIdRequiredFuncNode * curr;
 2212 
 2213     if (fn == NULL)
 2214         return;
 2215 
 2216     pthread_mutex_lock(&isAppIdRequiredFuncListMutex);
 2217 
 2218     curr = isAppIdRequiredFuncList;
 2219     while (curr != NULL)
 2220     {
 2221         if (curr->fn == fn)
 2222         {
 2223             pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
 2224             return;    /* function is already registered */
 2225         }
 2226         curr = curr->next;
 2227     }
 2228 
 2229     curr = malloc(sizeof(IsAppIdRequiredFuncNode));
 2230     if (curr == NULL)
 2231     {
 2232         pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
 2233         return;
 2234     }
 2235 
 2236     curr->fn = fn;
 2237     curr->next = isAppIdRequiredFuncList;
 2238     isAppIdRequiredFuncList = curr;
 2239 
 2240     pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
 2241 }
 2242 
 2243 static void unregisterIsAppIdRequired(IsAppIdRequiredFunc fn)
 2244 {
 2245     IsAppIdRequiredFuncNode *  tmp;
 2246     IsAppIdRequiredFuncNode ** curr;
 2247 
 2248     if (fn == NULL)
 2249         return;
 2250 
 2251     pthread_mutex_lock(&isAppIdRequiredFuncListMutex);
 2252 
 2253     curr = &isAppIdRequiredFuncList;
 2254     while (*curr != NULL)
 2255     {
 2256         if ((*curr)->fn == fn)
 2257             break;
 2258         curr = &((*curr)->next);
 2259     }
 2260 
 2261     if (*curr == NULL)
 2262     {
 2263         pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
 2264         return;    /* function is not currently registered */
 2265     }
 2266 
 2267     tmp   = *curr;
 2268     *curr = (*curr)->next;
 2269 
 2270     pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
 2271 
 2272     free(tmp);
 2273 }
 2274 
 2275 static bool isAppIdRequired(void)
 2276 {
 2277     IsAppIdRequiredFuncNode * curr;
 2278 
 2279     pthread_mutex_lock(&isAppIdRequiredFuncListMutex);
 2280 
 2281     curr = isAppIdRequiredFuncList;
 2282     while (curr != NULL)
 2283     {
 2284         if ((curr->fn != NULL) && curr->fn())
 2285         {
 2286             pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
 2287             return true;
 2288         }
 2289         curr = curr->next;
 2290     }
 2291 
 2292     pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
 2293 
 2294     return false;
 2295 }
 2296 
 2297 static const char *dummyGetApplicationName(int32_t appId)
 2298 {
 2299     return NULL;
 2300 }
 2301 
 2302 static tAppId dummyGetApplicationId(const char *appName)
 2303 {
 2304     return 0;
 2305 }
 2306 
 2307 static tAppId dummyAppIdFFromAppIdData(struct AppIdData *session)
 2308 {
 2309     return 0;
 2310 }
 2311 
 2312 static SFGHASH* dummyAppIdMultiPayload(struct AppIdData *session)
 2313 {
 2314     return NULL;
 2315 }
 2316 
 2317 static bool dummyCheckAppIdData(struct AppIdData *session)
 2318 {
 2319     return false;
 2320 }
 2321 
 2322 static char *dummyGetUserName(struct AppIdData *session, tAppId *service, bool *isLoginSuccessful)
 2323 {
 2324     return NULL;
 2325 }
 2326 
 2327 static char *dummyGetClientVersion(struct AppIdData *session)
 2328 {
 2329     return NULL;
 2330 }
 2331 
 2332 static uint64_t dummyGetAppIdSessionAttribute(struct AppIdData *session, uint64_t flag)
 2333 {
 2334     return 0;
 2335 }
 2336 
 2337 static APPID_FLOW_TYPE dummyGetFlowType(struct AppIdData *appIdData)
 2338 {
 2339     return APPID_FLOW_TYPE_IGNORE;
 2340 }
 2341 
 2342 static void dummyGetServiceInfo(struct AppIdData *appIdData, char **serviceVendor, char **serviceVersion, RNAServiceSubtype **serviceSubtype)
 2343 {
 2344 }
 2345 
 2346 static short dummyGetServicePort(struct AppIdData *appIdData)
 2347 {
 2348     return 0;
 2349 }
 2350 
 2351 static sfaddr_t *dummyIpFromAppIdData(struct AppIdData *appIdData)
 2352 {
 2353     return NULL;
 2354 }
 2355 
 2356 static struct in6_addr *dummyGetInitiatorIp(struct AppIdData *appIdData)
 2357 {
 2358     return NULL;
 2359 }
 2360 
 2361 static char *dummyStringFromAppIdData(struct AppIdData *appIdData)
 2362 {
 2363     return NULL;
 2364 }
 2365 
 2366 static char *dummyIndexedStringFromAppIdData(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
 2367 {
 2368     return NULL;
 2369 }
 2370 
 2371 static void dummyFreeIndexedStringFromAppIdData(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
 2372 {
 2373     return;
 2374 }
 2375 
 2376 static uint16_t dummyGetHttpFieldOffset(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
 2377 {
 2378     return 0;
 2379 }
 2380 
 2381 static SEARCH_SUPPORT_TYPE dummySearchTypeFromAppIdData(struct AppIdData *appIdData)
 2382 {
 2383     return NOT_A_SEARCH_ENGINE;
 2384 }
 2385 
 2386 static uint16_t dummyOffsetFromAppIdData(struct AppIdData *appIdData)
 2387 {
 2388     return 0;
 2389 }
 2390 
 2391 static DhcpFPData *dummyGetDhcpFpData(struct AppIdData *appIdData)
 2392 {
 2393     return NULL;
 2394 }
 2395 
 2396 static void dummyFreeDhcpFpData(struct AppIdData *session, DhcpFPData *data)
 2397 {
 2398 }
 2399 
 2400 static DHCPInfo *dummyGetDhcpInfo(struct AppIdData *session)
 2401 {
 2402     return NULL;
 2403 }
 2404 
 2405 static void dummyFreeDhcpInfo(struct AppIdData *session, DHCPInfo *data)
 2406 {
 2407 }
 2408 
 2409 static FpSMBData *dummyGetSmbFpData(struct AppIdData *session)
 2410 {
 2411     return NULL;
 2412 }
 2413 
 2414 static void dummyFreeSmbFpData(struct AppIdData *session, FpSMBData *data)
 2415 {
 2416 }
 2417 
 2418 static char *dummyGetNetbiosName(struct AppIdData *session)
 2419 {
 2420     return NULL;
 2421 }
 2422 
 2423 static uint32_t dummyProduceHAState(void *lwssn, uint8_t *buf)
 2424 {
 2425     return 0;
 2426 }
 2427 
 2428 static uint32_t dummyConsumeHAState(void *lwssn, const uint8_t *buf, uint8_t length, uint8_t proto, const struct in6_addr* ip, uint16_t initiatorPort)
 2429 {
 2430     return 0;
 2431 }
 2432 
 2433 static struct AppIdData *dummyGetAppIdData(void *lwssn)
 2434 {
 2435     return NULL;
 2436 }
 2437 
 2438 static int dummyGetAppIdSessionPacketCount(struct AppIdData * appIdData)
 2439 {
 2440     return 0;
 2441 }
 2442 
 2443 static char *dummyGetDNSQuery(struct AppIdData *session, uint8_t *query_len, bool *got_response)
 2444 {
 2445     if (query_len)
 2446         *query_len = 0;
 2447     if (got_response)
 2448         *got_response = false;
 2449     return NULL;
 2450 }
 2451 static uint16_t dummyGetDNSOffset(struct AppIdData *session)
 2452 {
 2453     return 0;
 2454 }
 2455 static uint16_t dummyGetDNSRecordType(struct AppIdData *session)
 2456 {
 2457     return 0;
 2458 }
 2459 static uint8_t dummyGetDNSResponseType(struct AppIdData *session)
 2460 {
 2461     return 0;
 2462 }
 2463 static uint32_t dummyGetDNSTTL(struct AppIdData *session)
 2464 {
 2465     return 0;
 2466 }
 2467 
 2468 struct AppIdData* dummyRemoveExpectedAppIdData(struct AppIdData *appIdData)
 2469 {
 2470     return NULL;
 2471 }
 2472 
 2473 static void dummyDumpDebugHostInfo(void)
 2474 {
 2475 }
 2476 
 2477 struct AppIdApi appIdApi = {
 2478     dummyGetApplicationName,    /* getApplicationName */
 2479     dummyGetApplicationId,      /* getApplicationId */
 2480 
 2481     dummyAppIdFFromAppIdData,    /* getServiceAppId */
 2482     dummyAppIdFFromAppIdData,    /* getPortServiceAppId */
 2483     dummyAppIdFFromAppIdData,    /* getOnlyServiceAppId */
 2484     dummyAppIdFFromAppIdData,    /* getMiscAppId */
 2485     dummyAppIdFFromAppIdData,    /* getClientAppId */
 2486     dummyAppIdFFromAppIdData,    /* getPayloadAppId */
 2487     dummyAppIdFFromAppIdData,    /* getReferredAppId */
 2488     dummyAppIdFFromAppIdData,    /* getFwServiceAppId */
 2489     dummyAppIdFFromAppIdData,    /* getFwMiscAppId */
 2490     dummyAppIdFFromAppIdData,    /* getFwClientAppId */
 2491     dummyAppIdFFromAppIdData,    /* getFwPayloadAppId */
 2492     dummyAppIdFFromAppIdData,    /* getFwReferredAppId */
 2493     dummyAppIdMultiPayload,      /* getFwMultiPayloadList */
 2494 
 2495     dummyCheckAppIdData,    /* isSessionSslDecrypted */
 2496     dummyCheckAppIdData,    /* isAppIdInspectingSession */
 2497     dummyCheckAppIdData,    /* isAppIdAvailable */
 2498 
 2499     dummyGetUserName,         /* getUserName */
 2500     dummyGetClientVersion,    /* getClientVersion */
 2501 
 2502     dummyGetAppIdSessionAttribute,    /* getAppIdSessionAttribute */
 2503 
 2504     dummyGetFlowType,       /* getFlowType */
 2505     dummyGetServiceInfo,    /* getServiceInfo */
 2506     dummyGetServicePort,    /* getServicePort */
 2507     dummyIpFromAppIdData,   /* getServiceIp */
 2508     dummyGetInitiatorIp,   /* getInitiatorIp */
 2509 
 2510     dummyStringFromAppIdData,    /* getHttpUserAgent */
 2511     dummyStringFromAppIdData,    /* getHttpHost */
 2512     dummyStringFromAppIdData,    /* getHttpUrl */
 2513     dummyStringFromAppIdData,    /* getHttpReferer */
 2514     dummyStringFromAppIdData,    /* getHttpNewUrl */
 2515     dummyStringFromAppIdData,    /* getHttpUri */
 2516     dummyStringFromAppIdData,    /* getHttpResponseCode */
 2517     dummyStringFromAppIdData,    /* getHttpCookie */
 2518     dummyStringFromAppIdData,    /* getHttpNewCookie */
 2519     dummyStringFromAppIdData,    /* getHttpContentType */
 2520     dummyStringFromAppIdData,    /* getHttpLocation */
 2521     dummyStringFromAppIdData,    /* getHttpBody */
 2522     dummyStringFromAppIdData,    /* getHttpReqBody */
 2523     dummyOffsetFromAppIdData,    /* getHttpUriOffset */
 2524     dummyOffsetFromAppIdData,    /* getHttpUriEndOffset */
 2525     dummyOffsetFromAppIdData,    /* getHttpCookieOffset */
 2526     dummyOffsetFromAppIdData,    /* getHttpCookieEndOffset */
 2527     dummySearchTypeFromAppIdData,       /* getHttpSearch */
 2528     dummyIpFromAppIdData,        /* getHttpXffAddr */
 2529 
 2530 
 2531     dummyStringFromAppIdData,    /* getTlsHost */
 2532 
 2533     dummyGetDhcpFpData,                  /* getDhcpFpData */
 2534     dummyFreeDhcpFpData,                 /* freeDhcpFpData */
 2535     dummyGetDhcpInfo,                    /* getDhcpInfo */
 2536     dummyFreeDhcpInfo,                   /* freeDhcpInfo */
 2537     dummyGetSmbFpData,                   /* getSmbFpData */
 2538     dummyFreeSmbFpData,                  /* freeSmbFpData */
 2539     dummyGetNetbiosName,                 /* getNetbiosName */
 2540     dummyProduceHAState,                 /* produceHAState */
 2541     dummyConsumeHAState,                 /* consumeHAState */
 2542 
 2543     dummyGetAppIdData,              /* getAppIdData */
 2544     dummyGetAppIdSessionPacketCount,     /* getAppIdSessionPacketCount */
 2545 
 2546     dummyGetDNSQuery,           /* getDNSQuery */
 2547     dummyGetDNSOffset,          /* getDNSQueryoffset */
 2548     dummyGetDNSRecordType,      /* getDNSQueryType */
 2549     dummyGetDNSResponseType,    /* getDNSQueryResponseType */
 2550     dummyGetDNSTTL,             /* getDNSTTL */
 2551     dummyGetDNSOffset,          /* getDNSOptionsOffset */
 2552 
 2553     dummyIndexedStringFromAppIdData,        /* getHttpNewField */
 2554     dummyFreeIndexedStringFromAppIdData,    /* freeHttpNewField */
 2555     dummyGetHttpFieldOffset,    /* getHttpFieldOffset */
 2556     dummyGetHttpFieldOffset,    /* getHttpFieldEndOffset */
 2557     dummyCheckAppIdData,        /* isHttpInspectionDone */
 2558     dummyDumpDebugHostInfo      /* dumpDebugHostInfo */
 2559 };
 2560 #endif /* defined(FEAT_OPEN_APPID) */
 2561 
 2562 static int GetSnortPerfIndicators( void *p )
 2563 {
 2564     return( PerfIndicator_GetIndicators( (Perf_Indicator_Descriptor_p_t)p ) );
 2565 }
 2566 
 2567 static uint32_t GetSnortPacketLatency()
 2568 {
 2569 #ifdef PI_PACKET_LATENCY_SUPPORT
 2570     return ( GetPacketLatency() );
 2571 #else
 2572     return 0;
 2573 #endif
 2574 }
 2575 
 2576 static double GetSnortPacketDropPortion()
 2577 {
 2578 #ifdef PI_PACKET_DROPS_SUPPORT
 2579     return ( GetPacketDropPortion() );
 2580 #else
 2581     return 0;
 2582 #endif
 2583 }
 2584 
 2585 static bool DynamicIsTestMode(void)
 2586 {
 2587     return (ScTestMode()!= 0);
 2588 }
 2589 
 2590 static SnortConfig* GetCurrentSnortConfig(void)
 2591 {
 2592     return snort_conf;
 2593 }
 2594 
 2595 static void DynamicSetIPRepUpdateCount(uint8_t count)
 2596 {
 2597     return setIPRepUpdateCount(count);
 2598 }
 2599 
 2600 static void ErrorMsgThrottled(void* tinfo, const char *format, ...)
 2601 {
 2602     char buf[STD_BUF+1];
 2603     va_list ap;
 2604     ThrottleInfo *throttleInfo = (ThrottleInfo *)tinfo;
 2605     
 2606     va_start(ap, format);
 2607     vsnprintf(buf, STD_BUF, format, ap);
 2608     va_end(ap);
 2609     
 2610     ErrorMessageThrottled(throttleInfo, "%s", buf);
 2611 }
 2612 
 2613 int InitDynamicPreprocessors(void)
 2614 {
 2615     DynamicPreprocessorData preprocData;
 2616 
 2617     preprocData.version = PREPROCESSOR_DATA_VERSION;
 2618     preprocData.size = sizeof(DynamicPreprocessorData);
 2619 
 2620     preprocData.altBuffer = (SFDataBuffer *)&DecodeBuffer;
 2621     preprocData.altDetect = (SFDataPointer *)&DetectBuffer;
 2622     preprocData.fileDataBuf = (SFDataPointer *)&file_data_ptr;
 2623 
 2624     preprocData.logMsg = &LogMessage;
 2625     preprocData.errMsg = &ErrorMessage;
 2626     preprocData.fatalMsg = &FatalError;
 2627     preprocData.debugMsg = &DebugMessageFunc;
 2628     preprocData.errMsgThrottled = &ErrorMsgThrottled;
 2629 #ifdef SF_WCHAR
 2630     preprocData.debugWideMsg = &DebugWideMessageFunc;
 2631 #endif
 2632 
 2633     preprocData.registerPreproc = &RegisterPreprocessor;
 2634 #ifdef SNORT_RELOAD
 2635     preprocData.getRelatedReloadData = GetRelatedReloadData;
 2636 #endif
 2637 #ifdef DUMP_BUFFER
 2638     preprocData.registerBufferTracer = &RegisterBufferTracer;
 2639 #endif
 2640     preprocData.addPreproc = &AddPreprocessor;
 2641     preprocData.addPreprocAllPolicies = &AddPreprocessorAllPolicies;
 2642     preprocData.addMetaEval = &AddMetaEval;
 2643     preprocData.getSnortInstance = DynamicGetSnortInstance;
 2644     preprocData.addPreprocExit = &AddFuncToPreprocCleanExitList;
 2645     preprocData.addPreprocConfCheck = &AddPreprocessorCheck;
 2646     preprocData.preprocOptRegister = &RegisterPreprocessorRuleOption;
 2647     preprocData.addPreprocProfileFunc = &DynamicRegisterPreprocessorProfile;
 2648     preprocData.profilingPreprocsFunc = &DynamicProfilingPreprocs;
 2649 #ifdef PERF_PROFILING
 2650     preprocData.totalPerfStats = &totalPerfStats;
 2651 #else
 2652     preprocData.totalPerfStats = NULL;
 2653 #endif
 2654 
 2655     preprocData.alertAdd = &SnortEventqAdd;
 2656     preprocData.genSnortEvent = &GenerateSnortEvent;
 2657     preprocData.thresholdCheck = &sfthreshold_test;
 2658     preprocData.detect = &DynamicDetect;
 2659     preprocData.disableDetect = &DynamicDisableDetection;
 2660     preprocData.disableAllDetect = &DynamicDisableAllDetection;
 2661     preprocData.enableContentDetect = &DynamicEnableContentDetection;
 2662     preprocData.disablePacketAnalysis = &DynamicDisablePacketAnalysis;
 2663     preprocData.enablePreprocessor = &DynamicEnablePreprocessor;
 2664     preprocData.sessionAPI = session_api;
 2665     preprocData.streamAPI = stream_api;
 2666     preprocData.searchAPI = search_api;
 2667 
 2668     preprocData.config_file = &file_name;
 2669     preprocData.config_line = &file_line;
 2670     preprocData.printfappend = &sfsnprintfappend;
 2671     preprocData.tokenSplit = &mSplit;
 2672     preprocData.tokenFree = &mSplitFree;
 2673 
 2674     preprocData.getRuleInfoByName = &DynamicGetRuleClassByName;
 2675     preprocData.getRuleInfoById = &DynamicGetRuleClassById;
 2676 
 2677     preprocData.preprocess = &DynamicPreprocess;
 2678 
 2679 #ifdef DEBUG_MSGS
 2680     preprocData.debugMsgFile = &DebugMessageFile;
 2681     preprocData.debugMsgLine = &DebugMessageLine;
 2682 #else
 2683     preprocData.debugMsgFile = &no_file;
 2684     preprocData.debugMsgLine = &no_line;
 2685 #endif
 2686 
 2687     preprocData.registerPreprocStats = &RegisterPreprocStats;
 2688     preprocData.addPreprocReset = &AddFuncToPreprocResetList;
 2689     preprocData.addPreprocResetStats = &AddFuncToPreprocResetStatsList;
 2690     preprocData.disablePreprocessors = &DynamicDisablePreprocessors;
 2691 
 2692     preprocData.ip6Build = &DynamicIP6Build;
 2693     preprocData.ip6SetCallbacks = &DynamicIP6SetCallbacks;
 2694 
 2695     preprocData.logAlerts = &DynamicSnortEventqLog;
 2696     preprocData.resetAlerts = &SnortEventqReset;
 2697     preprocData.pushAlerts = SnortEventqPush;
 2698     preprocData.popAlerts = SnortEventqPop;
 2699 
 2700 #ifdef TARGET_BASED
 2701     preprocData.findProtocolReference = &FindProtocolReference;
 2702     preprocData.addProtocolReference = &AddProtocolReference;
 2703     preprocData.isAdaptiveConfigured = &IsAdaptiveConfigured;
 2704     preprocData.isAdaptiveConfiguredForSnortConfig = &IsAdaptiveConfiguredForSnortConfig;
 2705 #endif
 2706 
 2707     preprocData.preprocOptOverrideKeyword = &RegisterPreprocessorRuleOptionOverride;
 2708     preprocData.preprocOptByteOrderKeyword = &RegisterPreprocessorRuleOptionByteOrder;
 2709     preprocData.isPreprocEnabled = &IsPreprocEnabled;
 2710 
 2711     preprocData.getNapRuntimePolicy = DynamicGetNapRuntimePolicy;
 2712     preprocData.getIpsRuntimePolicy = DynamicGetIpsRuntimePolicy;
 2713     preprocData.getParserPolicy = DynamicGetParserPolicy;
 2714     preprocData.getDefaultPolicy = DynamicGetDefaultPolicy;
 2715     preprocData.setParserPolicy = DynamicSetParserPolicy;
 2716     preprocData.setFileDataPtr = DynamicSetFileDataPtr;
 2717     preprocData.DetectReset = DynamicDetectResetPtr;
 2718     preprocData.SetAltDecode = &DynamicSetAltDecode;
 2719     preprocData.GetAltDetect = &DynamicGetAltDetect;
 2720     preprocData.SetAltDetect = &DynamicSetAltDetect;
 2721     preprocData.Is_DetectFlag = &DynamicIsDetectFlag;
 2722     preprocData.DetectFlag_Disable = &DynamicDetectFlagDisable;
 2723     preprocData.SnortStrtol = DynamicSnortStrtol;
 2724     preprocData.SnortStrtoul = DynamicSnortStrtoul;
 2725     preprocData.SnortStrnStr = DynamicSnortStrnStr;
 2726     preprocData.SnortStrncpy = DynamicSnortStrncpy;
 2727     preprocData.SnortStrnPbrk = DynamicSnortStrnPbrk;
 2728     preprocData.SnortStrcasestr = DynamicSnortStrcasestr;
 2729 
 2730     preprocData.portObjectCharPortArray = PortObjectCharPortArray;
 2731     preprocData.fpEvalRTN = DynamicEvalRTN;
 2732 
 2733     preprocData.obApi = obApi;
 2734 
 2735     preprocData.encodeNew = DynamicEncodeNew;
 2736     preprocData.encodeDelete = DynamicEncodeDelete;
 2737     preprocData.encodeFormat = DynamicEncodeFormat;
 2738     preprocData.encodeUpdate = DynamicEncodeUpdate;
 2739 
 2740     preprocData.newGrinderPkt = DynamicNewGrinderPkt;
 2741     preprocData.deleteGrinderPkt = DynamicDeleteGrinderPkt;
 2742 
 2743     preprocData.portObjectCharPortArray = PortObjectCharPortArray;
 2744 
 2745     preprocData.addDetect = &AddDetection;
 2746 
 2747     preprocData.getLogDirectory = DynamicGetLogDirectory;
 2748 
 2749     preprocData.controlSocketRegisterHandler = &ControlSocketRegisterHandler;
 2750 
 2751     preprocData.registerIdleHandler = &IdleProcessingRegisterHandler;
 2752 
 2753     preprocData.isPafEnabled = DynamicIsPafEnabled;
 2754 
 2755     preprocData.pktTime = DynamicPktTime;
 2756     preprocData.getPktTimeOfDay = DynamicGetPktTimeOfDay;
 2757 #ifdef SIDE_CHANNEL
 2758     preprocData.isSCEnabled = DynamicIsSCEnabled;
 2759     preprocData.scRegisterRXHandler = &DynamicSCRegisterRXHandler;
 2760     preprocData.scAllocMessageTX = &DynamicSCPreallocMessageTX;
 2761     preprocData.scEnqueueMessageTX = &DynamicSCEnqueueMessageTX;
 2762 #endif
 2763 
 2764     preprocData.getPolicyFromId = &DynamicGetPolicyFromId;
 2765     preprocData.changeNapRuntimePolicy = &DynamicChangeNapRuntimePolicy;
 2766     preprocData.changeIpsRuntimePolicy = &DynamicChangeIpsRuntimePolicy;
 2767 
 2768     preprocData.inlineDropPacket = &DynamicDropPacket;
 2769     preprocData.inlineRetryPacket = &DynamicRetryPacket;
 2770     preprocData.inlineForceDropPacket =&DynamicForceDropPacket;
 2771     preprocData.inlineDropSessionAndReset = &DynamicDropSessionAndReset;
 2772     preprocData.inlineForceDropSession = &DynamicForceDropSession;
 2773     preprocData.inlineForceDropSessionAndReset = &DynamicForceDropSessionAndReset;
 2774     preprocData.active_PacketWasDropped = &DynamicActivePacketWasDropped;
 2775 #ifdef ACTIVE_RESPONSE
 2776     preprocData.activeSetEnabled = &DynamicActiveSetEnabled;
 2777 #endif
 2778     preprocData.SnortIsStrEmpty = DynamicSnortIsStrEmpty;
 2779 #ifdef ACTIVE_RESPONSE
 2780     preprocData.dynamicSendBlockResponse = &DynamicSendBlockResponseMsg;
 2781 #endif
 2782     preprocData.dynamicSetFlowId = &setFlowId;
 2783 #ifdef HAVE_DAQ_EXT_MODFLOW
 2784     preprocData.dynamicModifyFlow = &DAQ_ModifyFlow;
 2785 #endif
 2786 #ifdef HAVE_DAQ_QUERYFLOW
 2787     preprocData.dynamicQueryFlow = &DAQ_QueryFlow;
 2788 #endif
 2789 
 2790 #if defined(DAQ_VERSION) && DAQ_VERSION > 8
 2791     preprocData.dynamicDebugPkt = &DAQ_DebugPkt;
 2792 #endif
 2793 
 2794 #if defined(DAQ_VERSION) && DAQ_VERSION > 9
 2795     preprocData.dynamicIoctl = &DAQ_Ioctl;
 2796 #endif
 2797     preprocData.addPeriodicCheck = &AddFuncToPeriodicCheckList;
 2798     preprocData.addPostConfigFunc = &AddFuncToPreprocPostConfigList;
 2799     preprocData.addFuncToPostConfigList = &AddFuncToPostConfigList;
 2800     preprocData.snort_conf_dir = &snort_conf_dir;
 2801     preprocData.addOutputModule = &output_load_module;
 2802     preprocData.canWhitelist = DynamicCanWhitelist;
 2803     preprocData.fileAPI = file_api;
 2804     preprocData.disableAllPolicies = &DynamicDisableAllPolicies;
 2805     preprocData.reenablePreprocBit = &DynamicReenablePreprocBitFunc;
 2806     preprocData.checkValueInRange = &CheckValueInRange;
 2807 
 2808     preprocData.setHttpBuffer = SetHttpBuffer;
 2809     preprocData.getHttpBuffer = getHttpBuffer;
 2810 
 2811 #ifdef ACTIVE_RESPONSE
 2812     preprocData.activeInjectData = &DynamicActiveInjectData;
 2813     preprocData.activeSendResponse = &DynamicActiveResponseMsg;
 2814     preprocData.activeSendForwardReset = &DynamicActiveSendForwardReset;
 2815     preprocData.activeQueueResponse = &DynamicActiveQueueResponse;
 2816 #endif
 2817     preprocData.readyForProcess = &DynamicReadyForProcess;
 2818 
 2819     preprocData.getSSLCallback = &DynamicGetSSLCallback;
 2820     preprocData.setSSLCallback = &DynamicSetSSLCallback;
 2821 
 2822     preprocData.sslAppIdLookup = &sslAppIdLookup;
 2823     preprocData.registerSslAppIdLookup = &registerSslAppIdLookup;
 2824 
 2825     preprocData.getAppId = &getAppId;
 2826     preprocData.registerGetAppId = &registerGetAppId;
 2827 
 2828     preprocData.urlQueryCreate = &urlQueryCreate;
 2829     preprocData.urlQueryDestroy = &urlQueryDestroy;
 2830     preprocData.urlQueryMatch = &urlQueryMatch;
 2831     preprocData.registerUrlQuery = &registerUrlQuery;
 2832 
 2833     preprocData.userGroupIdGet = &userGroupIdGet;
 2834     preprocData.registerUserGroupIdGet = &registerUserGroupIdGet;
 2835 
 2836     preprocData.geoIpAddressLookup = &geoIpAddressLookup;
 2837     preprocData.registerGeoIpAddressLookup = &registerGeoIpAddressLookup;
 2838     preprocData.updateSSLSSnLogData = &updateSSLSSnLogData;
 2839     preprocData.registerUpdateSSLSSnLogData = &registerUpdateSSLSSnLogData;
 2840     preprocData.endSSLSSnLogData = &endSSLSSnLogData;
 2841     preprocData.registerEndSSLSSnLogData = &registerEndSSLSSnLogData;
 2842     preprocData.registerGetSSLActualAction = &registerGetSSLActualAction;
 2843     preprocData.getSSLActualAction = &getSSLActualAction;
 2844     preprocData.getIntfData = &getIntfData;
 2845     preprocData.registerGetIntfData = &registerGetIntfData;
 2846     preprocData.isSSLPolicyEnabled = &DynamicIsSSLPolicyEnabled;
 2847     preprocData.setSSLPolicyEnabled = &DynamicSetSSLPolicyEnabled;
 2848     preprocData.getPerfIndicators = &GetSnortPerfIndicators;
 2849     preprocData.getPacketLatency = &GetSnortPacketLatency;
 2850     preprocData.getPacketDropPortion = &GetSnortPacketDropPortion;
 2851 
 2852     preprocData.loadAllLibs = &LoadAllLibs;
 2853     preprocData.openDynamicLibrary = &openDynamicLibrary;
 2854     preprocData.getSymbol = &getSymbol;
 2855     preprocData.closeDynamicLibrary = &CloseDynamicLibrary;
 2856 
 2857     preprocData.getHttpXffFields = &GetHttpXffFields;
 2858 
 2859 #if defined(FEAT_OPEN_APPID)
 2860     preprocData.appIdApi = &appIdApi;
 2861     preprocData.registerIsAppIdRequired = &registerIsAppIdRequired;
 2862     preprocData.unregisterIsAppIdRequired = &unregisterIsAppIdRequired;
 2863     preprocData.isAppIdRequired = &isAppIdRequired;
 2864 #endif /* defined(FEAT_OPEN_APPID) */
 2865     preprocData.isReadMode = DynamicIsReadMode;
 2866     preprocData.isTestMode = &DynamicIsTestMode;
 2867 
 2868     preprocData.getCurrentSnortConfig = GetCurrentSnortConfig;
 2869     preprocData.pkt_tracer_enabled = &pkt_trace_enabled;
 2870     preprocData.trace = trace_line;
 2871     preprocData.traceMax = MAX_TRACE_LINE;
 2872     preprocData.addPktTrace = DynamicAddPktTraceData;
 2873     preprocData.getPktTraceActionMsg = DynamicGetPktTraceActionMsg;
 2874     preprocData.setIPRepUpdateCount = DynamicSetIPRepUpdateCount;
 2875 
 2876 #if defined(DAQ_CAPA_CST_TIMEOUT)
 2877     preprocData.canGetTimeout = DynamicCanGetTimeout;
 2878     preprocData.registerGetDaqCapaTimeout = RegisterGetDaqCapaTimeout;
 2879 #endif
 2880 
 2881 #ifdef SNORT_RELOAD
 2882     preprocData.reloadAdjustRegister = DynamicReloadAdjustRegister;
 2883 #endif
 2884 
 2885 #ifdef DAQ_MODFLOW_TYPE_PRESERVE_FLOW
 2886     preprocData.setPreserveFlow = setPreserveFlow;
 2887 #endif
 2888 
 2889     preprocData.registerMemoryStatsFunc = RegisterMemoryStatsFunction;
 2890     preprocData.snortAlloc = SnortPreprocAlloc;
 2891     preprocData.snortFree = SnortPreprocFree;
 2892     preprocData.registerReputationProcessExternal = &registerReputationProcessExternal;
 2893     preprocData.reputation_process_external_ip = &_reputation_process_external_ip;
 2894     preprocData.registerReputationGetEntryCount = &registerReputationGetEntryCount;
 2895     preprocData.reputation_get_entry_count = &_reputation_get_entry_count;
 2896     preprocData.registerFtpmodeQuery = &registerFtpModeQuery;
 2897     preprocData.ftpGetMode = &ftpGetDataSessionMode;
 2898 
 2899     preprocData.setTlsHostAppId = &setTlsHostAppId;
 2900     preprocData.registerSetTlsHostAppId = &registerSetTlsHostAppId;
 2901     return InitDynamicPreprocessorPlugins(&preprocData);
 2902 }
 2903 
 2904 int InitDynamicDetectionPlugins(SnortConfig *sc)
 2905 {
 2906     DynamicDetectionPlugin *plugin;
 2907 
 2908     if (sc == NULL)
 2909         return -1;
 2910 
 2911     VerifyDetectionPluginRequirements(sc);
 2912 
 2913     plugin = sc->loadedDetectionPlugins;
 2914     while (plugin)
 2915     {
 2916         if (plugin->initFunc(sc))
 2917         {
 2918             ErrorMessage("Failed to initialize dynamic detection library: "
 2919                     "%s version %d.%d.%d\n",
 2920                     plugin->metaData.uniqueName,
 2921                     plugin->metaData.major,
 2922                     plugin->metaData.minor,
 2923                     plugin->metaData.build);
 2924 
 2925             return -1;
 2926         }
 2927 
 2928         plugin = plugin->next;
 2929     }
 2930 
 2931     return 0;
 2932 }
 2933 
 2934 int DumpDetectionLibRules(SnortConfig *sc)
 2935 {
 2936     DynamicDetectionPlugin *plugin = sc->loadedDetectionPlugins;
 2937     DumpDetectionRules ruleDumpFunc = NULL;
 2938     int retVal = 0;
 2939     int dumped = 0;
 2940 
 2941     LogMessage("Dumping dynamic rules...\n");
 2942     while (plugin)
 2943     {
 2944         ruleDumpFunc = (DumpDetectionRules) getSymbol(plugin->handle, "DumpSkeletonRules", &(plugin->metaData), NONFATAL);
 2945 
 2946         LogMessage("Dumping dynamic rules for Library %s %d.%d.%d\n",
 2947             plugin->metaData.uniqueName,
 2948             plugin->metaData.major,
 2949             plugin->metaData.minor,
 2950             plugin->metaData.build);
 2951         if (ruleDumpFunc != NULL)
 2952         {
 2953             if (ruleDumpFunc())
 2954             {
 2955                 LogMessage("Failed to dump the rules for Library %s %d.%d.%d\n",
 2956                     plugin->metaData.uniqueName,
 2957                     plugin->metaData.major,
 2958                     plugin->metaData.minor,
 2959                     plugin->metaData.build);
 2960                 dumped = 1;
 2961             }
 2962         }
 2963         plugin = plugin->next;
 2964     }
 2965     if( dumped == 0)
 2966     {
 2967         LogMessage("  Finished dumping dynamic rules.\n");
 2968     }
 2969     return retVal;
 2970 }
 2971 
 2972 int LoadDynamicPreprocessor(SnortConfig *sc, const char * const library_name, int indent)
 2973 {
 2974     DynamicPluginMeta metaData;
 2975     /* Presume here, that library name is full path */
 2976     InitPreprocessorLibFunc preprocInit;
 2977     PluginHandle handle;
 2978 
 2979     LogMessage("%sLoading dynamic preprocessor library %s... ",
 2980                indent ? "  " : "", library_name);
 2981 
 2982     handle = openDynamicLibrary(library_name, 0);
 2983     metaData.libraryPath = (char *) library_name;
 2984 
 2985     GetPluginVersion(handle, &metaData);
 2986 
 2987     /* Just to ensure that the function exists */
 2988     preprocInit = (InitPreprocessorLibFunc) getSymbol(handle, "InitializePreprocessor", &metaData, FATAL);
 2989 
 2990     if (metaData.type != TYPE_PREPROCESSOR)
 2991     {
 2992         CloseDynamicLibrary(handle);
 2993         LogMessage("failed, not a preprocessor library\n");
 2994         return 0;
 2995     }
 2996 
 2997     AddPreprocessorPlugin(handle, preprocInit, &metaData);
 2998 
 2999     LogMessage("done\n");
 3000     return 0;
 3001 }
 3002 
 3003 void LoadAllDynamicPreprocessors(SnortConfig *sc, const char * const path)
 3004 {
 3005     LogMessage("Loading all dynamic preprocessor libs from %s...\n", path);
 3006     LoadAllLibs(sc, path, LoadDynamicPreprocessor);
 3007     LogMessage("  Finished Loading all dynamic preprocessor libs from %s\n", path);
 3008 }
 3009 
 3010 void CloseDynamicPreprocessorLibs(void)
 3011 {
 3012     DynamicPreprocessorPlugin *tmpplugin, *plugin = loadedPreprocessorPlugins;
 3013     while (plugin)
 3014     {
 3015         tmpplugin = plugin->next;
 3016         CloseDynamicLibrary(plugin->handle);
 3017         free(plugin->metaData.libraryPath);
 3018         free(plugin);
 3019         plugin = tmpplugin;
 3020     }
 3021     loadedPreprocessorPlugins = NULL;
 3022 }
 3023 
 3024 void *GetNextEnginePluginVersion(void *p)
 3025 {
 3026     DynamicEnginePlugin *lib = (DynamicEnginePlugin *) p;
 3027 
 3028     if ( lib != NULL )
 3029     {
 3030         lib = lib->next;
 3031     }
 3032     else
 3033     {
 3034         lib = loadedEngines;
 3035     }
 3036 
 3037     if ( lib == NULL )
 3038     {
 3039         return lib;
 3040     }
 3041 
 3042     return (void *) lib;
 3043 }
 3044 
 3045 void *GetNextDetectionPluginVersion(SnortConfig *sc, void *p)
 3046 {
 3047     DynamicDetectionPlugin *lib = (DynamicDetectionPlugin *) p;
 3048 
 3049     if ( lib != NULL )
 3050     {
 3051         lib = lib->next;
 3052     }
 3053     else
 3054     {
 3055         lib = sc->loadedDetectionPlugins;
 3056     }
 3057 
 3058     if ( lib == NULL )
 3059     {
 3060         return lib;
 3061     }
 3062 
 3063     return (void *) lib;
 3064 }
 3065 
 3066 void *GetNextPreprocessorPluginVersion(void *p)
 3067 {
 3068     DynamicPreprocessorPlugin *lib = (DynamicPreprocessorPlugin *) p;
 3069 
 3070     if ( lib != NULL )
 3071     {
 3072         lib = lib->next;
 3073     }
 3074     else
 3075     {
 3076         lib = loadedPreprocessorPlugins;
 3077     }
 3078 
 3079     if ( lib == NULL )
 3080     {
 3081         return lib;
 3082     }
 3083 
 3084     return (void *) lib;
 3085 }
 3086 
 3087 DynamicPluginMeta *GetDetectionPluginMetaData(void *p)
 3088 {
 3089     DynamicDetectionPlugin *lib = (DynamicDetectionPlugin *) p;
 3090     DynamicPluginMeta *meta;
 3091 
 3092     meta = &(lib->metaData);
 3093 
 3094     return meta;
 3095 }
 3096 
 3097 DynamicPluginMeta *GetEnginePluginMetaData(void *p)
 3098 {
 3099     DynamicEnginePlugin *lib = (DynamicEnginePlugin *) p;
 3100     DynamicPluginMeta *meta;
 3101 
 3102     meta = &(lib->metaData);
 3103 
 3104     return meta;
 3105 }
 3106 
 3107 DynamicPluginMeta *GetPreprocessorPluginMetaData(void *p)
 3108 {
 3109     DynamicPreprocessorPlugin *lib = (DynamicPreprocessorPlugin *) p;
 3110     DynamicPluginMeta *meta;
 3111 
 3112     meta = &(lib->metaData);
 3113 
 3114     return meta;
 3115 }
 3116 
 3117 #ifdef SIDE_CHANNEL
 3118 
 3119 /*
 3120  * Dynamic Side Channel Plugin Support
 3121  */
 3122 typedef struct _DynamicSideChannelPlugin
 3123 {
 3124     PluginHandle handle;
 3125     DynamicPluginMeta metaData;
 3126     InitSideChannelLibFunc initFunc;
 3127     struct _DynamicSideChannelPlugin *next;
 3128     struct _DynamicSideChannelPlugin *prev;
 3129 } DynamicSideChannelPlugin;
 3130 
 3131 static DynamicSideChannelPlugin *loadedSideChannelPlugins = NULL;
 3132 
 3133 void AddSideChannelPlugin(PluginHandle handle,
 3134                         InitSideChannelLibFunc initFunc,
 3135                         DynamicPluginMeta *meta)
 3136 {
 3137     DynamicSideChannelPlugin *newPlugin = NULL;
 3138     newPlugin = (DynamicSideChannelPlugin *)SnortAlloc(sizeof(DynamicSideChannelPlugin));
 3139     newPlugin->handle = handle;
 3140 
 3141     if (!loadedSideChannelPlugins)
 3142     {
 3143         loadedSideChannelPlugins = newPlugin;
 3144     }
 3145     else
 3146     {
 3147         newPlugin->next = loadedSideChannelPlugins;
 3148         loadedSideChannelPlugins->prev = newPlugin;
 3149         loadedSideChannelPlugins = newPlugin;
 3150     }
 3151 
 3152     memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
 3153     newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
 3154     newPlugin->initFunc = initFunc;
 3155 }
 3156 
 3157 void RemoveSideChannelPlugin(DynamicSideChannelPlugin *plugin)
 3158 {
 3159     if (!plugin)
 3160         return;
 3161 
 3162     if (plugin == loadedSideChannelPlugins)
 3163     {
 3164         loadedSideChannelPlugins = loadedSideChannelPlugins->next;
 3165         loadedSideChannelPlugins->prev = NULL;
 3166     }
 3167     else
 3168     {
 3169         if (plugin->prev)
 3170             plugin->prev->next = plugin->next;
 3171         if (plugin->next)
 3172             plugin->next->prev = plugin->prev;
 3173     }
 3174     LogMessage("Unloading dynamic side channel library %s version %d.%d.%d\n",
 3175             plugin->metaData.uniqueName,
 3176             plugin->metaData.major,
 3177             plugin->metaData.minor,
 3178             plugin->metaData.build);
 3179     CloseDynamicLibrary(plugin->handle);
 3180     if (plugin->metaData.libraryPath != NULL)
 3181         free(plugin->metaData.libraryPath);
 3182     free(plugin);
 3183 }
 3184 
 3185 int LoadDynamicSideChannelLib(SnortConfig *sc, const char * const library_name, int indent)
 3186 {
 3187     DynamicPluginMeta metaData;
 3188     /* Presume here, that library name is full path */
 3189     InitSideChannelLibFunc sideChannelInit;
 3190     PluginHandle handle;
 3191 
 3192     LogMessage("%sLoading dynamic side channel library %s... ",
 3193                indent ? "  " : "", library_name);
 3194 
 3195     handle = openDynamicLibrary(library_name, 0);
 3196     metaData.libraryPath = (char *) library_name;
 3197 
 3198     GetPluginVersion(handle, &metaData);
 3199 
 3200     /* Just to ensure that the function exists */
 3201     sideChannelInit = (InitSideChannelLibFunc)getSymbol(handle, "InitializeSideChannel", &metaData, FATAL);
 3202 
 3203     if (!(metaData.type & TYPE_SIDE_CHANNEL))
 3204     {
 3205         CloseDynamicLibrary(handle);
 3206         LogMessage("failed, not a side channel library\n");
 3207         return 0;
 3208     }
 3209 
 3210     AddSideChannelPlugin(handle, sideChannelInit, &metaData);
 3211 
 3212     LogMessage("done\n");
 3213     return 0;
 3214 }
 3215 
 3216 void CloseDynamicSideChannelLibs(void)
 3217 {
 3218     DynamicSideChannelPlugin *tmpplugin, *plugin = loadedSideChannelPlugins;
 3219     while (plugin)
 3220     {
 3221         tmpplugin = plugin->next;
 3222         CloseDynamicLibrary(plugin->handle);
 3223         free(plugin->metaData.libraryPath);
 3224         free(plugin);
 3225         plugin = tmpplugin;
 3226     }
 3227     loadedSideChannelPlugins = NULL;
 3228 }
 3229 
 3230 void LoadAllDynamicSideChannelLibs(SnortConfig *sc, const char * const path)
 3231 {
 3232     LogMessage("Loading all dynamic side channel libs from %s...\n", path);
 3233     LoadAllLibs(sc, path, LoadDynamicSideChannelLib);
 3234     LogMessage("  Finished Loading all dynamic side channel libs from %s\n", path);
 3235 }
 3236 
 3237 int InitDynamicSideChannelPlugins(void)
 3238 {
 3239     DynamicSideChannelPlugin *plugin;
 3240     DynamicSideChannelData sideChannelData;
 3241 
 3242     RemoveDuplicateSideChannelPlugins();
 3243 
 3244     sideChannelData.version = SIDE_CHANNEL_DATA_VERSION;
 3245     sideChannelData.size = sizeof(DynamicSideChannelData);
 3246     sideChannelData.registerModule = &RegisterSideChannelModule;
 3247     sideChannelData.registerRXHandler = &SideChannelRegisterRXHandler;
 3248     sideChannelData.registerTXHandler = &SideChannelRegisterTXHandler;
 3249     sideChannelData.unregisterRXHandler = &SideChannelUnregisterRXHandler;
 3250     sideChannelData.unregisterTXHandler = &SideChannelUnregisterTXHandler;
 3251     sideChannelData.allocMessageRX = &SideChannelPreallocMessageRX;
 3252     sideChannelData.allocMessageTX = &SideChannelPreallocMessageTX;
 3253     sideChannelData.discardMessageRX = &SideChannelDiscardMessageRX;
 3254     sideChannelData.discardMessageTX = &SideChannelDiscardMessageTX;
 3255     sideChannelData.enqueueMessageRX = &SideChannelEnqueueMessageRX;
 3256     sideChannelData.enqueueMessageTX = &SideChannelEnqueueMessageTX;
 3257     sideChannelData.enqueueDataRX = &SideChannelEnqueueDataRX;
 3258     sideChannelData.enqueueDataTX = &SideChannelEnqueueDataTX;
 3259 
 3260     sideChannelData.getSnortInstance = &DynamicGetSnortInstance;
 3261     sideChannelData.snortSignalMask = &DynamicSnortSignalMask;
 3262 
 3263     sideChannelData.logMsg = &LogMessage;
 3264     sideChannelData.errMsg = &ErrorMessage;
 3265     sideChannelData.fatalMsg = &FatalError;
 3266     sideChannelData.debugMsg = &DebugMessageFunc;
 3267 
 3268     plugin = loadedSideChannelPlugins;
 3269     while (plugin)
 3270     {
 3271         if (plugin->initFunc(&sideChannelData))
 3272         {
 3273             ErrorMessage("Failed to initialize dynamic side channel library: %s version %d.%d.%d\n",
 3274                     plugin->metaData.uniqueName,
 3275                     plugin->metaData.major,
 3276                     plugin->metaData.minor,
 3277                     plugin->metaData.build);
 3278 
 3279             return -1;
 3280         }
 3281 
 3282         plugin = plugin->next;
 3283     }
 3284 
 3285     return 0;
 3286 }
 3287 
 3288 void *GetNextSideChannelPluginVersion(void *p)
 3289 {
 3290     DynamicSideChannelPlugin *lib = (DynamicSideChannelPlugin *) p;
 3291 
 3292     if (lib != NULL)
 3293         lib = lib->next;
 3294     else
 3295         lib = loadedSideChannelPlugins;
 3296 
 3297     if (lib == NULL)
 3298         return lib;
 3299 
 3300     return (void *) lib;
 3301 }
 3302 
 3303 DynamicPluginMeta *GetSideChannelPluginMetaData(void *p)
 3304 {
 3305     DynamicSideChannelPlugin *lib = (DynamicSideChannelPlugin *) p;
 3306     DynamicPluginMeta *meta;
 3307 
 3308     meta = &(lib->metaData);
 3309 
 3310     return meta;
 3311 }
 3312 
 3313 void RemoveDuplicateSideChannelPlugins(void)
 3314 {
 3315     int removed = 0;
 3316     DynamicSideChannelPlugin *lib1 = NULL;
 3317     DynamicSideChannelPlugin *lib2 = NULL;
 3318     DynamicPluginMeta *meta1;
 3319     DynamicPluginMeta *meta2;
 3320 
 3321     /* Side Channel Plugins */
 3322     do
 3323     {
 3324         removed = 0;
 3325         lib1 = loadedSideChannelPlugins;
 3326         while (lib1 != NULL)
 3327         {
 3328             lib2 = loadedSideChannelPlugins;
 3329             while (lib2 != NULL)
 3330             {
 3331                 /* Obviously, the same ones will be the same */
 3332                 if (lib1 != lib2)
 3333                 {
 3334                     meta1 = &lib1->metaData;
 3335                     meta2 = &lib2->metaData;
 3336                     if (!strcmp(meta1->uniqueName, meta2->uniqueName))
 3337                     {
 3338                         /* Uh, same uniqueName. */
 3339                         if ((meta1->major > meta2->major) ||
 3340                             ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
 3341                             ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
 3342                         {
 3343                             /* Lib1 is newer */
 3344                             RemoveSideChannelPlugin(lib2);
 3345                             removed = 1;
 3346                             break;
 3347                         }
 3348                         else if ((meta2->major > meta1->major) ||
 3349                             ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
 3350                             ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
 3351                         {
 3352                             /* Lib2 is newer */
 3353                             RemoveSideChannelPlugin(lib1);
 3354                             removed = 1;
 3355                             break;
 3356                         }
 3357                         else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
 3358                         {
 3359                             /* Duplicate */
 3360                             RemoveSideChannelPlugin(lib2);
 3361                             removed = 1;
 3362                             break;
 3363                         }
 3364                     }
 3365                 }
 3366                 /* If we removed anything, start back at the beginning */
 3367                 if (removed)
 3368                     break;
 3369                 lib2 = lib2->next;
 3370             }
 3371             /* If we removed anything, start back at the beginning */
 3372             if (removed)
 3373                 break;
 3374             lib1 = lib1->next;
 3375         }
 3376     } while (removed);
 3377 }
 3378 
 3379 #endif /* SIDE_CHANNEL */
 3380 
 3381 #ifdef SNORT_RELOAD
 3382 void AdjustSoRuleMemory(SnortConfig *new_config, SnortConfig *old_config) {
 3383     tSfPolicyId policy_id = getParserPolicy(new_config);
 3384     ada_reload_adjust_register(ada, policy_id, (void *) new_config,  "so_rule", (size_t) new_config->so_rule_memcap);
 3385 } 
 3386 
 3387 void ReloadDynamicDetectionLibs(SnortConfig *sc) 
 3388 {
 3389    uint32_t i;
 3390 
 3391    if (sc->dyn_rules != NULL)
 3392    {
 3393        /* Load the dynamic detection libs */
 3394        for (i = 0; i < sc->dyn_rules->count; i++)
 3395        {
 3396            switch (sc->dyn_rules->lib_paths[i]->ptype)
 3397            {
 3398                case PATH_TYPE__FILE:
 3399                    LoadDynamicDetectionLib(sc, sc->dyn_rules->lib_paths[i]->path, 0);
 3400                    break;
 3401 
 3402                case PATH_TYPE__DIRECTORY:
 3403                    LoadAllDynamicDetectionLibs(sc, sc->dyn_rules->lib_paths[i]->path);
 3404                    break;
 3405            }
 3406        }
 3407    }
 3408 }
 3409 #endif
 3410