1 /* $Id$ */
2 /*
3 ** Copyright (C) 2002-2009 Sourcefire, Inc.
4 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License Version 2 as
8 ** published by the Free Software Foundation.  You may not use, modify or
9 ** distribute this program under any other version of the GNU General
10 ** Public License.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 
22 /*
23  *
24  * Program: barnyard2
25  * Alot of code borrowed from snort. (all credit due)
26  *
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <unistd.h>
41 #include <string.h>
42 #include <timersub.h>
43 #include <setjmp.h>
44 #include <signal.h>
45 #include <sys/stat.h>
46 
47 #ifndef WIN32
48 #include <netdb.h>
49 #endif
50 
51 #ifdef HAVE_GETOPT_LONG
52 //#define _GNU_SOURCE
53 /* A GPL copy of getopt & getopt_long src code is now in sfutil */
54 # undef HAVE_GETOPT_LONG
55 #endif
56 #include <getopt.h>
57 
58 #ifdef TIMESTATS
59 # include <time.h>   /* added for new time stats function in util.c */
60 #endif
61 
62 #ifdef HAVE_STRINGS_H
63 # include <strings.h>
64 #endif
65 
66 #ifndef WIN32
67 # include <grp.h>
68 # include <pwd.h>
69 # include <sys/socket.h>
70 # include <netinet/in.h>
71 # include <arpa/inet.h>
72 #endif  /* !WIN32 */
73 
74 #if !defined(CATCH_SEGV) && !defined(WIN32)
75 # include <sys/resource.h>
76 #endif
77 
78 #include "decode.h"
79 #include "barnyard2.h"
80 #include "rules.h"
81 #include "plugbase.h"
82 #include "debug.h"
83 #include "util.h"
84 #include "parser.h"
85 #include "log.h"
86 #include "map.h"
87 #include "mstring.h"
88 #include "strlcpyu.h"
89 #include "output-plugins/spo_log_tcpdump.h"
90 
91 #ifdef HAVE_LIBPRELUDE
92 # include "output-plugins/spo_alert_prelude.h"
93 #endif
94 
95 /* Macros *********************************************************************/
96 #ifndef DLT_LANE8023
97 /*
98  * Old OPEN BSD Log format is 17.
99  * Define DLT_OLDPFLOG unless DLT_LANE8023 (Suse 6.3) is already
100  * defined in bpf.h.
101  */
102 # define DLT_OLDPFLOG 17
103 #endif
104 
105 /* Data types *****************************************************************/
106 typedef enum _GetOptArgType
107 {
108     LONGOPT_ARG_NONE = 0,
109     LONGOPT_ARG_REQUIRED,
110     LONGOPT_ARG_OPTIONAL
111 
112 } GetOptArgType;
113 
114 /* Globals ********************************************************************/
115 PacketCount pc;  /* packet count information */
116 
117 unsigned short stat_dropped = 0;
118 uint32_t *netmasks = NULL;   /* precalculated netmask array */
119 char **protocol_names = NULL;
120 
121 char *barnyard2_conf_file = NULL;   /* -c */
122 char *barnyard2_conf_dir = NULL;
123 
124 Barnyard2Config *barnyard2_cmd_line_conf = NULL;
125 Barnyard2Config *barnyard2_conf = NULL;
126 
127 static struct timeval starttime;
128 static struct timeval endtime;
129 
130 VarNode *cmd_line_var_list = NULL;
131 
132 int exit_signal = 0;
133 
134 static int usr_signal = 0;
135 static volatile int hup_signal = 0;
136 volatile int barnyard2_initializing = 1;
137 
138 InputConfigFuncNode  *input_config_funcs = NULL;
139 OutputConfigFuncNode *output_config_funcs = NULL;
140 
141 PluginSignalFuncNode *plugin_shutdown_funcs = NULL;
142 PluginSignalFuncNode *plugin_clean_exit_funcs = NULL;
143 PluginSignalFuncNode *plugin_restart_funcs = NULL;
144 
145 InputFuncNode *InputList = NULL;
146 OutputFuncNode *AlertList = NULL;   /* Alert function list */
147 OutputFuncNode *LogList = NULL;     /* Log function list */
148 
149 int datalink;   /* the datalink value */
150 uint32_t pcap_snaplen = SNAPLEN;
151 
152 static int exit_logged = 0;
153 
154 static int barnyard2_argc = 0;
155 static char **barnyard2_argv = NULL;
156 
157 /* command line options for getopt */
158 #ifndef WIN32
159 /* Unix does not support an argument to -s <wink marty!> OR -E, -W */
160 static char *valid_options = "?a:Ac:C:d:Def:Fg:G:h:i:Il:m:noOqr:R:S:t:Tu:UvVw:xXy";
161 #else
162 /* Win32 does not support:  -D, -g, -m, -t, -u */
163 /* Win32 no longer supports an argument to -s, either! */
164 static char *valid_options = "?a:Ac:C:d:eEf:FG:h:i:Il:noOqr:R:S:TUvVw:xXy";
165 #endif
166 
167 static struct option long_options[] =
168 {
169    {"snaplen", LONGOPT_ARG_REQUIRED, NULL, 'P'},
170    {"version", LONGOPT_ARG_NONE, NULL, 'V'},
171    {"help", LONGOPT_ARG_NONE, NULL, '?'},
172    {"conf-error-out", LONGOPT_ARG_NONE, NULL,'x'},
173    {"process-all-events", LONGOPT_ARG_NONE, NULL, PROCESS_ALL_EVENTS},
174    {"restart", LONGOPT_ARG_NONE, NULL, ARG_RESTART},
175    {"pid-path", LONGOPT_ARG_REQUIRED, NULL, PID_PATH},
176    {"create-pidfile", LONGOPT_ARG_NONE, NULL, CREATE_PID_FILE},
177    {"nolock-pidfile", LONGOPT_ARG_NONE, NULL, NOLOCK_PID_FILE},
178    {"nostamps", LONGOPT_ARG_NONE, NULL, NO_LOGGING_TIMESTAMPS},
179    {"gen-msg", LONGOPT_ARG_REQUIRED, NULL, 'G'},
180    {"sid-msg", LONGOPT_ARG_REQUIRED, NULL, 'S'},
181    {"reference", LONGOPT_ARG_REQUIRED, NULL, 'R'},
182    {"classification", LONGOPT_ARG_REQUIRED, NULL, 'C'},
183    {"disable-alert-on-each-packet-in-stream", LONGOPT_ARG_NONE, NULL, DISABLE_ALERT_ON_EACH_PACKET_IN_STREAM},
184    {"event-cache-size", LONGOPT_ARG_REQUIRED, NULL, EVENT_CACHE_SIZE},
185    {"alert-on-each-packet-in-stream", LONGOPT_ARG_NONE, NULL, ALERT_ON_EACH_PACKET_IN_STREAM},
186    {"process-new-records-only", LONGOPT_ARG_NONE, NULL, 'n'},
187 
188 #ifdef MPLS
189    {"max-mpls-labelchain-len", LONGOPT_ARG_REQUIRED, NULL, MAX_MPLS_LABELCHAIN_LEN},
190    {"mpls-payload-type", LONGOPT_ARG_REQUIRED, NULL, MPLS_PAYLOAD_TYPE},
191 #endif
192 
193    {0, 0, 0, 0}
194 };
195 
196 
197 /* Externs *******************************************************************/
198 /* for getopt */
199 extern char *optarg;
200 extern int optind;
201 extern int opterr;
202 extern int optopt;
203 
204 
205 
206 /* Private function prototypes ************************************************/
207 static void InitNetmasks(void);
208 static void InitProtoNames(void);
209 
210 static void Barnyard2Init(int, char **);
211 static void InitPidChrootAndPrivs(void);
212 static void ParseCmdLine(int, char **);
213 static int ShowUsage(char *);
214 static void PrintVersion(void);
215 static void SetBarnyard2ConfDir(void);
216 static void InitGlobals(void);
217 static Barnyard2Config * MergeBarnyard2Confs(Barnyard2Config *, Barnyard2Config *);
218 static void InitSignals(void);
219 #if defined(NOCOREFILE) && !defined(WIN32)
220 static void SetNoCores(void);
221 #endif
222 
223 static void Barnyard2Cleanup(int,int);
224 
225 static void FreeInputConfigs(InputConfig *);
226 static void FreeOutputConfigs(OutputConfig *);
227 static void FreePlugins(Barnyard2Config *);
228 
229 static void Barnyard2PostInit(void);
230 static char * ConfigFileSearch(void);
231 
232 int SignalCheck(void);
233 
234 /* Signal handler declarations ************************************************/
235 
236 static void SigExitHandler(int);
237 static void SigUsrHandler(int);
238 static void SigHupHandler(int);
239 
240 
241 /*  F U N C T I O N   D E F I N I T I O N S  **********************************/
242 
243 /*
244  *
245  * Function: main(int, char *)
246  *
247  * Purpose:  Handle program entry and exit, call main prog sections
248  *           This can handle both regular (command-line) style
249  *           startup, as well as Win32 Service style startup.
250  *
251  * Arguments: See command line args in README file
252  *
253  * Returns: 0 => normal exit, 1 => exit on error
254  *
255  */
main(int argc,char * argv[])256 int main(int argc, char *argv[])
257 {
258     barnyard2_argc = argc;
259     barnyard2_argv = argv;
260 
261     argc = 0;
262     argv = NULL;
263 
264 #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
265     /* Do some sanity checking, because some people seem to forget to
266      * put spaces between their parameters
267      */
268     if ((argc > 1) &&
269         ((_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_INSTALL_CMDLINE_PARAM)) == 0) ||
270          (_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_UNINSTALL_CMDLINE_PARAM)) == 0) ||
271          (_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_SHOW_CMDLINE_PARAM)) == 0)))
272     {
273         FatalError("You must have a space after the '%s' command-line parameter\n",
274                    SERVICE_CMDLINE_PARAM);
275     }
276 
277     /* If the first parameter is "/SERVICE", then start Snort as a Win32 service */
278     if((argc > 1) && (_stricmp(argv[1],SERVICE_CMDLINE_PARAM) == 0))
279     {
280         return Barnyard2ServiceMain(barnyard2_argc, barnyard2_argv);
281     }
282 #endif /* WIN32 && ENABLE_WIN32_SERVICE */
283 
284     return Barnyard2Main(barnyard2_argc, barnyard2_argv);
285 }
286 
287 /*
288  *
289  * Function: Barnyard2Main(int, char *)
290  *
291  * Purpose:  The real place that the program handles entry and exit.  Called
292  *           called by main(), or by Barnyard2ServiceMain().
293  *
294  * Arguments: See command line args in README file
295  *
296  * Returns: 0 => normal exit, 1 => exit on error
297  *
298  */
Barnyard2Main(int argc,char * argv[])299 int Barnyard2Main(int argc, char *argv[])
300 {
301     InitSignals();
302 
303 #if defined(NOCOREFILE) && !defined(WIN32)
304     SetNoCores();
305 #endif
306 
307 #ifdef WIN32
308     if (!init_winsock())
309         FatalError("Could not Initialize Winsock!\n");
310 #endif
311 
312 restart:
313 
314     Barnyard2Init(argc, argv);
315 
316     if (BcDaemonMode())
317     {
318         GoDaemon();
319     }
320 
321     Barnyard2PostInit();
322 
323 	/* check for waldo file usage */
324 	if (barnyard2_conf->waldo.state & WALDO_STATE_ENABLED)
325 	{
326 		int				ret;
327 
328 		ret = spoolerReadWaldo(&barnyard2_conf->waldo);
329 
330 		/* show waldo file contents on successful load */
331 		if (ret == WALDO_FILE_SUCCESS)
332 		{
333 			LogMessage("Using waldo file '%s':\n"
334 						"    spool directory = %s\n"
335 						"    spool filebase  = %s\n"
336 						"    time_stamp      = %lu\n"
337 						"    record_idx      = %lu\n",
338 						barnyard2_conf->waldo.filepath,
339 						barnyard2_conf->waldo.data.spool_dir,
340 						barnyard2_conf->waldo.data.spool_filebase,
341 						barnyard2_conf->waldo.data.timestamp,
342 						barnyard2_conf->waldo.data.record_idx);
343 		}
344 		else if (ret == WALDO_FILE_EEXIST)
345 		{
346 			LogMessage("Using empty waldo file '%s'\n", barnyard2_conf->waldo.filepath);
347 		}
348 		else if (ret == WALDO_FILE_ETRUNC)
349 		{
350 			LogMessage("WARNING: Ignoring corrupt/truncated waldo"
351 						"file '%s'\n", barnyard2_conf->waldo.filepath);
352 		}
353 	}
354 
355     /* Batch processing mode */
356     if(BcBatchMode())
357     {
358         int idx;
359 		if( barnyard2_conf->batch_total_files == 0 )
360         {
361             LogMessage("No files to process!\n");
362         }
363         else
364         {
365             LogMessage("Processing %d files...\n", barnyard2_conf->batch_total_files);
366             for(idx = 0; idx < barnyard2_conf->batch_total_files; idx++)
367             {
368 		ProcessBatch("", barnyard2_conf->batch_filelist[idx]);
369 		if( SignalCheck())
370 		{
371 		    /* Clean Things up */
372 		    Barnyard2Cleanup(0,0);
373 		    /* Relaunch status */
374 		    goto restart;
375 		}
376 	    }
377         }
378     }
379     /* Continual processing mode */
380     else if (BcContinuousMode())
381     {
382 	ProcessContinuousWithWaldo(&barnyard2_conf->waldo);
383 
384 	if( SignalCheck())
385 	{
386 	    /* Clean Things up */
387 	    Barnyard2Cleanup(0,0);
388 	    /* Relaunch status */
389 	    goto restart;
390 	}
391     }
392 
393 #ifndef WIN32
394     closelog();
395 #endif
396 
397     DropStats(1);
398 
399     return 0;
400 }
401 
InitPidChrootAndPrivs(void)402 static void InitPidChrootAndPrivs(void)
403 {
404     /* create the PID file */
405     /* TODO should be part of the GoDaemon process */
406     if (BcDaemonMode() || *barnyard2_conf->pidfile_suffix || BcCreatePidFile())
407     {
408 #ifdef WIN32
409         CreatePidFile("WIN32");
410 #else
411         CreatePidFile(PRINT_INTERFACE(barnyard2_conf->interface));
412 #endif /* WIN32 */
413     }
414 
415 #ifndef WIN32
416     /* Drop the Chrooted Settings */
417     if (barnyard2_conf->chroot_dir)
418         SetChroot(barnyard2_conf->chroot_dir, &barnyard2_conf->log_dir);
419 
420     /* Drop privileges if requested, when initialization is done */
421     SetUidGid(BcUid(), BcGid());
422 #endif  /* WIN32 */
423 }
424 
425 /*
426  * This function will print versioning information regardless of whether or
427  * not the quiet flag is set.  If the quiet flag has been set and we want
428  * to honor it, check it before calling this function.
429  */
PrintVersion(void)430 static void PrintVersion(void)
431 {
432     /* Unset quiet flag so LogMessage will print, then restore just
433      * in case anything other than exiting after this occurs */
434     int save_quiet_flag = barnyard2_conf->logging_flags & LOGGING_FLAG__QUIET;
435 
436     barnyard2_conf->logging_flags &= ~LOGGING_FLAG__QUIET;
437     DisplayBanner();
438 
439     barnyard2_conf->logging_flags |= save_quiet_flag;
440 }
441 
442 /*
443  * Function: ShowUsage(char *)
444  *
445  * Purpose:  Display the program options and exit
446  *
447  * Arguments: argv[0] => name of the program (argv[0])
448  *
449  * Returns: 0 => success
450  */
ShowUsage(char * program_name)451 static int ShowUsage(char *program_name)
452 {
453     fprintf(stdout, "USAGE: %s [-options] <filter options>\n", program_name);
454 #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
455     fprintf(stdout, "       %s %s %s [-options] <filter options>\n", program_name
456                                                                    , SERVICE_CMDLINE_PARAM
457                                                                    , SERVICE_INSTALL_CMDLINE_PARAM);
458     fprintf(stdout, "       %s %s %s\n", program_name
459                                        , SERVICE_CMDLINE_PARAM
460                                        , SERVICE_UNINSTALL_CMDLINE_PARAM);
461     fprintf(stdout, "       %s %s %s\n", program_name
462                                        , SERVICE_CMDLINE_PARAM
463                                        , SERVICE_SHOW_CMDLINE_PARAM);
464 #endif
465 
466 #ifdef WIN32
467 # define FPUTS_WIN32(msg) fputs(msg,stdout)
468 # define FPUTS_UNIX(msg)  NULL
469 # define FPUTS_BOTH(msg)  fputs(msg,stdout)
470 #else
471 # define FPUTS_WIN32(msg)
472 # define FPUTS_UNIX(msg)  fputs(msg,stdout)
473 # define FPUTS_BOTH(msg)  fputs(msg,stdout)
474 #endif
475 
476     FPUTS_BOTH ("Gernal Options:\n");
477 
478 //    FPUTS_BOTH ("        -A         Dump the Application Layer\n");
479     FPUTS_BOTH ("        -c <file>  Use configuration file <file>\n");
480     FPUTS_BOTH ("        -C <file>  Read the classification map from <file>\n");
481     FPUTS_UNIX ("        -D         Run barnyard2 in background (daemon) mode\n");
482     FPUTS_BOTH ("        -e         Display the second layer header info\n");
483     FPUTS_WIN32("        -E         Log alert messages to NT Eventlog. (Win32 only)\n");
484     FPUTS_BOTH ("        -F         Turn off fflush() calls after binary log writes\n");
485     FPUTS_UNIX ("        -g <gname> Run barnyard2 gid as <gname> group (or gid) after initialization\n");
486     FPUTS_BOTH ("        -G <file>  Read the gen-msg map from <file>\n");
487     FPUTS_BOTH ("        -h <name>  Define the hostname <name>. For logging purposes only\n");
488     FPUTS_BOTH ("        -i <if>    Define the interface <if>. For logging purposes only\n");
489     FPUTS_BOTH ("        -I         Add Interface name to alert output\n");
490     FPUTS_BOTH ("        -l <ld>    Log to directory <ld>\n");
491     FPUTS_UNIX ("        -m <umask> Set umask = <umask>\n");
492     FPUTS_BOTH ("        -O         Obfuscate the logged IP addresses\n");
493     FPUTS_BOTH ("        -q         Quiet. Don't show banner and status report\n");
494     FPUTS_BOTH ("        -r <id>    Include 'id' in barnyard2_intf<id>.pid file name\n");
495     FPUTS_BOTH ("        -R <file>  Read the reference map from <file>\n");
496 //    FPUTS_BOTH ("        -s         Log alert messages to syslog\n");
497     FPUTS_BOTH ("        -S <file>  Read the sid-msg map from <file>\n");
498     FPUTS_UNIX ("        -t <dir>   Chroots process to <dir> after initialization\n");
499     FPUTS_BOTH ("        -T         Test and report on the current barnyard2 configuration\n");
500     FPUTS_UNIX ("        -u <uname> Run barnyard2 uid as <uname> user (or uid) after initialization\n");
501     FPUTS_BOTH ("        -U         Use UTC for timestamps\n");
502     FPUTS_BOTH ("        -v         Be verbose\n");
503     FPUTS_BOTH ("        -V         Show version number\n");
504 //    FPUTS_BOTH ("        -X         Dump the raw packet data starting at the link layer\n");
505 //    FPUTS_BOTH ("        -x         Dump application data as chars only\n");
506     FPUTS_BOTH ("        -y         Include year in timestamp in the alert and log files\n");
507     FPUTS_BOTH ("        -?         Show this information\n");
508     FPUTS_BOTH ("\n");
509     FPUTS_BOTH ("Continual Processing Options:\n");
510     FPUTS_UNIX ("        -a <dir>   Archive processed files to <dir>\n");
511     FPUTS_BOTH ("        -f <base>  Use <base> as the base filename pattern\n");
512     FPUTS_BOTH ("        -d <dir>   Spool files from <dir>\n");
513     FPUTS_BOTH ("        -n         Only process new events\n");
514     FPUTS_BOTH ("        -w <file>  Enable bookmarking using <file>\n");
515 	FPUTS_BOTH ("\n");
516     FPUTS_BOTH ("Batch Processing Mode Options:\n");
517     FPUTS_BOTH ("        -o         Enable batch processing mode\n");
518 	FPUTS_BOTH ("\n");
519 
520     FPUTS_BOTH ("Longname options and their corresponding single char version\n");
521     FPUTS_BOTH ("   --disable-alert-on-each-packet-in-stream  Alert once per event\n");
522     FPUTS_BOTH ("   --event-cache-size <integer>      Set Spooler MAX event cache size \n");
523     FPUTS_BOTH ("   --reference <file>                Same as -R\n");
524     FPUTS_BOTH ("   --classification <file>           Same as -C\n");
525     FPUTS_BOTH ("   --gen-msg <file>                  Same as -G\n");
526     FPUTS_BOTH ("   --sid-msg <file>                  Same as -S\n");
527     FPUTS_BOTH ("   --process-new-records-only        Same as -n\n");
528     FPUTS_BOTH ("   --pid-path <dir>                  Specify the directory for the barnyard2 PID file\n");
529     FPUTS_BOTH ("   --help                            Same as -?\n");
530     FPUTS_BOTH ("   --version                         Same as -V\n");
531     FPUTS_UNIX ("   --create-pidfile                  Create PID file, even when not in Daemon mode\n");
532     FPUTS_UNIX ("   --nolock-pidfile                  Do not try to lock barnyard2 PID file\n");
533 #ifdef MPLS
534     FPUTS_BOTH ("   --max-mpls-labelchain-len         Specify the max MPLS label chain\n");
535     FPUTS_BOTH ("   --mpls-payload-type               Specify the protocol (ipv4, ipv6, ethernet) that is encapsulated by MPLS\n");
536 #endif
537 //    FPUTS_BOTH ("   --conf-error-out                Same as -x\n");
538 #undef FPUTS_WIN32
539 #undef FPUTS_UNIX
540 #undef FPUTS_BOTH
541     return 0;
542 }
543 
544 /*
545  * Function: ParseCmdLine(int, char **)
546  *
547  * Parses command line arguments
548  *
549  * Arguments:
550  *  int
551  *      count of arguments passed to the routine
552  *  char **
553  *      2-D character array, contains list of command line args
554  *
555  * Returns: None
556  *
557  */
558 
ParseCmdLine(int argc,char ** argv)559 static void ParseCmdLine(int argc, char **argv)
560 {
561     int ch;
562     int i;
563     int option_index = -1;
564     char *pcap_filter = NULL;
565     Barnyard2Config *bc;
566     int syslog_configured = 0;
567 #ifndef WIN32
568     int daemon_configured = 0;
569 #endif
570 #ifdef WIN32
571     char errorbuf[PCAP_ERRBUF_SIZE];
572 #endif
573 
574     DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Parsing command line...\n"););
575 
576     if (barnyard2_cmd_line_conf != NULL)
577     {
578         FatalError("%s(%d) Trying to parse the command line again.\n",
579                    __FILE__, __LINE__);
580     }
581 
582     barnyard2_cmd_line_conf = Barnyard2ConfNew();
583     barnyard2_conf = barnyard2_cmd_line_conf;     /* Set the global for log messages */
584     bc = barnyard2_cmd_line_conf;
585 
586     /* alert_on_each_packet_in_stream_flag enabled by default */
587     bc->alert_on_each_packet_in_stream_flag = 1;
588 
589     /* Look for a -D and/or -M switch so we can start logging to syslog
590      * with "barnyard2" tag right away */
591     for (i = 0; i < argc; i++)
592     {
593         if (strcmp("-M", argv[i]) == 0)
594         {
595             if (syslog_configured)
596                 continue;
597 
598             /* If daemon or logging to syslog use "snort" as identifier and
599              * start logging there now */
600             openlog("barnyard2", LOG_PID | LOG_CONS, LOG_DAEMON);
601 
602             bc->logging_flags |= LOGGING_FLAG__SYSLOG;
603             syslog_configured = 1;
604         }
605 #ifndef WIN32
606         else if ((strcmp("-D", argv[i]) == 0) ||
607                  (strcmp("--restart", argv[i]) == 0))
608         {
609             if (daemon_configured)
610                 continue;
611 
612             /* If daemon or logging to syslog use "barnyard2" as identifier and
613              * start logging there now */
614             openlog("barnyard2", LOG_PID | LOG_CONS, LOG_DAEMON);
615 
616             if (strcmp("--restart", argv[i]) == 0)
617                 bc->run_flags |= RUN_FLAG__DAEMON_RESTART;
618 
619             ConfigDaemon(bc, optarg);
620             daemon_configured = 1;
621         }
622 #endif
623         else if (strcmp("-q", argv[i]) == 0)
624         {
625             /* Turn on quiet mode if configured so any log messages that may
626              * be printed while parsing the command line before the quiet option
627              * is read won't be printed */
628             ConfigQuiet(bc, NULL);
629         }
630     }
631 
632     /*
633     **  Set this so we know whether to return 1 on invalid input.
634     **  Snort uses '?' for help and getopt uses '?' for telling us there
635     **  was an invalid option, so we can't use that to tell invalid input.
636     **  Instead, we check optopt and it will tell us.
637     */
638     optopt = 0;
639     optind = 0; /* in case we are being re-invoked , think HUP */
640 
641     /* loop through each command line var and process it */
642     while ((ch = getopt_long(argc, argv, valid_options, long_options, &option_index)) != -1)
643     {
644         DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Processing cmd line switch: %c\n", ch););
645 
646         switch (ch)
647         {
648             case PID_PATH:
649                 ConfigPidPath(bc, optarg);
650                 break;
651 
652             case CREATE_PID_FILE:
653                 ConfigCreatePidFile(bc, NULL);
654                 break;
655 
656             case NOLOCK_PID_FILE:
657                 bc->run_flags |= RUN_FLAG__NO_LOCK_PID_FILE;
658                 break;
659 
660             case NO_LOGGING_TIMESTAMPS:
661                 ConfigNoLoggingTimestamps(bc, NULL);
662                 break;
663 
664             case DISABLE_ALERT_ON_EACH_PACKET_IN_STREAM:
665                 ConfigDisableAlertOnEachPacketInStream(bc, NULL);
666                 break;
667 
668            case EVENT_CACHE_SIZE:
669                 ConfigSetEventCacheSize(bc,optarg);
670                 break;
671 
672             case ALERT_ON_EACH_PACKET_IN_STREAM:
673                 ConfigAlertOnEachPacketInStream(bc, NULL);
674                 break;
675 
676 #ifdef MPLS
677             case MAX_MPLS_LABELCHAIN_LEN:
678                 ConfigMaxMplsLabelChain(bc, optarg);
679                 break;
680 
681             case MPLS_PAYLOAD_TYPE:
682                 ConfigMplsPayloadType(bc, optarg);
683                 break;
684 #endif
685 
686             case 'a':  /* use archive directory <x> */
687                 ConfigArchiveDir(bc, optarg);
688                 break;
689 
690             case 'A':  /* dump the application layer data */
691                 ConfigDumpPayload(bc, NULL);
692                 break;
693 
694             case 'B':  /* obfuscate with a substitution mask */
695                 ConfigObfuscationMask(bc, optarg);
696                 break;
697 
698             case 'c':  /* use configuration file x */
699                 barnyard2_conf_file = SnortStrdup(optarg);
700                 break;
701 
702             case 'C':  /* set the classification file */
703                 ConfigClassificationFile(bc, optarg);
704                 break;
705 
706             case 'd':  /* dump the application layer data */
707                 bc->run_mode_flags |= RUN_MODE_FLAG__CONTINUOUS;
708                 ConfigSpoolDirectory(bc, optarg);
709                 break;
710 
711             case ARG_RESTART:  /* Restarting from daemon mode */
712             case 'D':  /* daemon mode */
713                 /* These are parsed at the beginning so as to start logging
714                  * to syslog right away */
715                 break;
716 
717             case 'e':  /* show second level header info */
718                 ConfigDecodeDataLink(bc, NULL);
719                 break;
720 #ifdef WIN32
721             case 'E':  /* log alerts to Event Log */
722                 ParseOutput(bc, NULL, "alert_syslog");
723                 bc->logging_flags &= ~LOGGING_FLAG__SYSLOG_REMOTE;
724                 break;
725 #endif
726             case 'f':
727                 bc->run_mode_flags |= RUN_MODE_FLAG__CONTINUOUS;
728                 ConfigSpoolFilebase(bc, optarg);
729                 break;
730 
731             case 'F':
732                 bc->output_flags |= OUTPUT_FLAG__LINE_BUFFER;
733                 break;
734 
735             case 'g':   /* setgid */
736                 ConfigSetGid(bc, optarg);
737                 break;
738 
739 
740 
741             case 'h':
742                 ConfigHostname(bc, optarg);
743                 break;
744 
745             case 'i':
746                 ConfigInterface(bc, optarg);
747                 break;
748 
749             case 'I':  /* add interface name to alert string */
750                 ConfigAlertWithInterfaceName(bc, NULL);
751                 break;
752 
753             case 'l':  /* use log dir <X> */
754                 ConfigLogDir(bc, optarg);
755                 break;
756 
757             case 'M':
758                 /* This is parsed at the beginning so as to start logging
759                  * to syslog right away */
760                 break;
761 
762             case 'm':  /* set the umask for the output files */
763                 ConfigUmask(bc, optarg);
764                 break;
765 
766             case 'n': /* process new records only */
767                 ConfigProcessNewRecordsOnly(bc, NULL);
768                 break;
769 
770             case 'o':  /* use configuration file x */
771                 bc->run_mode_flags |= RUN_MODE_FLAG__BATCH;
772                 break;
773 
774             case 'O':  /* obfuscate the logged IP addresses for privacy */
775                 ConfigObfuscate(bc, NULL);
776                 break;
777 
778             case 'q':  /* no stdout output mode */
779                 /* This is parsed at the beginning so as to start logging
780                  * in quiet mode right away */
781                 break;
782 
783             case 'r': /* augment pid file name suffix */
784                 if ((strlen(optarg) >= MAX_PIDFILE_SUFFIX) || (strlen(optarg) <= 0) ||
785                     (strstr(optarg, "..") != NULL) || (strstr(optarg, "/") != NULL))
786                 {
787                         FatalError("Invalid pidfile suffix: %s.  Suffix must "
788                                    "less than %u characters and not have "
789                                    "\"..\" or \"/\" in the name.\n", optarg,
790                                    MAX_PIDFILE_SUFFIX);
791                 }
792 
793                 SnortStrncpy(bc->pidfile_suffix, optarg, sizeof(bc->pidfile_suffix));
794                 break;
795 
796             case 'R': /* augment pid file name suffix */
797                 ConfigReferenceFile(bc, optarg);
798                 break;
799 
800             case 's':  /* log alerts to syslog */
801 #ifndef WIN32
802                 ParseOutput(bc, "alert_syslog");
803 #else
804                 bc->logging_flags |= LOGGING_FLAG__SYSLOG_REMOTE;
805 #endif
806                 break;
807 
808      	    case 'S':  /* set a rules file variable */
809 		bc->sid_msg_file = strndup(optarg,PATH_MAX);
810 		break;
811 
812    	    case 'G':  /* snort preprocessor identifier */
813 		bc->gen_msg_file = strndup(optarg,PATH_MAX);
814 		break;
815 
816             case 't':  /* chroot to the user specified directory */
817                 ConfigChrootDir(bc, optarg);
818                 break;
819 
820             case 'T':  /* test mode, verify that the rules load properly */
821                 bc->run_mode_flags |= RUN_MODE_FLAG__TEST;
822                 break;
823 
824             case 'u':  /* setuid */
825                 ConfigSetUid(bc, optarg);
826                 break;
827 
828             case 'U':  /* use UTC */
829                 ConfigUtc(bc, NULL);
830                 break;
831 
832             case 'v':  /* be verbose */
833                 ConfigVerbose(bc, NULL);
834                 break;
835 
836             case 'V':  /* prog ver already gets printed out, so we just exit */
837                 bc->run_mode_flags |= RUN_MODE_FLAG__VERSION;
838                 bc->logging_flags |= LOGGING_FLAG__QUIET;
839                 break;
840 
841 #if !defined(NO_NON_ETHER_DECODER) && defined(DLT_IEEE802_11)
842 //          case 'w':  /* show 802.11 all frames info */
843 //              bc->output_flags |= OUTPUT_FLAG__SHOW_WIFI_MGMT;
844 //              break;
845 #endif
846             case 'w':
847                 bc->run_mode_flags |= RUN_MODE_FLAG__CONTINUOUS;
848                 ConfigWaldoFile(bc, optarg);
849                 break;
850 
851             case 'X':  /* display verbose packet bytecode dumps */
852                 ConfigDumpPayloadVerbose(bc, NULL);
853                 break;
854 
855             case 'x':  /* dump the application layer as text only */
856                 ConfigDumpCharsOnly(bc, NULL);
857                 break;
858 
859             case 'y':  /* Add year to timestamp in alert and log files */
860                 ConfigShowYear(bc, NULL);
861                 break;
862 
863             case '?':  /* show help and exit with 0 since this is what was requested */
864                 PrintVersion();
865                 ShowUsage(argv[0]);
866                 exit(0);
867                 break;
868 
869             default:
870                 FatalError("Invalid option: %c.\n", ch);
871                 break;
872         }
873     }
874 
875     /* when batch processing check for any remaining arguments which should */
876     /* be a parsed as a list of files to process. */
877     if ((bc->run_mode_flags & RUN_MODE_FLAG__BATCH) && (optind < argc))
878     {
879 	int idx = 0;
880 
881 	bc->batch_total_files = argc - optind;
882 	bc->batch_filelist = SnortAlloc(bc->batch_total_files * sizeof(char *));
883 
884 	while (optind < argc)
885 	{
886 	    DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Extra args: %s\n", argv[optind]););
887 	    bc->batch_filelist[idx] = SnortStrdup(argv[optind]);
888 
889 	    idx++;
890 	    optind++;
891 	}
892 
893 	DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Total files: %i\n", bc->batch_total_files););
894     }
895 
896     if ((bc->run_mode_flags & RUN_MODE_FLAG__TEST) &&
897         (bc->run_flags & RUN_FLAG__DAEMON))
898     {
899         FatalError("Cannot use test mode and daemon mode together.\n"
900                    "To verify configuration, run first in test "
901                    "mode and then restart in daemon mode.\n");
902     }
903     else if ((bc->run_mode_flags & RUN_MODE_FLAG__BATCH) &&
904 	     (bc->run_flags & RUN_MODE_FLAG__CONTINUOUS))
905     {
906         FatalError("Cannot use batch mode and continuous mode together.\n");
907     }
908 
909 
910     if ((bc->run_mode_flags & RUN_MODE_FLAG__TEST) &&
911         (barnyard2_conf_file == NULL))
912     {
913         FatalError("Test mode must be run with a snort configuration "
914                    "file.  Use the '-c' option on the command line to "
915                    "specify a configuration file.\n");
916     }
917 
918     if (pcap_filter != NULL)
919         free(pcap_filter);
920 
921     /* Set the run mode based on what we've got from command line */
922 
923     /* Version overrides all */
924     if (bc->run_mode_flags & RUN_MODE_FLAG__VERSION)
925     {
926         bc->run_mode = RUN_MODE__VERSION;
927     }
928     /* Next if we want to test a snort conf */
929     else if (bc->run_mode_flags & RUN_MODE_FLAG__TEST)
930     {
931         bc->run_mode = RUN_MODE__TEST;
932     }
933     /* Now if there is a barnyard2 conf.  If a barnyard2 conf wasn't given on the
934      * command line, we'll look in a default place if the next ones
935      * don't match */
936     else if ((bc->run_mode_flags & RUN_MODE_FLAG__CONTINUOUS) && (barnyard2_conf_file != NULL))
937     {
938         bc->run_mode = RUN_MODE__CONTINUOUS;
939     }
940     else if ((bc->run_mode_flags & RUN_MODE_FLAG__BATCH) && (barnyard2_conf_file != NULL))
941     {
942         bc->run_mode = RUN_MODE__BATCH;
943     }
944 
945     if (!bc->run_mode)
946         bc->run_mode = RUN_MODE__CONTINUOUS;
947 
948     /* If no mode is set, try and find snort conf in some default location */
949     if (((bc->run_mode == RUN_MODE__CONTINUOUS) || (bc->run_mode == RUN_MODE__BATCH) ||
950         (bc->run_mode == RUN_MODE__TEST)) && (barnyard2_conf_file == NULL))
951     {
952         barnyard2_conf_file = ConfigFileSearch();
953         if (barnyard2_conf_file == NULL)
954         {
955             /* unable to determine a run mode */
956             DisplayBanner();
957             ShowUsage(argv[0]);
958 
959             ErrorMessage("\n");
960             ErrorMessage("\n");
961             ErrorMessage("Uh, you need to tell me to do something...");
962             ErrorMessage("\n");
963             ErrorMessage("\n");
964             FatalError("");
965         }
966     }
967 
968     SetBarnyard2ConfDir();
969 }
970 
971 /* locate one of the possible default config files */
972 /* allocates memory to hold filename */
ConfigFileSearch(void)973 static char *ConfigFileSearch(void)
974 {
975     struct stat st;
976     int i;
977     char *conf_files[]={"/etc/barnyard2.conf", "./barnyard2.conf", NULL};
978     char *fname = NULL;
979     char *rval = NULL;
980 
981     i = 0;
982 
983     /* search the default set of config files */
984     while(conf_files[i])
985     {
986         fname = conf_files[i];
987 
988         if(stat(fname, &st) != -1)
989         {
990             rval = SnortStrdup(fname);
991             break;
992         }
993         i++;
994     }
995 
996     /* search for .barnyard2rc in the HOMEDIR */
997     if(!rval)
998     {
999         char *home_dir = NULL;
1000 
1001         if((home_dir = getenv("HOME")) != NULL)
1002         {
1003             char *snortrc = "/.barnyard2rc";
1004             int path_len;
1005 
1006             path_len = strlen(home_dir) + strlen(snortrc) + 1;
1007 
1008             /* create the full path */
1009             fname = (char *)SnortAlloc(path_len);
1010 
1011             SnortSnprintf(fname, path_len, "%s%s", home_dir, snortrc);
1012 
1013             if(stat(fname, &st) != -1)
1014                 rval = fname;
1015             else
1016                 free(fname);
1017         }
1018     }
1019 
1020     return rval;
1021 }
1022 
1023 /* Signal Handlers ************************************************************/
SigExitHandler(int signal)1024 static void SigExitHandler(int signal)
1025 {
1026     if (exit_signal != 0)
1027         return;
1028 
1029     if (barnyard2_initializing)
1030         _exit(0);
1031 
1032     exit_signal = signal;
1033     return;
1034 }
1035 
SigUsrHandler(int signal)1036 static void SigUsrHandler(int signal)
1037 {
1038     if ( (usr_signal != 0) ||
1039 	 (exit_signal != 0))
1040         return;
1041 
1042     usr_signal = signal;
1043     return;
1044 }
1045 
SigHupHandler(int signal)1046 static void SigHupHandler(int signal)
1047 {
1048     if(exit_signal  != 0)
1049 	return;
1050 
1051     exit_signal = 1;
1052     hup_signal = 1;
1053 
1054     return;
1055 }
1056 
1057 /****************************************************************************
1058  *
1059  * Function: CleanExit()
1060  *
1061  * Purpose:  Clean up misc file handles and such and exit
1062  *
1063  * Arguments: exit value;
1064  *
1065  * Returns: void function
1066  *
1067  ****************************************************************************/
CleanExit(int exit_val)1068 void CleanExit(int exit_val)
1069 {
1070     LogMessage("Barnyard2 exiting\n");
1071 
1072 #ifndef WIN32
1073     closelog();
1074 #endif
1075 
1076     Barnyard2Cleanup(exit_val,1);
1077 }
1078 
1079 
Barnyard2Cleanup(int exit_val,int exit_needed)1080 static void Barnyard2Cleanup(int exit_val,int exit_needed)
1081 {
1082     PluginSignalFuncNode *idxPlugin = NULL;
1083     PluginSignalFuncNode *idxPluginNext = NULL;
1084 
1085     /* This function can be called more than once. */
1086     static int already_exiting = 0;
1087 
1088     if( already_exiting != 0 )
1089     {
1090         return;
1091     }
1092 
1093     already_exiting = 1;
1094 
1095     barnyard2_initializing = 0;  /* just in case we cut out early */
1096 
1097     if (BcContinuousMode() || BcBatchMode())
1098     {
1099         /* Do some post processing on any incomplete Plugin Data */
1100 	idxPlugin = plugin_clean_exit_funcs;
1101         while(idxPlugin)
1102         {
1103 	    idxPluginNext = idxPlugin->next;
1104             idxPlugin->func(SIGQUIT, idxPlugin->arg);
1105 	    free(idxPlugin);
1106             idxPlugin = idxPluginNext;
1107         }
1108 	plugin_clean_exit_funcs = NULL;
1109     }
1110 
1111 
1112 
1113 
1114 	/*
1115 	  Right now we will just free them if they are initialized since
1116 	  in the context we operate if we receive HUP we mainly just "restart"
1117 	*/
1118 	idxPlugin = plugin_restart_funcs;
1119 	while(idxPlugin)
1120         {
1121             idxPluginNext = idxPlugin->next;
1122             free(idxPlugin);
1123             idxPlugin = idxPluginNext;
1124         }
1125 	plugin_restart_funcs = NULL;
1126 
1127 
1128 	idxPlugin = plugin_shutdown_funcs;
1129 	while(idxPlugin)
1130         {
1131             idxPluginNext = idxPlugin->next;
1132             free(idxPlugin);
1133             idxPlugin = idxPluginNext;
1134         }
1135 	plugin_shutdown_funcs = NULL;
1136 
1137 
1138     if (!exit_val)
1139     {
1140         struct timeval difftime;
1141         struct timezone tz;
1142 
1143 	memset((char *) &tz, 0, sizeof(tz)); /* bzero() deprecated, replaced by memset() */
1144         gettimeofday(&endtime, &tz);
1145 
1146         TIMERSUB(&endtime, &starttime, &difftime);
1147 
1148         if (exit_signal)
1149         {
1150             LogMessage("Run time prior to being shutdown was %lu.%lu seconds\n",
1151                        (unsigned long)difftime.tv_sec,
1152                        (unsigned long)difftime.tv_usec);
1153         }
1154     }
1155 
1156     if (BcContinuousMode() || BcBatchMode() || BcTestMode())
1157     {
1158         /* Do some post processing on any incomplete Plugin Data */
1159         idxPlugin = plugin_clean_exit_funcs;
1160         while(idxPlugin)
1161         {
1162 	    idxPluginNext = idxPlugin->next;
1163             idxPlugin->func(SIGQUIT, idxPlugin->arg);
1164 	    free(idxPlugin);
1165             idxPlugin = idxPluginNext;
1166         }
1167 	plugin_clean_exit_funcs = NULL;
1168     }
1169 
1170     /* Print Statistics */
1171     if (!BcTestMode() && !BcVersionMode())
1172     {
1173 	if(!stat_dropped)
1174 	{
1175 	    DropStats(2);
1176 	}
1177 	else
1178 	{
1179 	    stat_dropped = 0;
1180 	}
1181     }
1182 
1183     /* Cleanup some spooler stuff */
1184     if(barnyard2_conf->spooler)
1185     {
1186 	spoolerEventCacheFlush(barnyard2_conf->spooler);
1187 
1188 	if(barnyard2_conf->spooler->header)
1189 	{
1190 	    free(barnyard2_conf->spooler->header);
1191 	    barnyard2_conf->spooler->header = NULL;
1192 	}
1193 
1194 	if(barnyard2_conf->spooler->record.header)
1195 	{
1196 	    free(barnyard2_conf->spooler->record.header);
1197 	    barnyard2_conf->spooler->record.header = NULL;
1198 	}
1199 
1200 	if(barnyard2_conf->spooler->record.data)
1201 	{
1202 	    free(barnyard2_conf->spooler->record.data);
1203 	    barnyard2_conf->spooler->record.data = NULL;
1204 	}
1205     }
1206 
1207     CleanupProtoNames();
1208     ClosePidFile();
1209 
1210     /* remove pid file */
1211     if (SnortStrnlen(barnyard2_conf->pid_filename, sizeof(barnyard2_conf->pid_filename)) > 0)
1212     {
1213         int ret;
1214         ret = unlink(barnyard2_conf->pid_filename);
1215 
1216         if (ret != 0)
1217         {
1218             ErrorMessage("Could not remove pid file %s: %s\n",
1219                          barnyard2_conf->pid_filename, strerror(errno));
1220         }
1221     }
1222 
1223     spoolerCloseWaldo(&barnyard2_conf->waldo);
1224 
1225     if(barnyard2_conf->spooler)
1226     {
1227 	spoolerClose(barnyard2_conf->spooler);
1228 	barnyard2_conf->spooler = NULL;
1229     }
1230 
1231 
1232     /* free allocated memory */
1233     if (barnyard2_conf == barnyard2_cmd_line_conf)
1234     {
1235         Barnyard2ConfFree(barnyard2_cmd_line_conf);
1236         barnyard2_cmd_line_conf = NULL;
1237         barnyard2_conf = NULL;
1238     }
1239     else
1240     {
1241         Barnyard2ConfFree(barnyard2_cmd_line_conf);
1242         barnyard2_cmd_line_conf = NULL;
1243         Barnyard2ConfFree(barnyard2_conf);
1244         barnyard2_conf = NULL;
1245     }
1246 
1247     FreeOutputList(AlertList);
1248     FreeOutputList(LogList);
1249     AlertList = NULL;
1250     LogList = NULL;
1251 
1252     FreeOutputConfigFuncs();
1253 
1254     FreeInputPlugins();
1255 
1256     /* Global lists */
1257     ParserCleanup();
1258 
1259     /* Stuff from plugbase */
1260     ClearDumpBuf();
1261 
1262     if (netmasks != NULL)
1263     {
1264         free(netmasks);
1265         netmasks = NULL;
1266     }
1267 
1268     if (barnyard2_conf_file != NULL)
1269     {
1270         free(barnyard2_conf_file);
1271 	barnyard2_conf_file = NULL;
1272     }
1273 
1274     if (barnyard2_conf_dir != NULL)
1275     {
1276         free(barnyard2_conf_dir);
1277 	barnyard2_conf_dir = NULL;
1278     }
1279 
1280     if(exit_needed)
1281 	_exit(exit_val);
1282 
1283     already_exiting = 0;
1284     return;
1285 }
1286 
Restart(void)1287 void Restart(void)
1288 {
1289     int daemon_mode = BcDaemonMode();
1290 
1291 #ifndef WIN32
1292     if ((getuid() != 0) || (barnyard2_conf->chroot_dir != NULL))
1293     {
1294         LogMessage("Reload via Signal HUP does not work if you aren't root "
1295                    "or are chroot'ed.\n");
1296         return;
1297     }
1298 #endif
1299 
1300     LogMessage("\n");
1301     LogMessage("***** Restarting Barnyard2 *****\n");
1302     LogMessage("\n");
1303     Barnyard2Cleanup(0,0);
1304 
1305     if (daemon_mode)
1306     {
1307         int i;
1308 
1309         for (i = 0; i < barnyard2_argc; i++)
1310         {
1311             if (!strcmp(barnyard2_argv[i], "--restart"))
1312             {
1313                 break;
1314             }
1315             else if (!strncmp(barnyard2_argv[i], "-D", 2))
1316             {
1317                 /* Replace -D with --restart */
1318                 /* a probable memory leak - but we're exec()ing anyway */
1319                 barnyard2_argv[i] = SnortStrdup("--restart");
1320                 break;
1321             }
1322         }
1323     }
1324 
1325 #ifdef PARANOID
1326     execv(barnyard2_argv[0], barnyard2_argv);
1327 #else
1328     execvp(barnyard2_argv[0], barnyard2_argv);
1329 #endif
1330 
1331     /* only get here if we failed to restart */
1332     LogMessage("Restarting %s failed: %s\n", barnyard2_argv[0], strerror(errno));
1333 
1334 #ifndef WIN32
1335     closelog();
1336 #endif
1337 
1338     exit(-1);
1339 }
1340 
1341 
1342 /*
1343  *  Check for signal activity
1344  */
SignalCheck(void)1345 int SignalCheck(void)
1346 {
1347     switch (exit_signal)
1348     {
1349 
1350     case SIGTERM:
1351 	if (!exit_logged)
1352 	{
1353 	    ErrorMessage("*** Caught Term-Signal\n");
1354 	    exit_logged = 1;
1355 	}
1356 
1357 	CleanExit(exit_signal);
1358 	break;
1359 
1360     case SIGINT:
1361 	if (!exit_logged)
1362 	{
1363 	    ErrorMessage("*** Caught Int-Signal\n");
1364 	    exit_logged = 1;
1365 	}
1366 
1367 	CleanExit(exit_signal);
1368 	break;
1369 
1370     case SIGQUIT:
1371 	if (!exit_logged)
1372 	{
1373 	    ErrorMessage("*** Caught Quit-Signal\n");
1374 	    exit_logged = 1;
1375 	}
1376 
1377 	CleanExit(exit_signal);
1378 	break;
1379 
1380     case SIGKILL:
1381 	if (!exit_logged)
1382         {
1383             ErrorMessage("*** Caught Kill-Signal\n");
1384             exit_logged = 1;
1385         }
1386 
1387 	CleanExit(exit_signal);
1388 	break;
1389 
1390     default:
1391 	break;
1392     }
1393 
1394     exit_signal = 0;
1395 
1396     switch (usr_signal)
1397     {
1398     case SIGUSR1:
1399 	ErrorMessage("*** Caught Usr-Signal\n");
1400 	DropStats(0);
1401 	break;
1402 
1403     case SIGNAL_SNORT_ROTATE_STATS:
1404 	ErrorMessage("*** Caught Usr-Signal: 'Rotate Stats'\n");
1405 	break;
1406     }
1407 
1408     usr_signal = 0;
1409 
1410     if (hup_signal)
1411     {
1412         ErrorMessage("*** Caught Hup-Signal\n");
1413 	DropStats(0);
1414 	stat_dropped = 1;
1415 	ErrorMessage("*** Resetting Stats\n");
1416 	memset(&pc,'\0',sizeof(PacketCount));
1417         hup_signal = 0;
1418         return 1;
1419     }
1420 
1421     return 0;
1422 }
1423 
1424 
InitGlobals(void)1425 static void InitGlobals(void)
1426 {
1427     memset(&pc, 0, sizeof(PacketCount));
1428     InitNetmasks();
1429     InitProtoNames();
1430 }
1431 
1432 /* XXX Alot of this initialization can be skipped if not running
1433  * in IDS mode */
Barnyard2ConfNew(void)1434 Barnyard2Config * Barnyard2ConfNew(void)
1435 {
1436     Barnyard2Config *bc = (Barnyard2Config *)SnortAlloc(sizeof(Barnyard2Config));
1437 
1438     bc->user_id = -1;
1439     bc->group_id = -1;
1440 
1441     memset(bc->pid_path, 0, sizeof(bc->pid_path));
1442     memset(bc->pid_filename, 0, sizeof(bc->pid_filename));
1443     memset(bc->pidfile_suffix, 0, sizeof(bc->pidfile_suffix));
1444 
1445     memset(bc->waldo.data.spool_dir, 0, sizeof(bc->waldo.data.spool_dir));
1446     memset(bc->waldo.data.spool_filebase, 0, sizeof(bc->waldo.data.spool_filebase));
1447     memset(bc->waldo.filepath, 0, sizeof(bc->waldo.filepath));
1448 
1449     return bc;
1450 }
1451 
Barnyard2ConfFree(Barnyard2Config * bc)1452 void Barnyard2ConfFree(Barnyard2Config *bc)
1453 {
1454     if (bc == NULL)
1455         return;
1456 
1457     if (bc->log_dir != NULL)
1458     {
1459         free(bc->log_dir);
1460 	bc->log_dir = NULL;
1461     }
1462 
1463     if (bc->orig_log_dir != NULL)
1464     {
1465         free(bc->orig_log_dir);
1466 	bc->orig_log_dir = NULL;
1467     }
1468 
1469     if (bc->interface != NULL)
1470     {
1471         free(bc->interface);
1472 	bc->interface = NULL;
1473     }
1474 
1475     if (bc->chroot_dir != NULL)
1476     {
1477         free(bc->chroot_dir);
1478 	bc->chroot_dir = NULL;
1479     }
1480 
1481     if (bc->archive_dir != NULL)
1482     {
1483         free(bc->archive_dir);
1484 	bc->archive_dir = NULL;
1485     }
1486 
1487     if(bc->config_file != NULL)
1488     {
1489 	free(bc->config_file);
1490 	bc->config_file = NULL;
1491     }
1492 
1493     if(bc->config_dir != NULL)
1494     {
1495 	free(bc->config_dir);
1496 	bc->config_dir = NULL;
1497     }
1498 
1499     if(bc->hostname != NULL)
1500     {
1501 	free(bc->hostname);
1502 	bc->hostname = NULL;
1503     }
1504 
1505     if(bc->class_file != NULL)
1506     {
1507 	free(bc->class_file);
1508 	bc->class_file = NULL;
1509     }
1510 
1511     if( bc->sid_msg_file != NULL)
1512     {
1513 	free(bc->sid_msg_file);
1514 	bc->sid_msg_file = NULL;
1515     }
1516 
1517     if( bc->gen_msg_file != NULL)
1518     {
1519 	free(bc->gen_msg_file);
1520 	bc->gen_msg_file = NULL;
1521     }
1522 
1523     if( bc->reference_file != NULL)
1524     {
1525 	free(bc->reference_file);
1526 	bc->reference_file = NULL;
1527     }
1528 
1529     if( bc->bpf_filter != NULL)
1530     {
1531 	free(bc->bpf_filter);
1532 	bc->bpf_filter = NULL;
1533     }
1534 
1535     if (bc->batch_total_files > 0)
1536     {
1537 	int idx;
1538 	for(idx = 0; idx< bc->batch_total_files; idx++)
1539 	{
1540 	    free(bc->batch_filelist[idx]);
1541 	    bc->batch_filelist[idx] = NULL;
1542 	}
1543 	free(bc->batch_filelist);
1544     }
1545 
1546     FreeSigSuppression(&bc->ssHead);
1547     FreeSigNodes(&bc->sigHead);
1548     FreeClassifications(&bc->classifications);
1549     FreeReferences(&bc->references);
1550 
1551     FreeInputConfigs(bc->input_configs);
1552     bc->input_configs = NULL;
1553 
1554     FreeOutputConfigs(bc->output_configs);
1555     bc->output_configs = NULL;
1556 
1557     VarTablesFree(bc);
1558     FreePlugins(bc);
1559 
1560     free(bc);
1561 }
1562 
1563 /****************************************************************************
1564  *
1565  * Function: InitNetMasks()
1566  *
1567  * Purpose: Loads the netmask struct in network order.  Yes, I know I could
1568  *          just load the array when I define it, but this is what occurred
1569  *          to me when I wrote this at 3:00 AM.
1570  *
1571  * Arguments: None.
1572  *
1573  * Returns: void function
1574  *
1575  ****************************************************************************/
InitNetmasks(void)1576 static void InitNetmasks(void)
1577 {
1578     if (netmasks == NULL)
1579         netmasks = (uint32_t *)SnortAlloc(33 * sizeof(uint32_t));
1580 
1581     netmasks[0]  = 0x00000000;
1582     netmasks[1]  = 0x80000000;
1583     netmasks[2]  = 0xC0000000;
1584     netmasks[3]  = 0xE0000000;
1585     netmasks[4]  = 0xF0000000;
1586     netmasks[5]  = 0xF8000000;
1587     netmasks[6]  = 0xFC000000;
1588     netmasks[7]  = 0xFE000000;
1589     netmasks[8]  = 0xFF000000;
1590     netmasks[9]  = 0xFF800000;
1591     netmasks[10] = 0xFFC00000;
1592     netmasks[11] = 0xFFE00000;
1593     netmasks[12] = 0xFFF00000;
1594     netmasks[13] = 0xFFF80000;
1595     netmasks[14] = 0xFFFC0000;
1596     netmasks[15] = 0xFFFE0000;
1597     netmasks[16] = 0xFFFF0000;
1598     netmasks[17] = 0xFFFF8000;
1599     netmasks[18] = 0xFFFFC000;
1600     netmasks[19] = 0xFFFFE000;
1601     netmasks[20] = 0xFFFFF000;
1602     netmasks[21] = 0xFFFFF800;
1603     netmasks[22] = 0xFFFFFC00;
1604     netmasks[23] = 0xFFFFFE00;
1605     netmasks[24] = 0xFFFFFF00;
1606     netmasks[25] = 0xFFFFFF80;
1607     netmasks[26] = 0xFFFFFFC0;
1608     netmasks[27] = 0xFFFFFFE0;
1609     netmasks[28] = 0xFFFFFFF0;
1610     netmasks[29] = 0xFFFFFFF8;
1611     netmasks[30] = 0xFFFFFFFC;
1612     netmasks[31] = 0xFFFFFFFE;
1613     netmasks[32] = 0xFFFFFFFF;
1614 }
1615 
1616 /****************************************************************************
1617  *
1618  * Function: InitProtoNames()
1619  *
1620  * Purpose: Initializes the protocol names
1621  *
1622  * Arguments: None.
1623  *
1624  * Returns: void function
1625  *
1626  ****************************************************************************/
InitProtoNames(void)1627 static void InitProtoNames(void)
1628 {
1629     int i;
1630 
1631     if (protocol_names == NULL)
1632         protocol_names = (char **)SnortAlloc(sizeof(char *) * NUM_IP_PROTOS);
1633 
1634     for (i = 0; i < NUM_IP_PROTOS; i++)
1635     {
1636         struct protoent *pt = getprotobynumber(i);
1637 
1638         if (pt != NULL)
1639         {
1640             size_t j;
1641 
1642             protocol_names[i] = SnortStrdup(pt->p_name);
1643             for (j = 0; j < strlen(protocol_names[i]); j++)
1644                 protocol_names[i][j] = toupper(protocol_names[i][j]);
1645         }
1646         else
1647         {
1648             char protoname[10];
1649 
1650             SnortSnprintf(protoname, sizeof(protoname), "PROTO:%03d", i);
1651             protocol_names[i] = SnortStrdup(protoname);
1652         }
1653     }
1654 }
1655 
1656 
SetBarnyard2ConfDir(void)1657 static void SetBarnyard2ConfDir(void)
1658 {
1659     /* extract the config directory from the config filename */
1660     if (barnyard2_conf_file != NULL)
1661     {
1662 #ifndef WIN32
1663         char *path_sep = strrchr(barnyard2_conf_file, '/');
1664 #else
1665         char *path_sep = strrchr(barnyard2_conf_file, '\\');
1666 #endif
1667 
1668         /* is there a directory seperator in the filename */
1669         if (path_sep != NULL)
1670         {
1671             path_sep++;  /* include path separator */
1672             barnyard2_conf_dir = SnortStrndup(barnyard2_conf_file, path_sep - barnyard2_conf_file);
1673         }
1674         else
1675         {
1676             barnyard2_conf_dir = SnortStrdup("./");
1677         }
1678 
1679         DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Config file = %s, config dir = "
1680                     "%s\n", barnyard2_conf_file, barnyard2_conf_dir););
1681     }
1682 }
1683 
FreePlugins(Barnyard2Config * bc)1684 static void FreePlugins(Barnyard2Config *bc)
1685 {
1686     if (bc == NULL)
1687         return;
1688 
1689     FreePluginSigFuncs(bc->plugin_post_config_funcs);
1690     bc->plugin_post_config_funcs = NULL;
1691 }
1692 
MergeBarnyard2Confs(Barnyard2Config * cmd_line,Barnyard2Config * config_file)1693 static Barnyard2Config * MergeBarnyard2Confs(Barnyard2Config *cmd_line, Barnyard2Config *config_file)
1694 {
1695     /* Move everything from the command line config over to the
1696      * config_file config */
1697 
1698     if (cmd_line == NULL)
1699     {
1700         FatalError("%s(%d) Merging barnyard2 configs: barnyard2 conf is NULL.\n",
1701                    __FILE__, __LINE__);
1702     }
1703 
1704     ResolveOutputPlugins(cmd_line, config_file);
1705 
1706     if (config_file == NULL)
1707     {
1708         if (cmd_line->log_dir == NULL)
1709             cmd_line->log_dir = SnortStrdup(DEFAULT_LOG_DIR);
1710     }
1711     else if ((cmd_line->log_dir == NULL) && (config_file->log_dir == NULL))
1712     {
1713         config_file->log_dir = SnortStrdup(DEFAULT_LOG_DIR);
1714     }
1715     else if (cmd_line->log_dir != NULL)
1716     {
1717         if (config_file->log_dir != NULL)
1718             free(config_file->log_dir);
1719 
1720         config_file->log_dir = SnortStrdup(cmd_line->log_dir);
1721     }
1722 
1723     if (config_file == NULL)
1724         return cmd_line;
1725 
1726     if(cmd_line->ssHead)
1727     {
1728 	config_file->ssHead = cmd_line->ssHead;
1729 	cmd_line->ssHead = NULL;
1730     }
1731 
1732     if( (cmd_line->sid_msg_file) &&
1733 	(config_file->sid_msg_file))
1734     {
1735 	FatalError("The sid map file was included two times command line (-S) [%s] and in the configuration file (config sid_map) [%s].\n"
1736 		   "It only need to be defined once.\n",
1737 		   cmd_line->sid_msg_file,
1738 		   config_file->sid_msg_file);
1739     }
1740 
1741     if( (cmd_line->gen_msg_file) &&
1742 	(config_file->gen_msg_file))
1743     {
1744 	FatalError("The gen map file was included two times command line (-G) [%s] and in the configuration file (config gen_map) [%s].\n"
1745 		   "It only need to be defined once.\n",
1746 		   cmd_line->gen_msg_file,
1747 		   config_file->gen_msg_file);
1748     }
1749 
1750     if( (cmd_line->sid_msg_file != NULL) &&
1751 	(config_file->sid_msg_file == NULL))
1752     {
1753 	config_file->sid_msg_file = cmd_line->sid_msg_file;
1754 	cmd_line->sid_msg_file = NULL;
1755     }
1756 
1757     if( (cmd_line->gen_msg_file != NULL) &&
1758         (config_file->gen_msg_file == NULL))
1759     {
1760         config_file->gen_msg_file = cmd_line->gen_msg_file;
1761         cmd_line->gen_msg_file = NULL;
1762     }
1763 
1764 
1765     if( cmd_line->event_cache_size > config_file->event_cache_size)
1766     {
1767 	config_file->event_cache_size = cmd_line->event_cache_size;
1768     }
1769 
1770     /* In case */
1771     if(cmd_line->sidmap_version > config_file->sidmap_version)
1772     {
1773 	config_file->sidmap_version = cmd_line->sidmap_version;
1774     }
1775 
1776 
1777     /* Used because of a potential chroot */
1778     config_file->orig_log_dir = SnortStrdup(config_file->log_dir);
1779 
1780     config_file->run_mode = cmd_line->run_mode;
1781     config_file->run_mode_flags |= cmd_line->run_mode_flags;
1782 
1783     if ((cmd_line->run_mode == RUN_MODE__TEST) &&
1784         (config_file->run_flags & RUN_FLAG__DAEMON))
1785     {
1786         /* Just ignore deamon setting in conf file */
1787         config_file->run_flags &= ~RUN_FLAG__DAEMON;
1788     }
1789 
1790     config_file->run_flags |= cmd_line->run_flags;
1791 
1792     config_file->output_flags |= cmd_line->output_flags;
1793 
1794     config_file->logging_flags |= cmd_line->logging_flags;
1795 
1796     if (cmd_line->pid_path[0] != '\0')
1797         ConfigPidPath(config_file, cmd_line->pid_path);
1798 
1799     if( (config_file->alert_on_each_packet_in_stream_flag == 0) &&
1800 	(cmd_line->alert_on_each_packet_in_stream_flag == 1))
1801     {
1802 	config_file->alert_on_each_packet_in_stream_flag = 0;
1803     }
1804     else
1805     {
1806 	config_file->alert_on_each_packet_in_stream_flag  = cmd_line->alert_on_each_packet_in_stream_flag;
1807     }
1808 
1809     config_file->process_new_records_only_flag = cmd_line->process_new_records_only_flag;
1810 
1811 #ifdef SUP_IP6
1812     if (cmd_line->obfuscation_net.family != 0)
1813         memcpy(&config_file->obfuscation_net, &cmd_line->obfuscation_net, sizeof(sfip_t));
1814 
1815     if (cmd_line->homenet.family != 0)
1816         memcpy(&config_file->homenet, &cmd_line->homenet, sizeof(sfip_t));
1817 #else
1818     if (cmd_line->obfuscation_mask != 0)
1819     {
1820         config_file->obfuscation_mask = cmd_line->obfuscation_mask;
1821         config_file->obfuscation_net = cmd_line->obfuscation_net;
1822     }
1823 
1824     if (cmd_line->netmask != 0)
1825     {
1826         config_file->netmask = cmd_line->netmask;
1827         config_file->homenet = cmd_line->homenet;
1828     }
1829 #endif
1830 
1831     if (cmd_line->hostname != NULL)
1832     {
1833         if (config_file->hostname != NULL)
1834             free(config_file->hostname);
1835         config_file->hostname = SnortStrdup(cmd_line->hostname);
1836     }
1837 
1838     if (cmd_line->interface != NULL)
1839     {
1840         if (config_file->interface != NULL)
1841             free(config_file->interface);
1842         config_file->interface = SnortStrdup(cmd_line->interface);
1843     }
1844 
1845     if (cmd_line->bpf_filter != NULL)
1846         config_file->bpf_filter = SnortStrdup(cmd_line->bpf_filter);
1847 
1848     if (cmd_line->group_id != -1)
1849         config_file->group_id = cmd_line->group_id;
1850 
1851     if (cmd_line->user_id != -1)
1852         config_file->user_id = cmd_line->user_id;
1853 
1854     if (cmd_line->archive_dir != NULL)
1855     {
1856         if (config_file->archive_dir != NULL)
1857             free(config_file->archive_dir);
1858 
1859         config_file->archive_dir = SnortStrdup(cmd_line->archive_dir);
1860     }
1861 
1862     /* Only configurable on command line */
1863     if (cmd_line->file_mask != 0)
1864         config_file->file_mask = cmd_line->file_mask;
1865 
1866     if (cmd_line->pidfile_suffix[0] != '\0')
1867     {
1868         SnortStrncpy(config_file->pidfile_suffix, cmd_line->pidfile_suffix,
1869                      sizeof(config_file->pidfile_suffix));
1870     }
1871 
1872     if (cmd_line->chroot_dir != NULL)
1873     {
1874         if (config_file->chroot_dir != NULL)
1875             free(config_file->chroot_dir);
1876         config_file->chroot_dir = SnortStrdup(cmd_line->chroot_dir);
1877     }
1878 
1879     /* waldo file components */
1880     if (cmd_line->waldo.data.spool_filebase[0] != '\0')
1881     {
1882         ConfigSpoolFilebase(config_file, cmd_line->waldo.data.spool_filebase);
1883     }
1884 
1885     if (cmd_line->waldo.data.spool_dir[0] != '\0')
1886     {
1887         ConfigSpoolDirectory(config_file, cmd_line->waldo.data.spool_dir);
1888     }
1889 
1890     if (cmd_line->waldo.filepath[0] != '\0')
1891     {
1892         ConfigWaldoFile(config_file, cmd_line->waldo.filepath);
1893     }
1894 
1895     /* batch list */
1896     if (cmd_line->batch_total_files > 0 )
1897     {
1898         config_file->batch_total_files = cmd_line->batch_total_files;
1899         config_file->batch_filelist = cmd_line->batch_filelist;
1900         cmd_line->batch_filelist = NULL;
1901         cmd_line->batch_total_files = 0;
1902     }
1903 
1904     return config_file;
1905 }
1906 
FreeVarList(VarNode * head)1907 void FreeVarList(VarNode *head)
1908 {
1909     while (head != NULL)
1910     {
1911         VarNode *tmp = head;
1912 
1913         head = head->next;
1914 
1915         if (tmp->name != NULL)
1916             free(tmp->name);
1917 
1918         if (tmp->value != NULL)
1919             free(tmp->value);
1920 
1921         if (tmp->line != NULL)
1922             free(tmp->line);
1923 
1924         free(tmp);
1925     }
1926 }
1927 
Barnyard2Init(int argc,char ** argv)1928 static void Barnyard2Init(int argc, char **argv)
1929 {
1930     InitGlobals();
1931 
1932     /* chew up the command line */
1933     ParseCmdLine(argc, argv);
1934 
1935     switch (barnyard2_conf->run_mode)
1936     {
1937         case RUN_MODE__VERSION:
1938             break;
1939 
1940         case RUN_MODE__CONTINUOUS:
1941             LogMessage("Running in Continuous mode\n");
1942             break;
1943 
1944         case RUN_MODE__BATCH:
1945             LogMessage("Running in Batch mode\n");
1946             break;
1947 
1948         case RUN_MODE__TEST:
1949             LogMessage("Running in Test mode\n");
1950             break;
1951 
1952         default:
1953             break;
1954     }
1955 
1956     LogMessage("\n");
1957     LogMessage("        --== Initializing Barnyard2 ==--\n");
1958 
1959     if (!BcVersionMode())
1960     {
1961         /* Every run mode except version will potentially need output
1962          * If output plugins should become dynamic, this needs to move */
1963         RegisterInputPlugins();
1964         RegisterOutputPlugins();
1965     }
1966 
1967     /* if we're using the rules system, it gets initialized here */
1968     if (barnyard2_conf_file != NULL)
1969     {
1970         Barnyard2Config *bc;
1971 
1972         /* initialize all the plugin modules */
1973 //        RegisterPreprocessors();
1974 
1975 #ifdef DEBUG
1976 //        DumpPreprocessors();
1977 #endif
1978 
1979         LogMessage("Parsing config file \"%s\"\n", barnyard2_conf_file);
1980         bc = ParseBarnyard2Conf();
1981 
1982         bc->config_dir = strdup(barnyard2_conf_dir);
1983         bc->config_file = strdup(barnyard2_conf_file);
1984 
1985         /* Merge the command line and config file confs to take care of
1986          * command line overriding config file.
1987          * Set the global barnyard2_conf that will be used during run time */
1988         barnyard2_conf = MergeBarnyard2Confs(barnyard2_cmd_line_conf, bc);
1989 
1990 	DisplaySigSuppress(BCGetSigSuppressHead());
1991 
1992 	if(ReadSidFile(barnyard2_conf))
1993 	{
1994 	    FatalError("[%s()], failed while processing [%s] \n",
1995 		       __FUNCTION__,
1996 		       bc->sid_msg_file);
1997 	}
1998 
1999 	if(ReadGenFile(barnyard2_conf))
2000 	{
2001 	    FatalError("[%s()], failed while processing [%s] \n",
2002 		       __FUNCTION__,
2003 		       bc->gen_msg_file);
2004 	}
2005 
2006 	if(barnyard2_conf->event_cache_size == 0)
2007 	{
2008 	    barnyard2_conf->event_cache_size = 2048;
2009 	}
2010 
2011 	LogMessage("Barnyard2 spooler: Event cache size set to [%u] \n",
2012 		   barnyard2_conf->event_cache_size);
2013 
2014     }
2015 
2016     /* Resolve classification integer for signature and free some memory */
2017     if(barnyard2_conf->sidmap_version == SIDMAPV2)
2018     {
2019 	if(SignatureResolveClassification(barnyard2_conf->classifications,
2020 					  (SigNode *)*BcGetSigNodeHead(),
2021 					  barnyard2_conf->sid_msg_file,
2022 					  barnyard2_conf->class_file))
2023 	{
2024 	    FatalError("[%s()], Call to SignatureResolveClassification failed \n",
2025 		       __FUNCTION__);
2026 	}
2027     }
2028 
2029     /* pcap_snaplen is already initialized to SNAPLEN */
2030     //  if (barnyard2_conf->pkt_snaplen != -1)
2031     //      pcap_snaplen = (uint32_t)snort_conf->pkt_snaplen;
2032 
2033     /* Display barnyard2 version information here so that we can also show dynamic
2034      * plugin versions, if loaded.  */
2035     if (BcVersionMode())
2036     {
2037         PrintVersion();
2038         CleanExit(0);
2039     }
2040 
2041     /* Validate the log directory for logging packets - probably should
2042      * add test mode as well, but not expected behavior */
2043     if ((BcContinuousMode() || BcBatchMode()))
2044     {
2045         CheckLogDir();
2046         LogMessage("Log directory = %s\n", barnyard2_conf->log_dir);
2047     }
2048 
2049     if (BcOutputUseUtc())
2050         barnyard2_conf->thiszone = 0;
2051     else
2052         barnyard2_conf->thiszone = gmt2local(0);  /* ripped from tcpdump */
2053 
2054     ConfigureInputPlugins(barnyard2_conf);
2055     ConfigureOutputPlugins(barnyard2_conf);
2056 
2057     if (BcContinuousMode() || BcBatchMode() || BcTestMode())
2058     {
2059         /* Have to split up configuring preprocessors between internal and dynamic
2060          * because the dpd structure has a pointer to the stream api and stream5
2061          * needs to be configured first to set this */
2062 //        ConfigurePreprocessors(snort_conf, 0);
2063     }
2064 
2065     if (barnyard2_conf->file_mask != 0)
2066         umask(barnyard2_conf->file_mask);
2067     else
2068         umask(077);    /* set default to be sane */
2069 
2070 }
2071 
Barnyard2PostInit(void)2072 static void Barnyard2PostInit(void)
2073 {
2074     InitPidChrootAndPrivs();
2075 
2076 #ifdef HAVE_LIBPRELUDE
2077     AlertPreludeSetupAfterSetuid();
2078 #endif
2079 
2080     PostConfigInitPlugins(barnyard2_conf->plugin_post_config_funcs);
2081 
2082 #ifdef DEBUG
2083         DumpInputPlugins();
2084         DumpOutputPlugins();
2085 #endif
2086 
2087     LogMessage("\n");
2088     LogMessage("        --== Initialization Complete ==--\n");
2089 
2090     /* Tell 'em who wrote it, and what "it" is */
2091     if (!BcLogQuiet())
2092         PrintVersion();
2093 
2094     if (BcTestMode())
2095     {
2096         LogMessage("\n");
2097         LogMessage("Barnyard2 successfully loaded configuration file!\n");
2098         CleanExit(0);
2099     }
2100 
2101     if (BcDaemonMode())
2102     {
2103         LogMessage("Barnyard2 initialization completed successfully (pid=%u)\n",getpid());
2104     }
2105 
2106     barnyard2_initializing = 0;
2107 }
2108 
2109 #if defined(NOCOREFILE) && !defined(WIN32)
SetNoCores(void)2110 static void SetNoCores(void)
2111 {
2112     struct rlimit rlim;
2113 
2114     getrlimit(RLIMIT_CORE, &rlim);
2115     rlim.rlim_max = 0;
2116     setrlimit(RLIMIT_CORE, &rlim);
2117 }
2118 #endif
2119 
InitSignals(void)2120 static void InitSignals(void)
2121 {
2122 #if !defined(WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) && \
2123     !defined( __CYGWIN64__)
2124 # if defined(LINUX) || defined(FREEBSD) || defined(OPENBSD) || \
2125      defined(SOLARIS) || defined(BSD) || defined(MACOS)
2126     sigset_t set;
2127 
2128     sigemptyset(&set);
2129 #  if defined(HAVE_LIBPRELUDE)
2130     pthread_sigmask(SIG_SETMASK, &set, NULL);
2131 #  else
2132     sigprocmask(SIG_SETMASK, &set, NULL);
2133 #  endif /* HAVE_LIBPRELUDE */
2134 # else
2135     sigsetmask(0);
2136 # endif /* LINUX, BSD, SOLARIS */
2137 #endif  /* !WIN32 */
2138 
2139     /* Make this prog behave nicely when signals come along.
2140      * Windows doesn't like all of these signals, and will
2141      * set errno for some.  Ignore/reset this error so it
2142      * doesn't interfere with later checks of errno value.  */
2143     signal(SIGTERM, SigExitHandler);
2144     signal(SIGINT, SigExitHandler);
2145     signal(SIGQUIT, SigExitHandler);
2146     signal(SIGUSR1, SigUsrHandler);
2147 
2148 #ifdef TIMESTATS
2149     /* Establish a handler for SIGALRM signals and set an alarm to go off
2150      * in approximately one hour.  This is used to drop statistics at
2151      * an interval which the alarm will tell us to do. */
2152     signal(SIGALRM, SigAlrmHandler);
2153 #endif
2154 
2155     signal(SIGHUP, SigHupHandler);
2156 
2157     errno = 0;
2158 }
2159 
FreeInputConfigs(InputConfig * head)2160 static void FreeInputConfigs(InputConfig *head)
2161 {
2162     while (head != NULL)
2163     {
2164         InputConfig *tmp = head;
2165 
2166         head = head->next;
2167 
2168         if (tmp->keyword != NULL)
2169             free(tmp->keyword);
2170 
2171         if (tmp->opts != NULL)
2172             free(tmp->opts);
2173 
2174         if (tmp->file_name != NULL)
2175             free(tmp->file_name);
2176 
2177         free(tmp);
2178     }
2179 }
2180 
FreeOutputConfigs(OutputConfig * head)2181 static void FreeOutputConfigs(OutputConfig *head)
2182 {
2183     while (head != NULL)
2184     {
2185         OutputConfig *tmp = head;
2186 
2187         head = head->next;
2188 
2189         if (tmp->keyword != NULL)
2190             free(tmp->keyword);
2191 
2192         if (tmp->opts != NULL)
2193             free(tmp->opts);
2194 
2195         if (tmp->file_name != NULL)
2196             free(tmp->file_name);
2197 
2198         free(tmp);
2199     }
2200 }
2201 
2202