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-2021 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 
CloseDynamicLibrary(PluginHandle handle)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 
getSymbol(PluginHandle handle,char * symbol,DynamicPluginMeta * meta,int fatal)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 
GetPluginVersion(PluginHandle handle,DynamicPluginMeta * meta)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 
openDynamicLibrary(const char * const library_name,int useGlobal)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 
LoadAllLibs(struct _SnortConfig * sc,const char * const path,LoadLibraryFunc loadFunc)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 
AddEnginePlugin(PluginHandle handle,InitEngineLibFunc initFunc,CompatibilityFunc compatFunc,DynamicPluginMeta * meta)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 
RemoveEnginePlugin(DynamicEnginePlugin * plugin)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 
ValidateDynamicEngines(SnortConfig * sc)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 
LoadDynamicEngineLib(SnortConfig * sc,const char * const library_name,int indent)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 
LoadAllDynamicEngineLibs(SnortConfig * sc,const char * const path)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 
CloseDynamicEngineLibs(void)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 
RemovePreprocessorPlugin(DynamicPreprocessorPlugin * plugin)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 
AddPreprocessorPlugin(PluginHandle handle,InitPreprocessorLibFunc initFunc,DynamicPluginMeta * meta)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 
AddDetectionPlugin(SnortConfig * sc,PluginHandle handle,InitDetectionLibFunc initFunc,DynamicPluginMeta * meta)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 
RemoveDetectionPlugin(SnortConfig * sc,DynamicDetectionPlugin * plugin)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 
LoadDynamicDetectionLib(SnortConfig * sc,const char * const library_name,int indent)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 
CloseDynamicDetectionLibs(SnortConfig * sc)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 
LoadAllDynamicDetectionLibs(SnortConfig * sc,const char * const path)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 
RemoveDuplicateEngines(void)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 
RemoveDuplicateDetectionPlugins(SnortConfig * sc)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 
RemoveDuplicatePreprocessorPlugins(void)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 
VerifyDetectionPluginRequirements(SnortConfig * sc)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 
InitDynamicEnginePlugins(DynamicEngineData * info)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 
SoRuleMemInUse()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 
DynamicRuleDataAlloc(size_t size)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 
DynamicRuleDataFree(void * data)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 
DynamicRuleDataFreeSession(void * data)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 
DynamicSetRuleData(void * p,const RuleInformation * info,void * data,void * compression_data)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 
DynamicGetRuleData(void * p,const RuleInformation * info,void ** p_data,void ** p_compression_data)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 
pcreCompile(const char * pattern,int options,const char ** errptr,int * erroffset,const unsigned char * tableptr)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 
pcreStudy(struct _SnortConfig * sc,const void * code,int options,const char ** errptr)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  */
pcreOvectorInfo(int ** ovector,int * ovector_size)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 
pcreExec(const void * code,const void * extra,const char * subj,int len,int start,int options,int * ovec,int ovecsize)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 
setFlowId(const void * p,uint32_t id)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
setPreserveFlow(const void * p)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 
getHttpBuffer(HTTP_BUFFER hb_type,unsigned * len)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 
InitDynamicEngines(char * dynamic_rules_path)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 
InitDynamicPreprocessorPlugins(DynamicPreprocessorData * info)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 *);
AddPreprocessor(struct _SnortConfig * sc,void (* pp_func)(void *,void *),uint16_t priority,uint32_t preproc_id,uint32_t proto_mask)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 
AddPreprocessorAllPolicies(struct _SnortConfig * sc,void (* pp_func)(void *,void *),uint16_t priority,uint32_t preproc_id,uint32_t proto_mask)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 *);
AddMetaEval(struct _SnortConfig * sc,void (* meta_eval_func)(int,const uint8_t *),uint16_t priority,uint32_t preproc_id)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 
AddDetection(struct _SnortConfig * sc,void (* det_func)(void *,void *),uint16_t priority,uint32_t det_id,uint32_t proto_mask)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 
AddPreprocessorCheck(struct _SnortConfig * sc,int (* pp_chk_func)(struct _SnortConfig * sc))1500 void AddPreprocessorCheck(struct _SnortConfig *sc, int (*pp_chk_func)(struct _SnortConfig *sc))
1501 {
1502     AddFuncToConfigCheckList(sc, pp_chk_func);
1503 }
1504 
DynamicDisableDetection(void * p)1505 void DynamicDisableDetection( void *p )
1506 {
1507     DisableDetect( ( Packet * ) p );
1508 }
1509 
DynamicDisableAllDetection(void * p)1510 void DynamicDisableAllDetection( void *p )
1511 {
1512     DisableAllDetect( ( Packet * ) p );
1513 }
1514 
DynamicEnableContentDetection(void)1515 void DynamicEnableContentDetection( void )
1516 {
1517     EnableContentDetect();
1518 }
1519 
DynamicDisablePacketAnalysis(void * p)1520 void DynamicDisablePacketAnalysis( void *p )
1521 {
1522     DisablePacketAnalysis( ( Packet * ) p );
1523 }
1524 
DynamicDetect(void * p)1525 int DynamicDetect(void *p)
1526 {
1527     return Detect((Packet *)p);
1528 }
1529 
DynamicEnablePreprocessor(void * p,uint32_t preprocId)1530 int DynamicEnablePreprocessor(void *p, uint32_t preprocId)
1531 {
1532     return EnablePreprocessor((Packet *)p, preprocId);
1533 }
1534 
1535 #ifdef ACTIVE_RESPONSE
DynamicActiveSetEnabled(int on_off)1536 void DynamicActiveSetEnabled(int on_off)
1537 {
1538      Active_SetEnabled(on_off);
1539 }
1540 #endif
1541 
DynamicGetRuleClassByName(char * name)1542 void *DynamicGetRuleClassByName(char *name)
1543 {
1544     return (void *)ClassTypeLookupByType(snort_conf, name);
1545 }
1546 
DynamicGetRuleClassById(int id)1547 void *DynamicGetRuleClassById(int id)
1548 {
1549     return (void *)ClassTypeLookupById(snort_conf, id);
1550 }
1551 
DynamicRegisterPreprocessorProfile(const char * keyword,void * stats,int layer,void * parent,PreprocStatsNodeFreeFunc freefn)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 
DynamicProfilingPreprocs(void)1559 int DynamicProfilingPreprocs(void)
1560 {
1561 #ifdef PERF_PROFILING
1562     return ScProfilePreprocs();
1563 #else
1564     return 0;
1565 #endif
1566 }
1567 
DynamicPreprocess(void * packet)1568 int DynamicPreprocess(void *packet)
1569 {
1570     return Preprocess( ( Packet * ) packet );
1571 }
1572 
DynamicDisablePreprocessors(void * p)1573 void DynamicDisablePreprocessors(void *p)
1574 {
1575     DisableAppPreprocessors( ( Packet * ) p );
1576 }
1577 
DynamicIP6Build(void * p,const void * hdr,int family)1578 void DynamicIP6Build(void *p, const void *hdr, int family)
1579 {
1580     sfiph_build((Packet *)p, hdr, family);
1581 }
1582 
DynamicIP6SetCallbacks(void * p,int family,char orig)1583 static inline void DynamicIP6SetCallbacks(void *p, int family, char orig)
1584 {
1585     set_callbacks((Packet *)p, family, orig);
1586 }
1587 
DynamicSnortEventqLog(void * p)1588 int DynamicSnortEventqLog(void *p)
1589 {
1590     return SnortEventqLog(snort_conf->event_queue, (Packet *)p);
1591 }
1592 
DynamicGetParserPolicy(struct _SnortConfig * sc)1593 tSfPolicyId DynamicGetParserPolicy(struct _SnortConfig *sc)
1594 {
1595     return getParserPolicy(sc);
1596 }
1597 
DynamicGetNapRuntimePolicy(void)1598 tSfPolicyId DynamicGetNapRuntimePolicy(void)
1599 {
1600     return getNapRuntimePolicy();
1601 }
1602 
DynamicGetIpsRuntimePolicy(void)1603 tSfPolicyId DynamicGetIpsRuntimePolicy(void)
1604 {
1605     return getIpsRuntimePolicy();
1606 }
1607 
DynamicGetDefaultPolicy(void)1608 tSfPolicyId DynamicGetDefaultPolicy(void)
1609 {
1610     return getDefaultPolicy();
1611 }
1612 
DynamicGetPolicyFromId(uint16_t id)1613 tSfPolicyId DynamicGetPolicyFromId(uint16_t id)
1614 {
1615     return sfPolicyIdGetBinding(snort_conf->policy_config, id);
1616 }
1617 
DynamicChangeNapRuntimePolicy(tSfPolicyId new_id,void * scb)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 
DynamicChangeIpsRuntimePolicy(tSfPolicyId new_id,void * p)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 
DynamicAddPktTraceData(int module,int strLen)1633 static void DynamicAddPktTraceData(int module, int strLen)
1634 {
1635     addPktTraceData(module, strLen);
1636 }
1637 
DynamicGetPktTraceActionMsg()1638 static const char* DynamicGetPktTraceActionMsg()
1639 {
1640     return getPktTraceActMsg();
1641 }
1642 
DynamicEncodeNew(void)1643 static void* DynamicEncodeNew (void)
1644 {
1645     return (void*)Encode_New();
1646 }
1647 
DynamicEncodeDelete(void * p)1648 static void DynamicEncodeDelete (void *p)
1649 {
1650     Encode_Delete((Packet*)p);
1651 }
1652 
DynamicNewGrinderPkt(void * p,void * phdr,uint8_t * pkt)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 
DynamicDeleteGrinderPkt(void * p)1658 static void DynamicDeleteGrinderPkt(void *p)
1659 {
1660     DeleteGrinderPkt((Packet*)p);
1661 }
1662 
DynamicEncodeFormat(uint32_t f,const void * p,void * c,int t)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 
DynamicEncodeUpdate(void * p)1668 static void DynamicEncodeUpdate (void* p)
1669 {
1670     Encode_Update((Packet*)p);
1671 }
1672 
1673 #ifdef ACTIVE_RESPONSE
DynamicSendBlockResponseMsg(void * p,const uint8_t * buffer,uint32_t buffer_len,unsigned flags)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 
DynamicActiveResponseMsg(void * p,const uint8_t * buf,uint32_t blen,unsigned flags)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 }
DynamicActiveInjectData(void * p,uint32_t flags,const uint8_t * buf,uint32_t blen)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 
DynamicActiveSendForwardReset(void * p)1701 void DynamicActiveSendForwardReset(void *p)
1702 {
1703     Active_SendReset((Packet *)p, ENC_FLAG_FWD);
1704 }
1705 
DynamicActiveQueueResponse(Active_ResponseFunc cb,void * data)1706 int DynamicActiveQueueResponse( Active_ResponseFunc cb, void *data )
1707 {
1708     return Active_QueueResponse( cb, data );
1709 }
1710 
1711 #endif
1712 
DynamicDropPacket(void * p)1713 void DynamicDropPacket(void *p)
1714 {
1715     Active_DropPacket((Packet*)p);
1716 }
1717 
DynamicRetryPacket(void * p)1718 bool DynamicRetryPacket(void *p)
1719 {
1720     return Active_DAQRetryPacket( ( Packet * ) p );
1721 }
1722 
DynamicActivePacketWasDropped(void)1723 bool DynamicActivePacketWasDropped(void)
1724 {
1725     return Active_PacketWasDropped();
1726 }
1727 
DynamicForceDropPacket(void * p)1728 void DynamicForceDropPacket(void *p)
1729 {
1730     Active_ForceDropPacket( );
1731 }
1732 
DynamicDropSessionAndReset(void * p)1733 void DynamicDropSessionAndReset(void *p)
1734 {
1735     Active_DropSession((Packet*)p);
1736 }
1737 
DynamicForceDropSession(void * p)1738 void DynamicForceDropSession(void *p)
1739 {
1740     Active_ForceDropSession();
1741 }
1742 
DynamicForceDropSessionAndReset(void * p)1743 void DynamicForceDropSessionAndReset(void *p)
1744 {
1745     Active_ForceDropResetAction((Packet *)p);
1746 }
1747 
1748 
DynamicSetParserPolicy(SnortConfig * sc,tSfPolicyId id)1749 void DynamicSetParserPolicy(SnortConfig *sc, tSfPolicyId id)
1750 {
1751     setParserPolicy(sc, id);
1752 }
1753 
DynamicSetFileDataPtr(uint8_t * ptr,uint16_t decode_size)1754 void DynamicSetFileDataPtr(uint8_t *ptr, uint16_t decode_size)
1755 {
1756     setFileDataPtr((const uint8_t*)ptr, decode_size);
1757 }
1758 
DynamicDetectResetPtr(uint8_t * ptr,uint16_t decode_size)1759 void DynamicDetectResetPtr(uint8_t *ptr, uint16_t decode_size)
1760 {
1761     DetectReset(ptr, decode_size);
1762 }
1763 
1764 
DynamicSetAltDecode(uint16_t altLen)1765 void DynamicSetAltDecode(uint16_t altLen)
1766 {
1767     SetAltDecode(altLen);
1768 }
1769 
DynamicGetNapInlineMode(void)1770 int DynamicGetNapInlineMode(void)
1771 {
1772     return ScNapInlineMode();
1773 }
1774 
DynamicGetIpsInlineMode(void)1775 int DynamicGetIpsInlineMode(void)
1776 {
1777     return ScIpsInlineMode();
1778 }
1779 
DynamicSnortStrtol(const char * nptr,char ** endptr,int base)1780 long DynamicSnortStrtol(const char *nptr, char **endptr, int base)
1781 {
1782     return SnortStrtol(nptr,endptr,base);
1783 }
1784 
DynamicSnortStrtoul(const char * nptr,char ** endptr,int base)1785 unsigned long DynamicSnortStrtoul(const char *nptr, char **endptr, int base)
1786 {
1787     return SnortStrtoul(nptr,endptr,base);
1788 }
1789 
DynamicSnortStrnStr(const char * s,int slen,const char * accept)1790 const char *DynamicSnortStrnStr(const char *s, int slen, const char *accept)
1791 {
1792     return SnortStrnStr(s, slen, accept);
1793 }
1794 
1795 
DynamicSnortStrcasestr(const char * s,int slen,const char * accept)1796 const char *DynamicSnortStrcasestr(const char *s, int slen, const char *accept)
1797 {
1798     return SnortStrcasestr(s, slen, accept);
1799 }
1800 
DynamicSnortStrncpy(char * dst,const char * src,size_t dst_size)1801 int DynamicSnortStrncpy(char *dst, const char *src, size_t dst_size)
1802 {
1803     return SnortStrncpy(dst, src, dst_size);
1804 }
1805 
DynamicSnortStrnPbrk(const char * s,int slen,const char * accept)1806 const char *DynamicSnortStrnPbrk(const char *s, int slen, const char *accept)
1807 {
1808     return SnortStrnPbrk(s, slen, accept);
1809 }
1810 
DynamicEvalRTN(void * rtn,void * p,int check_ports)1811 int DynamicEvalRTN(void *rtn, void *p, int check_ports)
1812 {
1813     return fpEvalRTN((RuleTreeNode *)rtn, (Packet *)p, check_ports);
1814 }
1815 
DynamicGetLogDirectory(void)1816 char *DynamicGetLogDirectory(void)
1817 {
1818     return SnortStrdup(snort_conf->log_dir);
1819 }
1820 
DynamicGetSnortInstance(void)1821 uint32_t DynamicGetSnortInstance(void)
1822 {
1823     return (snort_conf->event_log_id >> 16);
1824 }
1825 
DynamicIsPafEnabled(void)1826 bool DynamicIsPafEnabled(void)
1827 {
1828     return ScPafEnabled();
1829 }
1830 
DynamicIsReadMode(void)1831 bool DynamicIsReadMode(void)
1832 {
1833     return ScReadMode();
1834 }
1835 
DynamicPktTime(void)1836 time_t DynamicPktTime(void)
1837 {
1838     return packet_time();
1839 }
1840 
DynamicGetPktTimeOfDay(struct timeval * tv)1841 void DynamicGetPktTimeOfDay(struct timeval *tv)
1842 {
1843     packet_gettimeofday(tv);
1844 }
1845 
1846 #ifdef SIDE_CHANNEL
DynamicIsSCEnabled(void)1847 bool DynamicIsSCEnabled(void)
1848 {
1849     return ScSideChannelEnabled();
1850 }
1851 
DynamicSCRegisterRXHandler(uint16_t type,SCMProcessMsgFunc processMsgFunc,void * data)1852 int DynamicSCRegisterRXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data)
1853 {
1854     return SideChannelRegisterRXHandler(type, processMsgFunc, data);
1855 }
1856 
DynamicSCPreallocMessageTX(uint32_t length,SCMsgHdr ** hdr_ptr,uint8_t ** msg_ptr,void ** msg_handle)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 
DynamicSCEnqueueMessageTX(SCMsgHdr * hdr,const uint8_t * msg,uint32_t length,void * msg_handle,SCMQMsgFreeFunc msgFreeFunc)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 
DynamicCanWhitelist(void)1868 int DynamicCanWhitelist(void)
1869 {
1870     return DAQ_CanWhitelist();
1871 }
1872 
1873 #if defined(DAQ_CAPA_CST_TIMEOUT)
DynamicCanGetTimeout(void)1874 bool DynamicCanGetTimeout(void)
1875 {
1876      return Daq_Capa_Timeout;
1877 }
1878 #endif
1879 
DynamicSnortIsStrEmpty(const char * s)1880 int DynamicSnortIsStrEmpty(const char *s)
1881 {
1882     return IsEmptyStr((char*)s);
1883 }
1884 
DynamicDisableAllPolicies(struct _SnortConfig * sc)1885 static void DynamicDisableAllPolicies(struct _SnortConfig *sc)
1886 {
1887     DisableAllPolicies(sc);
1888 }
1889 
DynamicReenablePreprocBitFunc(struct _SnortConfig * sc,unsigned int preproc_id)1890 static int DynamicReenablePreprocBitFunc(struct _SnortConfig *sc, unsigned int preproc_id)
1891 {
1892     return ReenablePreprocBit(sc, preproc_id);
1893 }
1894 
1895 #ifdef SIDE_CHANNEL
DynamicSnortSignalMask(void)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 
registerSslAppIdLookup(SslAppIdLookupFunc fnptr)1923 static void registerSslAppIdLookup(SslAppIdLookupFunc fnptr)
1924 {
1925     sslAppIdLookupFnPtr = fnptr;
1926 }
1927 
sslAppIdLookup(void * ssnptr,const char * serverName,const char * commonName,int32_t * serviceAppId,int32_t * clientAppId,int32_t * payloadAppId)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 
registerSetTlsHostAppId(SetTlsHostAppIdFunc fnptr)1937 static void registerSetTlsHostAppId(SetTlsHostAppIdFunc fnptr)
1938 {
1939     setTlsHostAppIdFnPtr = fnptr;
1940 }
1941 
setTlsHostAppId(void * ssnptr,const char * serverName,const char * commonName,const char * orgName,const char * subjectAltName,bool isSniMismatch,int32_t * serviceAppId,int32_t * clientAppId,int32_t * payloadAppId)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 
registerGetAppId(GetAppIdFunc fnptr)1952 static void registerGetAppId(GetAppIdFunc fnptr)
1953 {
1954     getAppIdFnPtr = fnptr;
1955 }
1956 
getAppId(void * ssnptr)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 
registerReputationGetEntryCount(ReputationGetEntryCountFunc entryCountFn)1977 void registerReputationGetEntryCount(ReputationGetEntryCountFunc entryCountFn)
1978 {
1979     reputatinGetEntryCountFnPtr = entryCountFn;
1980 }
1981 
registerReputationProcessExternal(ReputationProcessExternalIpFunc extProcessFn)1982 void registerReputationProcessExternal(ReputationProcessExternalIpFunc extProcessFn)
1983 {
1984     reputationProcessExternalIpFnPtr = extProcessFn;
1985 }
1986 
_reputation_get_entry_count(void)1987 static int _reputation_get_entry_count(void)
1988 {
1989     if(reputatinGetEntryCountFnPtr)
1990         return (reputatinGetEntryCountFnPtr());
1991     return 0;
1992 }
1993 
_reputation_process_external_ip(void * p,sfaddr_t * ip)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 
registerUrlQuery(UrlQueryCreateFunc createFn,UrlQueryDestroyFunc destroyFn,UrlQueryMatchFunc matchFn)2003 void registerUrlQuery(UrlQueryCreateFunc createFn, UrlQueryDestroyFunc destroyFn, UrlQueryMatchFunc matchFn)
2004 {
2005     urlQueryCreateFnPtr = createFn;
2006     urlQueryDestroyFnPtr = destroyFn;
2007     urlQueryMatchFnPtr = matchFn;
2008 }
urlQueryCreate(const char * url)2009 static struct urlQueryContext* urlQueryCreate(const char *url)
2010 {
2011     if (urlQueryCreateFnPtr)
2012     {
2013         return ((urlQueryCreateFnPtr)(url));
2014     }
2015 
2016     return NULL;
2017 }
urlQueryDestroy(struct urlQueryContext * context)2018 static void urlQueryDestroy(struct urlQueryContext *context)
2019 {
2020     if (urlQueryDestroyFnPtr)
2021         (urlQueryDestroyFnPtr)(context);
2022 }
urlQueryMatch(void * ssnptr,struct urlQueryContext * context,uint16_t inUrlCat,uint16_t inUrlMinRep,uint16_t inUrlMaxRep)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
RegisterGetDaqCapaTimeout(GetDaqCapaTimeOutFunc timeoutFn)2031 void RegisterGetDaqCapaTimeout(GetDaqCapaTimeOutFunc timeoutFn)
2032 {
2033      getDaqCapaTimeoutFnPtr = timeoutFn;
2034 }
2035 #endif
2036 
registerUserGroupIdGet(UserGroupIdGetFunc userIdFn)2037 static void registerUserGroupIdGet(UserGroupIdGetFunc userIdFn)
2038 {
2039     userGroupIdGetFnPtr = userIdFn;
2040 }
2041 
userGroupIdGet(void * ssnptr,uint32_t * userId,uint32_t * realmId,unsigned * groupIdArray,unsigned groupIdArrayLen)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 
registerGeoIpAddressLookup(GeoIpAddressLookupFunc fn)2049 static void registerGeoIpAddressLookup(GeoIpAddressLookupFunc fn)
2050 {
2051     geoIpAddressLookupFnPtr = fn;
2052 }
geoIpAddressLookup(const sfaddr_t * snortIp,uint16_t * geo)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 
registerGetIntfData(GetIntfDataFunc fn)2060 static void registerGetIntfData(GetIntfDataFunc fn)
2061 {
2062     getIntfDataFnPtr = fn;
2063 }
2064 
getIntfData(void * ssnptr,int32_t * ingressIntfIndex,int32_t * egressIntfIndex,int32_t * ingressZoneIndex,int32_t * egressZoneIndex)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 
registerUpdateSSLSSnLogData(UpdateSSLSSnLogDataFunc fn)2074 static void registerUpdateSSLSSnLogData(UpdateSSLSSnLogDataFunc fn)
2075 {
2076     updateSSLSSnLogDataFnPtr = fn;
2077 }
2078 
updateSSLSSnLogData(void * ssnptr,uint8_t logging_on,uint8_t action_is_block,const char * ssl_cert_fingerprint,uint32_t ssl_cert_fingerprint_len,uint32_t ssl_cert_status,uint8_t * ssl_policy_id,uint32_t ssl_policy_id_len,uint32_t ssl_rule_id,uint16_t ssl_cipher_suite,uint8_t ssl_version,uint16_t ssl_actual_action,uint16_t ssl_expected_action,uint32_t ssl_url_category,uint16_t ssl_flow_status,uint32_t ssl_flow_error,uint32_t ssl_flow_messages,uint64_t ssl_flow_flags,char * ssl_server_name,uint8_t * ssl_session_id,uint8_t session_id_len,uint8_t * ssl_ticket_id,uint8_t ticket_id_len)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 
registerGetSSLActualAction(GetSSLActualActionFunc fn)2098 static void registerGetSSLActualAction(GetSSLActualActionFunc fn)
2099 {
2100     getSSLActualActionFnPtr = fn;
2101 }
2102 
getSSLActualAction(void * ssnptr,uint16_t * action)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 
registerEndSSLSSnLogData(EndSSLSSnLogDataFunc fn)2114 static void registerEndSSLSSnLogData(EndSSLSSnLogDataFunc fn)
2115 {
2116     endSSLSSnLogDataFnPtr = fn;
2117 }
2118 
endSSLSSnLogData(void * ssnptr,uint32_t ssl_flow_messages,uint64_t ssl_flow_flags)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 }
DynamicReadyForProcess(void * pkt)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 
DynamicSetSSLCallback(void * p)2136 void DynamicSetSSLCallback(void *p)
2137 {
2138     SetSSLCallback(p);
2139 }
2140 
DynamicGetSSLCallback(void)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 */
DynamicIsSSLPolicyEnabled(struct _SnortConfig * sc)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 
DynamicSetSSLPolicyEnabled(struct _SnortConfig * sc,tSfPolicyId policy,bool value)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;
registerFtpModeQuery(ftpGetModefunc fnptr)2174 void registerFtpModeQuery(ftpGetModefunc fnptr)
2175 {
2176     if (!ftpGetDataModefnptr)
2177         ftpGetDataModefnptr = fnptr;
2178 }
2179 
ftpGetDataSessionMode(void * ssnptr)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
DynamicReloadAdjustRegister(SnortConfig * sc,const char * raName,tSfPolicyId raPolicyId,ReloadAdjustFunc raFunc,void * raUserData,ReloadAdjustUserFreeFunc raUserFreeFunc)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 
registerIsAppIdRequired(IsAppIdRequiredFunc fn)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 
unregisterIsAppIdRequired(IsAppIdRequiredFunc fn)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 
isAppIdRequired(void)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 
dummyGetApplicationName(int32_t appId)2297 static const char *dummyGetApplicationName(int32_t appId)
2298 {
2299     return NULL;
2300 }
2301 
dummyGetApplicationId(const char * appName)2302 static tAppId dummyGetApplicationId(const char *appName)
2303 {
2304     return 0;
2305 }
2306 
dummyAppIdFFromAppIdData(struct AppIdData * session)2307 static tAppId dummyAppIdFFromAppIdData(struct AppIdData *session)
2308 {
2309     return 0;
2310 }
2311 
dummyAppIdMultiPayload(struct AppIdData * session)2312 static SFGHASH* dummyAppIdMultiPayload(struct AppIdData *session)
2313 {
2314     return NULL;
2315 }
2316 
dummyCheckAppIdData(struct AppIdData * session)2317 static bool dummyCheckAppIdData(struct AppIdData *session)
2318 {
2319     return false;
2320 }
2321 
dummyGetUserName(struct AppIdData * session,tAppId * service,bool * isLoginSuccessful)2322 static char *dummyGetUserName(struct AppIdData *session, tAppId *service, bool *isLoginSuccessful)
2323 {
2324     return NULL;
2325 }
2326 
dummyGetClientVersion(struct AppIdData * session)2327 static char *dummyGetClientVersion(struct AppIdData *session)
2328 {
2329     return NULL;
2330 }
2331 
dummyGetAppIdSessionAttribute(struct AppIdData * session,uint64_t flag)2332 static uint64_t dummyGetAppIdSessionAttribute(struct AppIdData *session, uint64_t flag)
2333 {
2334     return 0;
2335 }
2336 
dummyGetFlowType(struct AppIdData * appIdData)2337 static APPID_FLOW_TYPE dummyGetFlowType(struct AppIdData *appIdData)
2338 {
2339     return APPID_FLOW_TYPE_IGNORE;
2340 }
2341 
dummyGetServiceInfo(struct AppIdData * appIdData,char ** serviceVendor,char ** serviceVersion,RNAServiceSubtype ** serviceSubtype)2342 static void dummyGetServiceInfo(struct AppIdData *appIdData, char **serviceVendor, char **serviceVersion, RNAServiceSubtype **serviceSubtype)
2343 {
2344 }
2345 
dummyGetServicePort(struct AppIdData * appIdData)2346 static short dummyGetServicePort(struct AppIdData *appIdData)
2347 {
2348     return 0;
2349 }
2350 
dummyIpFromAppIdData(struct AppIdData * appIdData)2351 static sfaddr_t *dummyIpFromAppIdData(struct AppIdData *appIdData)
2352 {
2353     return NULL;
2354 }
2355 
dummyGetInitiatorIp(struct AppIdData * appIdData)2356 static struct in6_addr *dummyGetInitiatorIp(struct AppIdData *appIdData)
2357 {
2358     return NULL;
2359 }
2360 
dummyStringFromAppIdData(struct AppIdData * appIdData)2361 static char *dummyStringFromAppIdData(struct AppIdData *appIdData)
2362 {
2363     return NULL;
2364 }
2365 
dummyIndexedStringFromAppIdData(struct AppIdData * appIdData,HTTP_FIELD_ID fieldId)2366 static char *dummyIndexedStringFromAppIdData(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
2367 {
2368     return NULL;
2369 }
2370 
dummyFreeIndexedStringFromAppIdData(struct AppIdData * appIdData,HTTP_FIELD_ID fieldId)2371 static void dummyFreeIndexedStringFromAppIdData(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
2372 {
2373     return;
2374 }
2375 
dummyGetHttpFieldOffset(struct AppIdData * appIdData,HTTP_FIELD_ID fieldId)2376 static uint16_t dummyGetHttpFieldOffset(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
2377 {
2378     return 0;
2379 }
2380 
dummySearchTypeFromAppIdData(struct AppIdData * appIdData)2381 static SEARCH_SUPPORT_TYPE dummySearchTypeFromAppIdData(struct AppIdData *appIdData)
2382 {
2383     return NOT_A_SEARCH_ENGINE;
2384 }
2385 
dummyOffsetFromAppIdData(struct AppIdData * appIdData)2386 static uint16_t dummyOffsetFromAppIdData(struct AppIdData *appIdData)
2387 {
2388     return 0;
2389 }
2390 
dummyGetDhcpFpData(struct AppIdData * appIdData)2391 static DhcpFPData *dummyGetDhcpFpData(struct AppIdData *appIdData)
2392 {
2393     return NULL;
2394 }
2395 
dummyFreeDhcpFpData(struct AppIdData * session,DhcpFPData * data)2396 static void dummyFreeDhcpFpData(struct AppIdData *session, DhcpFPData *data)
2397 {
2398 }
2399 
dummyGetDhcpInfo(struct AppIdData * session)2400 static DHCPInfo *dummyGetDhcpInfo(struct AppIdData *session)
2401 {
2402     return NULL;
2403 }
2404 
dummyFreeDhcpInfo(struct AppIdData * session,DHCPInfo * data)2405 static void dummyFreeDhcpInfo(struct AppIdData *session, DHCPInfo *data)
2406 {
2407 }
2408 
dummyGetSmbFpData(struct AppIdData * session)2409 static FpSMBData *dummyGetSmbFpData(struct AppIdData *session)
2410 {
2411     return NULL;
2412 }
2413 
dummyFreeSmbFpData(struct AppIdData * session,FpSMBData * data)2414 static void dummyFreeSmbFpData(struct AppIdData *session, FpSMBData *data)
2415 {
2416 }
2417 
dummyGetNetbiosName(struct AppIdData * session)2418 static char *dummyGetNetbiosName(struct AppIdData *session)
2419 {
2420     return NULL;
2421 }
2422 
dummyProduceHAState(void * lwssn,uint8_t * buf)2423 static uint32_t dummyProduceHAState(void *lwssn, uint8_t *buf)
2424 {
2425     return 0;
2426 }
2427 
dummyConsumeHAState(void * lwssn,const uint8_t * buf,uint8_t length,uint8_t proto,const struct in6_addr * ip,uint16_t initiatorPort)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 
dummyGetAppIdData(void * lwssn)2433 static struct AppIdData *dummyGetAppIdData(void *lwssn)
2434 {
2435     return NULL;
2436 }
2437 
dummyGetAppIdSessionPacketCount(struct AppIdData * appIdData)2438 static int dummyGetAppIdSessionPacketCount(struct AppIdData * appIdData)
2439 {
2440     return 0;
2441 }
2442 
dummyGetDNSQuery(struct AppIdData * session,uint8_t * query_len,bool * got_response)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 }
dummyGetDNSOffset(struct AppIdData * session)2451 static uint16_t dummyGetDNSOffset(struct AppIdData *session)
2452 {
2453     return 0;
2454 }
dummyGetDNSRecordType(struct AppIdData * session)2455 static uint16_t dummyGetDNSRecordType(struct AppIdData *session)
2456 {
2457     return 0;
2458 }
dummyGetDNSResponseType(struct AppIdData * session)2459 static uint8_t dummyGetDNSResponseType(struct AppIdData *session)
2460 {
2461     return 0;
2462 }
dummyGetDNSTTL(struct AppIdData * session)2463 static uint32_t dummyGetDNSTTL(struct AppIdData *session)
2464 {
2465     return 0;
2466 }
2467 
dummyRemoveExpectedAppIdData(struct AppIdData * appIdData)2468 struct AppIdData* dummyRemoveExpectedAppIdData(struct AppIdData *appIdData)
2469 {
2470     return NULL;
2471 }
2472 
dummyDumpDebugHostInfo(void)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 
GetSnortPerfIndicators(void * p)2562 static int GetSnortPerfIndicators( void *p )
2563 {
2564     return( PerfIndicator_GetIndicators( (Perf_Indicator_Descriptor_p_t)p ) );
2565 }
2566 
GetSnortPacketLatency()2567 static uint32_t GetSnortPacketLatency()
2568 {
2569 #ifdef PI_PACKET_LATENCY_SUPPORT
2570     return ( GetPacketLatency() );
2571 #else
2572     return 0;
2573 #endif
2574 }
2575 
GetSnortPacketDropPortion()2576 static double GetSnortPacketDropPortion()
2577 {
2578 #ifdef PI_PACKET_DROPS_SUPPORT
2579     return ( GetPacketDropPortion() );
2580 #else
2581     return 0;
2582 #endif
2583 }
2584 
DynamicIsTestMode(void)2585 static bool DynamicIsTestMode(void)
2586 {
2587     return (ScTestMode()!= 0);
2588 }
2589 
GetCurrentSnortConfig(void)2590 static SnortConfig* GetCurrentSnortConfig(void)
2591 {
2592     return snort_conf;
2593 }
2594 
DynamicSetIPRepUpdateCount(uint8_t count)2595 static void DynamicSetIPRepUpdateCount(uint8_t count)
2596 {
2597     return setIPRepUpdateCount(count);
2598 }
2599 
ErrorMsgThrottled(void * tinfo,const char * format,...)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 
InitDynamicPreprocessors(void)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     preprocData.getCapability = &DAQ_GetCapabilities;
2877 #if defined(DAQ_CAPA_CST_TIMEOUT)
2878     preprocData.canGetTimeout = DynamicCanGetTimeout;
2879     preprocData.registerGetDaqCapaTimeout = RegisterGetDaqCapaTimeout;
2880 #endif
2881 
2882 #ifdef SNORT_RELOAD
2883     preprocData.reloadAdjustRegister = DynamicReloadAdjustRegister;
2884 #endif
2885 
2886 #ifdef DAQ_MODFLOW_TYPE_PRESERVE_FLOW
2887     preprocData.setPreserveFlow = setPreserveFlow;
2888 #endif
2889 
2890     preprocData.registerMemoryStatsFunc = RegisterMemoryStatsFunction;
2891     preprocData.snortAlloc = SnortPreprocAlloc;
2892     preprocData.snortFree = SnortPreprocFree;
2893     preprocData.registerReputationProcessExternal = &registerReputationProcessExternal;
2894     preprocData.reputation_process_external_ip = &_reputation_process_external_ip;
2895     preprocData.registerReputationGetEntryCount = &registerReputationGetEntryCount;
2896     preprocData.reputation_get_entry_count = &_reputation_get_entry_count;
2897     preprocData.registerFtpmodeQuery = &registerFtpModeQuery;
2898     preprocData.ftpGetMode = &ftpGetDataSessionMode;
2899 
2900     preprocData.setTlsHostAppId = &setTlsHostAppId;
2901     preprocData.registerSetTlsHostAppId = &registerSetTlsHostAppId;
2902     return InitDynamicPreprocessorPlugins(&preprocData);
2903 }
2904 
InitDynamicDetectionPlugins(SnortConfig * sc)2905 int InitDynamicDetectionPlugins(SnortConfig *sc)
2906 {
2907     DynamicDetectionPlugin *plugin;
2908 
2909     if (sc == NULL)
2910         return -1;
2911 
2912     VerifyDetectionPluginRequirements(sc);
2913 
2914     plugin = sc->loadedDetectionPlugins;
2915     while (plugin)
2916     {
2917         if (plugin->initFunc(sc))
2918         {
2919             ErrorMessage("Failed to initialize dynamic detection library: "
2920                     "%s version %d.%d.%d\n",
2921                     plugin->metaData.uniqueName,
2922                     plugin->metaData.major,
2923                     plugin->metaData.minor,
2924                     plugin->metaData.build);
2925 
2926             return -1;
2927         }
2928 
2929         plugin = plugin->next;
2930     }
2931 
2932     return 0;
2933 }
2934 
DumpDetectionLibRules(SnortConfig * sc)2935 int DumpDetectionLibRules(SnortConfig *sc)
2936 {
2937     DynamicDetectionPlugin *plugin = sc->loadedDetectionPlugins;
2938     DumpDetectionRules ruleDumpFunc = NULL;
2939     int retVal = 0;
2940     int dumped = 0;
2941 
2942     LogMessage("Dumping dynamic rules...\n");
2943     while (plugin)
2944     {
2945         ruleDumpFunc = (DumpDetectionRules) getSymbol(plugin->handle, "DumpSkeletonRules", &(plugin->metaData), NONFATAL);
2946 
2947         LogMessage("Dumping dynamic rules for Library %s %d.%d.%d\n",
2948             plugin->metaData.uniqueName,
2949             plugin->metaData.major,
2950             plugin->metaData.minor,
2951             plugin->metaData.build);
2952         if (ruleDumpFunc != NULL)
2953         {
2954             if (ruleDumpFunc())
2955             {
2956                 LogMessage("Failed to dump the rules for Library %s %d.%d.%d\n",
2957                     plugin->metaData.uniqueName,
2958                     plugin->metaData.major,
2959                     plugin->metaData.minor,
2960                     plugin->metaData.build);
2961                 dumped = 1;
2962             }
2963         }
2964         plugin = plugin->next;
2965     }
2966     if( dumped == 0)
2967     {
2968         LogMessage("  Finished dumping dynamic rules.\n");
2969     }
2970     return retVal;
2971 }
2972 
LoadDynamicPreprocessor(SnortConfig * sc,const char * const library_name,int indent)2973 int LoadDynamicPreprocessor(SnortConfig *sc, const char * const library_name, int indent)
2974 {
2975     DynamicPluginMeta metaData;
2976     /* Presume here, that library name is full path */
2977     InitPreprocessorLibFunc preprocInit;
2978     PluginHandle handle;
2979 
2980     LogMessage("%sLoading dynamic preprocessor library %s... ",
2981                indent ? "  " : "", library_name);
2982 
2983     handle = openDynamicLibrary(library_name, 0);
2984     metaData.libraryPath = (char *) library_name;
2985 
2986     GetPluginVersion(handle, &metaData);
2987 
2988     /* Just to ensure that the function exists */
2989     preprocInit = (InitPreprocessorLibFunc) getSymbol(handle, "InitializePreprocessor", &metaData, FATAL);
2990 
2991     if (metaData.type != TYPE_PREPROCESSOR)
2992     {
2993         CloseDynamicLibrary(handle);
2994         LogMessage("failed, not a preprocessor library\n");
2995         return 0;
2996     }
2997 
2998     AddPreprocessorPlugin(handle, preprocInit, &metaData);
2999 
3000     LogMessage("done\n");
3001     return 0;
3002 }
3003 
LoadAllDynamicPreprocessors(SnortConfig * sc,const char * const path)3004 void LoadAllDynamicPreprocessors(SnortConfig *sc, const char * const path)
3005 {
3006     LogMessage("Loading all dynamic preprocessor libs from %s...\n", path);
3007     LoadAllLibs(sc, path, LoadDynamicPreprocessor);
3008     LogMessage("  Finished Loading all dynamic preprocessor libs from %s\n", path);
3009 }
3010 
CloseDynamicPreprocessorLibs(void)3011 void CloseDynamicPreprocessorLibs(void)
3012 {
3013     DynamicPreprocessorPlugin *tmpplugin, *plugin = loadedPreprocessorPlugins;
3014     while (plugin)
3015     {
3016         tmpplugin = plugin->next;
3017         CloseDynamicLibrary(plugin->handle);
3018         free(plugin->metaData.libraryPath);
3019         free(plugin);
3020         plugin = tmpplugin;
3021     }
3022     loadedPreprocessorPlugins = NULL;
3023 }
3024 
GetNextEnginePluginVersion(void * p)3025 void *GetNextEnginePluginVersion(void *p)
3026 {
3027     DynamicEnginePlugin *lib = (DynamicEnginePlugin *) p;
3028 
3029     if ( lib != NULL )
3030     {
3031         lib = lib->next;
3032     }
3033     else
3034     {
3035         lib = loadedEngines;
3036     }
3037 
3038     if ( lib == NULL )
3039     {
3040         return lib;
3041     }
3042 
3043     return (void *) lib;
3044 }
3045 
GetNextDetectionPluginVersion(SnortConfig * sc,void * p)3046 void *GetNextDetectionPluginVersion(SnortConfig *sc, void *p)
3047 {
3048     DynamicDetectionPlugin *lib = (DynamicDetectionPlugin *) p;
3049 
3050     if ( lib != NULL )
3051     {
3052         lib = lib->next;
3053     }
3054     else
3055     {
3056         lib = sc->loadedDetectionPlugins;
3057     }
3058 
3059     if ( lib == NULL )
3060     {
3061         return lib;
3062     }
3063 
3064     return (void *) lib;
3065 }
3066 
GetNextPreprocessorPluginVersion(void * p)3067 void *GetNextPreprocessorPluginVersion(void *p)
3068 {
3069     DynamicPreprocessorPlugin *lib = (DynamicPreprocessorPlugin *) p;
3070 
3071     if ( lib != NULL )
3072     {
3073         lib = lib->next;
3074     }
3075     else
3076     {
3077         lib = loadedPreprocessorPlugins;
3078     }
3079 
3080     if ( lib == NULL )
3081     {
3082         return lib;
3083     }
3084 
3085     return (void *) lib;
3086 }
3087 
GetDetectionPluginMetaData(void * p)3088 DynamicPluginMeta *GetDetectionPluginMetaData(void *p)
3089 {
3090     DynamicDetectionPlugin *lib = (DynamicDetectionPlugin *) p;
3091     DynamicPluginMeta *meta;
3092 
3093     meta = &(lib->metaData);
3094 
3095     return meta;
3096 }
3097 
GetEnginePluginMetaData(void * p)3098 DynamicPluginMeta *GetEnginePluginMetaData(void *p)
3099 {
3100     DynamicEnginePlugin *lib = (DynamicEnginePlugin *) p;
3101     DynamicPluginMeta *meta;
3102 
3103     meta = &(lib->metaData);
3104 
3105     return meta;
3106 }
3107 
GetPreprocessorPluginMetaData(void * p)3108 DynamicPluginMeta *GetPreprocessorPluginMetaData(void *p)
3109 {
3110     DynamicPreprocessorPlugin *lib = (DynamicPreprocessorPlugin *) p;
3111     DynamicPluginMeta *meta;
3112 
3113     meta = &(lib->metaData);
3114 
3115     return meta;
3116 }
3117 
3118 #ifdef SIDE_CHANNEL
3119 
3120 /*
3121  * Dynamic Side Channel Plugin Support
3122  */
3123 typedef struct _DynamicSideChannelPlugin
3124 {
3125     PluginHandle handle;
3126     DynamicPluginMeta metaData;
3127     InitSideChannelLibFunc initFunc;
3128     struct _DynamicSideChannelPlugin *next;
3129     struct _DynamicSideChannelPlugin *prev;
3130 } DynamicSideChannelPlugin;
3131 
3132 static DynamicSideChannelPlugin *loadedSideChannelPlugins = NULL;
3133 
AddSideChannelPlugin(PluginHandle handle,InitSideChannelLibFunc initFunc,DynamicPluginMeta * meta)3134 void AddSideChannelPlugin(PluginHandle handle,
3135                         InitSideChannelLibFunc initFunc,
3136                         DynamicPluginMeta *meta)
3137 {
3138     DynamicSideChannelPlugin *newPlugin = NULL;
3139     newPlugin = (DynamicSideChannelPlugin *)SnortAlloc(sizeof(DynamicSideChannelPlugin));
3140     newPlugin->handle = handle;
3141 
3142     if (!loadedSideChannelPlugins)
3143     {
3144         loadedSideChannelPlugins = newPlugin;
3145     }
3146     else
3147     {
3148         newPlugin->next = loadedSideChannelPlugins;
3149         loadedSideChannelPlugins->prev = newPlugin;
3150         loadedSideChannelPlugins = newPlugin;
3151     }
3152 
3153     memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
3154     newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
3155     newPlugin->initFunc = initFunc;
3156 }
3157 
RemoveSideChannelPlugin(DynamicSideChannelPlugin * plugin)3158 void RemoveSideChannelPlugin(DynamicSideChannelPlugin *plugin)
3159 {
3160     if (!plugin)
3161         return;
3162 
3163     if (plugin == loadedSideChannelPlugins)
3164     {
3165         loadedSideChannelPlugins = loadedSideChannelPlugins->next;
3166         loadedSideChannelPlugins->prev = NULL;
3167     }
3168     else
3169     {
3170         if (plugin->prev)
3171             plugin->prev->next = plugin->next;
3172         if (plugin->next)
3173             plugin->next->prev = plugin->prev;
3174     }
3175     LogMessage("Unloading dynamic side channel library %s version %d.%d.%d\n",
3176             plugin->metaData.uniqueName,
3177             plugin->metaData.major,
3178             plugin->metaData.minor,
3179             plugin->metaData.build);
3180     CloseDynamicLibrary(plugin->handle);
3181     if (plugin->metaData.libraryPath != NULL)
3182         free(plugin->metaData.libraryPath);
3183     free(plugin);
3184 }
3185 
LoadDynamicSideChannelLib(SnortConfig * sc,const char * const library_name,int indent)3186 int LoadDynamicSideChannelLib(SnortConfig *sc, const char * const library_name, int indent)
3187 {
3188     DynamicPluginMeta metaData;
3189     /* Presume here, that library name is full path */
3190     InitSideChannelLibFunc sideChannelInit;
3191     PluginHandle handle;
3192 
3193     LogMessage("%sLoading dynamic side channel library %s... ",
3194                indent ? "  " : "", library_name);
3195 
3196     handle = openDynamicLibrary(library_name, 0);
3197     metaData.libraryPath = (char *) library_name;
3198 
3199     GetPluginVersion(handle, &metaData);
3200 
3201     /* Just to ensure that the function exists */
3202     sideChannelInit = (InitSideChannelLibFunc)getSymbol(handle, "InitializeSideChannel", &metaData, FATAL);
3203 
3204     if (!(metaData.type & TYPE_SIDE_CHANNEL))
3205     {
3206         CloseDynamicLibrary(handle);
3207         LogMessage("failed, not a side channel library\n");
3208         return 0;
3209     }
3210 
3211     AddSideChannelPlugin(handle, sideChannelInit, &metaData);
3212 
3213     LogMessage("done\n");
3214     return 0;
3215 }
3216 
CloseDynamicSideChannelLibs(void)3217 void CloseDynamicSideChannelLibs(void)
3218 {
3219     DynamicSideChannelPlugin *tmpplugin, *plugin = loadedSideChannelPlugins;
3220     while (plugin)
3221     {
3222         tmpplugin = plugin->next;
3223         CloseDynamicLibrary(plugin->handle);
3224         free(plugin->metaData.libraryPath);
3225         free(plugin);
3226         plugin = tmpplugin;
3227     }
3228     loadedSideChannelPlugins = NULL;
3229 }
3230 
LoadAllDynamicSideChannelLibs(SnortConfig * sc,const char * const path)3231 void LoadAllDynamicSideChannelLibs(SnortConfig *sc, const char * const path)
3232 {
3233     LogMessage("Loading all dynamic side channel libs from %s...\n", path);
3234     LoadAllLibs(sc, path, LoadDynamicSideChannelLib);
3235     LogMessage("  Finished Loading all dynamic side channel libs from %s\n", path);
3236 }
3237 
InitDynamicSideChannelPlugins(void)3238 int InitDynamicSideChannelPlugins(void)
3239 {
3240     DynamicSideChannelPlugin *plugin;
3241     DynamicSideChannelData sideChannelData;
3242 
3243     RemoveDuplicateSideChannelPlugins();
3244 
3245     sideChannelData.version = SIDE_CHANNEL_DATA_VERSION;
3246     sideChannelData.size = sizeof(DynamicSideChannelData);
3247     sideChannelData.registerModule = &RegisterSideChannelModule;
3248     sideChannelData.registerRXHandler = &SideChannelRegisterRXHandler;
3249     sideChannelData.registerTXHandler = &SideChannelRegisterTXHandler;
3250     sideChannelData.unregisterRXHandler = &SideChannelUnregisterRXHandler;
3251     sideChannelData.unregisterTXHandler = &SideChannelUnregisterTXHandler;
3252     sideChannelData.allocMessageRX = &SideChannelPreallocMessageRX;
3253     sideChannelData.allocMessageTX = &SideChannelPreallocMessageTX;
3254     sideChannelData.discardMessageRX = &SideChannelDiscardMessageRX;
3255     sideChannelData.discardMessageTX = &SideChannelDiscardMessageTX;
3256     sideChannelData.enqueueMessageRX = &SideChannelEnqueueMessageRX;
3257     sideChannelData.enqueueMessageTX = &SideChannelEnqueueMessageTX;
3258     sideChannelData.enqueueDataRX = &SideChannelEnqueueDataRX;
3259     sideChannelData.enqueueDataTX = &SideChannelEnqueueDataTX;
3260 
3261     sideChannelData.getSnortInstance = &DynamicGetSnortInstance;
3262     sideChannelData.snortSignalMask = &DynamicSnortSignalMask;
3263 
3264     sideChannelData.logMsg = &LogMessage;
3265     sideChannelData.errMsg = &ErrorMessage;
3266     sideChannelData.fatalMsg = &FatalError;
3267     sideChannelData.debugMsg = &DebugMessageFunc;
3268 
3269     plugin = loadedSideChannelPlugins;
3270     while (plugin)
3271     {
3272         if (plugin->initFunc(&sideChannelData))
3273         {
3274             ErrorMessage("Failed to initialize dynamic side channel library: %s version %d.%d.%d\n",
3275                     plugin->metaData.uniqueName,
3276                     plugin->metaData.major,
3277                     plugin->metaData.minor,
3278                     plugin->metaData.build);
3279 
3280             return -1;
3281         }
3282 
3283         plugin = plugin->next;
3284     }
3285 
3286     return 0;
3287 }
3288 
GetNextSideChannelPluginVersion(void * p)3289 void *GetNextSideChannelPluginVersion(void *p)
3290 {
3291     DynamicSideChannelPlugin *lib = (DynamicSideChannelPlugin *) p;
3292 
3293     if (lib != NULL)
3294         lib = lib->next;
3295     else
3296         lib = loadedSideChannelPlugins;
3297 
3298     if (lib == NULL)
3299         return lib;
3300 
3301     return (void *) lib;
3302 }
3303 
GetSideChannelPluginMetaData(void * p)3304 DynamicPluginMeta *GetSideChannelPluginMetaData(void *p)
3305 {
3306     DynamicSideChannelPlugin *lib = (DynamicSideChannelPlugin *) p;
3307     DynamicPluginMeta *meta;
3308 
3309     meta = &(lib->metaData);
3310 
3311     return meta;
3312 }
3313 
RemoveDuplicateSideChannelPlugins(void)3314 void RemoveDuplicateSideChannelPlugins(void)
3315 {
3316     int removed = 0;
3317     DynamicSideChannelPlugin *lib1 = NULL;
3318     DynamicSideChannelPlugin *lib2 = NULL;
3319     DynamicPluginMeta *meta1;
3320     DynamicPluginMeta *meta2;
3321 
3322     /* Side Channel Plugins */
3323     do
3324     {
3325         removed = 0;
3326         lib1 = loadedSideChannelPlugins;
3327         while (lib1 != NULL)
3328         {
3329             lib2 = loadedSideChannelPlugins;
3330             while (lib2 != NULL)
3331             {
3332                 /* Obviously, the same ones will be the same */
3333                 if (lib1 != lib2)
3334                 {
3335                     meta1 = &lib1->metaData;
3336                     meta2 = &lib2->metaData;
3337                     if (!strcmp(meta1->uniqueName, meta2->uniqueName))
3338                     {
3339                         /* Uh, same uniqueName. */
3340                         if ((meta1->major > meta2->major) ||
3341                             ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
3342                             ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
3343                         {
3344                             /* Lib1 is newer */
3345                             RemoveSideChannelPlugin(lib2);
3346                             removed = 1;
3347                             break;
3348                         }
3349                         else if ((meta2->major > meta1->major) ||
3350                             ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
3351                             ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
3352                         {
3353                             /* Lib2 is newer */
3354                             RemoveSideChannelPlugin(lib1);
3355                             removed = 1;
3356                             break;
3357                         }
3358                         else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
3359                         {
3360                             /* Duplicate */
3361                             RemoveSideChannelPlugin(lib2);
3362                             removed = 1;
3363                             break;
3364                         }
3365                     }
3366                 }
3367                 /* If we removed anything, start back at the beginning */
3368                 if (removed)
3369                     break;
3370                 lib2 = lib2->next;
3371             }
3372             /* If we removed anything, start back at the beginning */
3373             if (removed)
3374                 break;
3375             lib1 = lib1->next;
3376         }
3377     } while (removed);
3378 }
3379 
3380 #endif /* SIDE_CHANNEL */
3381 
3382 #ifdef SNORT_RELOAD
AdjustSoRuleMemory(SnortConfig * new_config,SnortConfig * old_config)3383 void AdjustSoRuleMemory(SnortConfig *new_config, SnortConfig *old_config) {
3384     tSfPolicyId policy_id = getParserPolicy(new_config);
3385     ada_reload_adjust_register(ada, policy_id, (void *) new_config,  "so_rule", (size_t) new_config->so_rule_memcap);
3386 }
3387 
ReloadDynamicDetectionLibs(SnortConfig * sc)3388 void ReloadDynamicDetectionLibs(SnortConfig *sc)
3389 {
3390    uint32_t i;
3391 
3392    if (sc->dyn_rules != NULL)
3393    {
3394        /* Load the dynamic detection libs */
3395        for (i = 0; i < sc->dyn_rules->count; i++)
3396        {
3397            switch (sc->dyn_rules->lib_paths[i]->ptype)
3398            {
3399                case PATH_TYPE__FILE:
3400                    LoadDynamicDetectionLib(sc, sc->dyn_rules->lib_paths[i]->path, 0);
3401                    break;
3402 
3403                case PATH_TYPE__DIRECTORY:
3404                    LoadAllDynamicDetectionLibs(sc, sc->dyn_rules->lib_paths[i]->path);
3405                    break;
3406            }
3407        }
3408    }
3409 }
3410 #endif
3411 
3412