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