00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #ifdef HAVE_CONFIG_H
00048 #include "config.h"
00049 #endif
00050
00051 #include <errno.h>
00052 #include <sys/types.h>
00053 #include <stdlib.h>
00054 #include <unistd.h>
00055 #include <string.h>
00056 #ifdef TIMESTATS
00057 #include <signal.h>
00058 #include <time.h>
00059 #endif
00060 #ifdef HAVE_STRINGS_H
00061 #include <strings.h>
00062 #endif
00063 #include <sys/stat.h>
00064 #ifndef WIN32
00065 #include <grp.h>
00066 #include <pwd.h>
00067 #include <sys/socket.h>
00068 #include <netinet/in.h>
00069 #include <arpa/inet.h>
00070 #endif
00071 #include <timersub.h>
00072
00073 #include "snort.h"
00074 #include "rules.h"
00075 #include "plugbase.h"
00076 #include "signal.h"
00077 #include "debug.h"
00078 #include "util.h"
00079 #include "parser.h"
00080 #include "tag.h"
00081 #include "log.h"
00082 #include "detect.h"
00083 #include "mstring.h"
00084 #include "fpcreate.h"
00085 #include "fpdetect.h"
00086 #include "sfthreshold.h"
00087 #include "packet_time.h"
00088 #include "src/preprocessors/flow/flow_print.h"
00089 #include "src/detection-plugins/sp_flowbits.h"
00090 #include "src/preprocessors/spp_perfmonitor.h"
00091 #include "src/preprocessors/spp_bait_and_switch.h"
00092
00093 #ifdef HAVE_LIBPRELUDE
00094 #include "src/output-plugins/spo_alert_prelude.h"
00095 #endif
00096
00097 #include "event_queue.h"
00098 #include "asn1.h"
00099 #include "inline.h"
00100 #include "mpse.h"
00101
00102 #ifndef DLT_LANE8023
00103
00104
00105
00106
00107
00108 #define DLT_OLDPFLOG 17
00109 #endif
00110
00111
00112 extern OutputFuncNode *AlertList;
00113 extern OutputFuncNode *LogList;
00114 #ifdef TIMESTATS
00115 long start_time;
00116 #endif
00117
00118 extern int errno;
00119
00120
00121 #ifdef NFNETLINKQ
00122 extern u_int16_t nfqueue_num;
00123 extern struct nfq_handle *nfqh;
00124 extern struct nfq_q_handle *qhndl;
00125 #endif
00126
00127
00128 u_int8_t runMode = 0;
00129 PV pv;
00130 int datalink;
00131 char *progname;
00132 char **progargs;
00133 char *username;
00134 char *groupname;
00135 unsigned long userid = 0;
00136 unsigned long groupid = 0;
00137 struct passwd *pw;
00138 struct group *gr;
00139 char *pcap_cmd;
00140 char *pktidx;
00141 pcap_t *pd;
00142
00143 int g_drop_pkt;
00144
00145
00146 FILE *alert;
00147 FILE *binlog_ptr;
00148 int flow;
00149 int thiszone;
00150 PacketCount pc;
00151 u_long netmasks[33];
00152 struct pcap_pkthdr *g_pkthdr;
00153 u_char *g_pkt;
00154 u_long g_caplen;
00155 char *protocol_names[256];
00156 u_int snaplen;
00157
00158
00159 grinder_t grinder;
00160 runtime_config snort_runtime;
00161
00162
00163
00164
00165
00166 #ifndef _PATH_VARRUN
00167 char _PATH_VARRUN[STD_BUF];
00168 #endif
00169
00170 SFPERF sfPerf;
00171
00172
00173 static char *ConfigFileSearch();
00174 static int ProcessAlertCommandLine();
00175 static int ProcessLogCommandLine();
00176 static void Restart();
00177
00178
00179 static void SigTermHandler(int signal);
00180 static void SigIntHandler(int signal);
00181 static void SigQuitHandler(int signal);
00182 static void SigHupHandler(int signal);
00183 static void SigUsrHandler(int signal);
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 int main(int argc, char* argv[])
00199 {
00200 #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
00201
00202
00203
00204 if( argc > 1 &&
00205 ( _stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_INSTALL_CMDLINE_PARAM))==0 ||
00206 _stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_UNINSTALL_CMDLINE_PARAM))==0 ||
00207 _stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_SHOW_CMDLINE_PARAM))==0 ) )
00208 {
00209 FatalError("You must have a space after the '%s' command-line parameter\n",
00210 SERVICE_CMDLINE_PARAM);
00211 exit(0);
00212 }
00213
00214
00215 if( argc>1 && _stricmp(argv[1],SERVICE_CMDLINE_PARAM)==0)
00216 {
00217 return SnortServiceMain(argc, argv);
00218 }
00219 #endif
00220
00221 return SnortMain(argc,argv);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 int SnortMain(int argc, char *argv[])
00237 {
00238 #ifndef WIN32
00239 #if defined(LINUX) || defined(FREEBSD) || defined(OPENBSD) || defined(SOLARIS)
00240 sigset_t set;
00241
00242 sigemptyset(&set);
00243 sigprocmask(SIG_SETMASK, &set, NULL);
00244 #else
00245 sigsetmask(0);
00246 #endif
00247 #endif
00248
00249
00250
00251
00252
00253
00254
00255
00256 signal(SIGTERM, SigTermHandler); if(errno!=0) errno=0;
00257 signal(SIGINT, SigIntHandler); if(errno!=0) errno=0;
00258 signal(SIGQUIT, SigQuitHandler); if(errno!=0) errno=0;
00259 signal(SIGHUP, SigHupHandler); if(errno!=0) errno=0;
00260 signal(SIGUSR1, SigUsrHandler); if(errno!=0) errno=0;
00261 signal(SIGNAL_SNORT_ROTATE_STATS, SigUsrHandler);
00262 if(errno!=0) errno=0;
00263
00264
00265
00266
00267
00268 progname = argv[0];
00269 progargs = argv;
00270
00271 #ifdef WIN32
00272 if (!init_winsock())
00273 FatalError("Could not Initialize Winsock!\n");
00274 #endif
00275
00276 memset(&pv, 0, sizeof(PV));
00277
00278
00279
00280
00281 InitNetmasks();
00282 InitProtoNames();
00283
00284
00285
00286
00287
00288 fpInitDetectionEngine();
00289
00290
00291 pv.pkt_cnt = -1;
00292
00293
00294 pv.alert_filename = NULL;
00295
00296
00297 pv.alert_mode = ALERT_FULL;
00298
00299
00300 pv.assurance_mode = ASSURE_ALL;
00301
00302 pv.use_utc = 0;
00303
00304 pv.log_mode = 0;
00305
00306
00307
00308
00309 pv.quiet_flag = 0;
00310
00311
00312 pv.rotate_perf_file = 0;
00313
00314 InitDecoderFlags();
00315
00316
00317 pv.checksums_mode = DO_IP_CHECKSUMS | DO_TCP_CHECKSUMS |
00318 DO_UDP_CHECKSUMS | DO_ICMP_CHECKSUMS;
00319
00320
00321 pv.event_log_id = 0x0000;
00322
00323 #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
00324
00325 pv.terminate_service_flag = 0;
00326 pv.pause_service_flag = 0;
00327 #endif
00328
00329
00330 ParseCmdLine(argc, argv);
00331
00332
00333 if (userid != 0)
00334 signal(SIGHUP, SigCantHupHandler);
00335
00336
00337 if(pv.test_mode_flag)
00338 {
00339 if(!pv.quiet_flag)
00340 {
00341 if (pv.config_file)
00342 LogMessage("Running in Test mode with config file: %s\n",
00343 pv.config_file);
00344 else if((pv.config_file = ConfigFileSearch()))
00345 LogMessage("Running in Test mode with inferred config file: %s\n",
00346 pv.config_file);
00347 }
00348 }
00349
00350 if(pv.config_file)
00351 {
00352 runMode = MODE_IDS;
00353 if(!pv.quiet_flag)
00354 LogMessage("Running in IDS mode\n");
00355 }
00356 else if(pv.log_mode || pv.log_dir)
00357 {
00358 runMode = MODE_PACKET_LOG;
00359 if(!pv.quiet_flag)
00360 LogMessage("Running in packet logging mode\n");
00361 }
00362 else if(pv.verbose_flag)
00363 {
00364 runMode = MODE_PACKET_DUMP;
00365 if(!pv.quiet_flag)
00366 LogMessage("Running in packet dump mode\n");
00367 }
00368 else if((pv.config_file = ConfigFileSearch()))
00369 {
00370 runMode = MODE_IDS;
00371 if(!pv.quiet_flag)
00372 LogMessage("Running in IDS mode with inferred config file: %s\n",
00373 pv.config_file);
00374 }
00375 else
00376 {
00377
00378 DisplayBanner();
00379 ShowUsage(progname);
00380 PrintError("\n\nUh, you need to tell me to do something...\n\n");
00381 exit(1);
00382 }
00383
00384
00385
00386 if(!pv.log_dir)
00387 {
00388 if(!(pv.log_dir = strdup(DEFAULT_LOG_DIR)))
00389 FatalError("Out of memory setting default log dir\n");
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 if(runMode == MODE_PACKET_LOG)
00401 {
00402 CheckLogDir();
00403
00404 if(!pv.quiet_flag)
00405 {
00406 LogMessage("Log directory = %s\n", pv.log_dir);
00407 }
00408 }
00409
00410
00411 if(runMode == MODE_PACKET_LOG && !pv.log_mode)
00412 {
00413
00414 pv.log_mode = LOG_PCAP;
00415 }
00416
00417
00418
00419
00420
00421
00422 #ifdef GIDS
00423 #ifdef IPFW
00424
00425 if(!pv.divert_port)
00426 {
00427 pv.divert_port = 8000;
00428 }
00429
00430
00431 if(!pv.ipfw_reinject_rule)
00432 {
00433 pv.ipfw_reinject_rule = 0;
00434 }
00435
00436 #endif
00437
00438 if (InlineMode())
00439 {
00440 InitInline();
00441 }
00442 else
00443 #endif
00444
00445 if(!pv.readmode_flag && !pv.test_mode_flag)
00446 {
00447 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Opening interface: %s\n",
00448 PRINT_INTERFACE(pv.interface)););
00449
00450 OpenPcap();
00451 }
00452 else if(!pv.test_mode_flag)
00453 {
00454 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Opening file: %s\n",
00455 pv.readfile););
00456
00457
00458 OpenPcap();
00459 }
00460
00461
00462 if(pv.config_file)
00463 {
00464
00465 if(strrchr(pv.config_file,'/'))
00466 {
00467 char *tmp;
00468
00469 if(!(pv.config_dir = strdup(pv.config_file)))
00470 FatalError("Out of memory extracting config dir\n");
00471
00472 tmp = strrchr(pv.config_dir,'/');
00473 *(++tmp) = '\0';
00474 }
00475 else
00476 {
00477 #ifdef WIN32
00478
00479 if(strrchr(pv.config_file,'\\'))
00480 {
00481 char *tmp;
00482
00483 if(!(pv.config_dir = strdup(pv.config_file)))
00484 FatalError("Out of memory extracting config dir\n");
00485
00486 tmp = strrchr(pv.config_dir,'\\');
00487 *(++tmp) = '\0';
00488 }
00489 else
00490 #endif
00491 if(!(pv.config_dir = strdup("./")))
00492 FatalError("Out of memory extracting config dir\n");
00493 }
00494 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Config file = %s, config dir = "
00495 "%s\n", pv.config_file, pv.config_dir););
00496 }
00497
00498
00499 if(pv.use_utc == 1)
00500 {
00501 thiszone = 0;
00502 }
00503 else
00504 {
00505
00506 thiszone = gmt2local(0);
00507 }
00508
00509 if(!pv.quiet_flag)
00510 {
00511 LogMessage("\n --== Initializing Snort ==--\n");
00512 }
00513
00514 if(runMode == MODE_IDS && pv.rules_order_flag)
00515 {
00516 if(!pv.quiet_flag)
00517 {
00518 LogMessage("Rule application order changed to Pass->Alert->Log\n");
00519 }
00520 }
00521
00522
00523
00524
00525
00526 if(pv.daemon_flag)
00527 {
00528 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Entering daemon mode\n"););
00529 openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON );
00530 GoDaemon();
00531 }
00532
00533 #ifdef TIMESTATS
00534
00535
00536
00537 signal (SIGALRM, DropHourlyStats);
00538
00539
00540 alarm(3600);
00541 #endif
00542
00543 InitOutputPlugins();
00544
00545
00546
00547 if((runMode == MODE_IDS) || pv.log_mode || pv.daemon_flag
00548 || *pv.pidfile_suffix)
00549 {
00550
00551 if (!pv.readmode_flag && (pv.daemon_flag || *pv.pidfile_suffix))
00552 {
00553 #ifndef WIN32
00554 #ifdef GIDS
00555 if (InlineMode())
00556 {
00557 CreatePidFile("inline");
00558 }
00559 else
00560 {
00561 #else
00562 CreatePidFile(pv.interface);
00563 #endif
00564 #ifdef GIDS
00565 }
00566 #endif
00567 #else
00568 CreatePidFile("WIN32");
00569 #endif
00570 }
00571 }
00572
00573
00574 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Setting Packet Processor\n"););
00575
00576
00577 SetPktProcessor();
00578
00579
00580 if(runMode == MODE_IDS)
00581 {
00582
00583 InitPreprocessors();
00584 InitPlugIns();
00585 InitTag();
00586
00587 #ifdef DEBUG
00588 DumpPreprocessors();
00589 DumpPlugIns();
00590 DumpOutputPlugins();
00591 #endif
00592
00593
00594 CreateDefaultRules();
00595
00596 if(pv.rules_order_flag)
00597 {
00598 #ifdef GIDS
00599 #ifndef IPFW
00600 OrderRuleLists("activation dynamic pass drop sdrop reject alert log");
00601 #else
00602 OrderRuleLists("activation dynamic pass drop sdrop reject reinject alert log");
00603 #endif
00604 #else
00605 if(InlineMode())
00606 OrderRuleLists("activation dynamic pass drop alert log");
00607
00608 OrderRuleLists("pass activation dynamic alert log");
00609 #endif
00610 }
00611
00612 if(!(pv.quiet_flag && !pv.daemon_flag))
00613 LogMessage("Parsing Rules file %s\n", pv.config_file);
00614
00615 ParseRulesFile(pv.config_file, 0);
00616
00617 CheckLogDir();
00618
00619 OtnXMatchDataInitialize();
00620
00621 FlowBitsVerify();
00622
00623 asn1_init_mem(512);
00624
00625
00626
00627
00628 SnortEventqInit();
00629
00630 #ifdef GIDS
00631 if (InlineMode())
00632 {
00633 InitInlinePostConfig();
00634 }
00635 #endif
00636
00637 if(!(pv.quiet_flag && !pv.daemon_flag))
00638 {
00639 print_thresholding();
00640 printRuleOrder();
00641 LogMessage("Log directory = %s\n", pv.log_dir);
00642 }
00643 }
00644
00645
00646 #ifndef WIN32
00647
00648 if(pv.chroot_dir)
00649 SetChroot(pv.chroot_dir, &pv.log_dir);
00650
00651
00652 SetUidGid();
00653
00654 #endif
00655
00656 #ifdef HAVE_LIBPRELUDE
00657 AlertPreludeSetupAfterSetuid();
00658 #endif
00659
00660
00661
00662
00663
00664
00665 if(runMode == MODE_IDS &&
00666 (pv.alert_cmd_override || !pv.alert_plugin_active))
00667 {
00668 ProcessAlertCommandLine();
00669 }
00670
00671
00672
00673
00674
00675
00676 if((runMode == MODE_IDS || runMode == MODE_PACKET_LOG) &&
00677 (pv.log_cmd_override || !pv.log_plugin_active))
00678 {
00679 ProcessLogCommandLine();
00680 }
00681
00682
00683
00684
00685
00686
00687 fpCreateFastPacketDetection();
00688
00689 if(!pv.quiet_flag)
00690 {
00691 mpsePrintSummary();
00692 }
00693
00694 if(!pv.quiet_flag)
00695 {
00696 LogMessage("\n --== Initialization Complete ==--\n");
00697 }
00698
00699
00700 if(!pv.quiet_flag)
00701 DisplayBanner();
00702
00703 if(pv.test_mode_flag)
00704 {
00705 LogMessage("\nSnort sucessfully loaded all rules and checked all rule "
00706 "chains!\n");
00707 CleanExit(0);
00708 }
00709
00710 if(pv.daemon_flag)
00711 {
00712 LogMessage("Snort initialization completed successfully (pid=%u)\n",getpid());
00713 }
00714
00715 #ifdef TIMESTATS
00716 start_time = time(&start_time);
00717 #endif
00718
00719 #ifdef GIDS
00720 if (InlineMode())
00721 {
00722 #ifdef NFNETLINKQ
00723 NfnetlinkQLoop();
00724 #else
00725 #ifndef IPFW
00726 IpqLoop();
00727 #else
00728 IpfwLoop();
00729 #endif
00730 #endif
00731 }
00732 else
00733 {
00734 #endif
00735
00736 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Entering pcap loop\n"););
00737
00738 InterfaceThread(NULL);
00739
00740 #ifdef GIDS
00741 }
00742 #endif
00743
00744 return 0;
00745 }
00746
00747
00748
00749 void PcapProcessPacket(char *user, struct pcap_pkthdr * pkthdr, u_char * pkt)
00750 {
00751 pc.total++;
00752
00753
00754
00755
00756 packet_time_update(pkthdr->ts.tv_sec);
00757
00758
00759
00760 sfthreshold_reset();
00761
00762 SnortEventqReset();
00763
00764 #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
00765 if( pv.terminate_service_flag || pv.pause_service_flag )
00766 {
00767 ClearDumpBuf();
00768 return;
00769 }
00770 #endif
00771
00772
00773 UpdateWireStats(&(sfPerf.sfBase), pkthdr->caplen);
00774
00775 ProcessPacket(user, pkthdr, pkt, NULL);
00776 return;
00777 }
00778
00779 void ProcessPacket(char *user, struct pcap_pkthdr * pkthdr, u_char * pkt, void *ft)
00780 {
00781 Packet p;
00782
00783
00784 p.packet_flags = 0;
00785 g_drop_pkt = 0;
00786
00787
00788 (*grinder) (&p, pkthdr, pkt);
00789
00790 if (ft)
00791 {
00792 p.packet_flags |= PKT_REBUILT_FRAG;
00793 p.fragtracker = ft;
00794 }
00795
00796
00797 if(pv.verbose_flag)
00798 {
00799 if(p.iph != NULL)
00800 PrintIPPkt(stdout, p.iph->ip_proto, &p);
00801 else if(p.ah != NULL)
00802 PrintArpHeader(stdout, &p);
00803 else if(p.eplh != NULL)
00804 {
00805 PrintEapolPkt(stdout, &p);
00806 }
00807 else if(p.wifih && pv.showwifimgmt_flag)
00808 {
00809 PrintWifiPkt(stdout, &p);
00810 }
00811 }
00812
00813 switch(runMode)
00814 {
00815 case MODE_PACKET_LOG:
00816 CallLogPlugins(&p, NULL, NULL, NULL);
00817 break;
00818 case MODE_IDS:
00819
00820
00821 if(pv.min_ttl && p.iph != NULL && (p.iph->ip_ttl < pv.min_ttl))
00822 {
00823 DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
00824 "MinTTL reached in main detection loop\n"););
00825 return;
00826 }
00827
00828
00829 if ( p.packet_flags & PKT_IGNORE_PORT )
00830 {
00831 return;
00832 }
00833
00834
00835 Preprocess(&p);
00836 break;
00837 default:
00838 break;
00839 }
00840
00841 ClearDumpBuf();
00842
00843 }
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855 int ShowUsage(char *progname)
00856 {
00857 fprintf(stdout, "USAGE: %s [-options] <filter options>\n", progname);
00858 #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
00859 fprintf(stdout, " %s %s %s [-options] <filter options>\n", progname
00860 , SERVICE_CMDLINE_PARAM
00861 , SERVICE_INSTALL_CMDLINE_PARAM);
00862 fprintf(stdout, " %s %s %s\n", progname
00863 , SERVICE_CMDLINE_PARAM
00864 , SERVICE_UNINSTALL_CMDLINE_PARAM);
00865 fprintf(stdout, " %s %s %s\n", progname
00866 , SERVICE_CMDLINE_PARAM
00867 , SERVICE_SHOW_CMDLINE_PARAM);
00868 #endif
00869
00870 #ifdef WIN32
00871 #define FPUTS_WIN32(msg) fputs(msg,stdout)
00872 #define FPUTS_UNIX(msg) NULL
00873 #define FPUTS_BOTH(msg) fputs(msg,stdout)
00874 #else
00875 #define FPUTS_WIN32(msg)
00876 #define FPUTS_UNIX(msg) fputs(msg,stdout)
00877 #define FPUTS_BOTH(msg) fputs(msg,stdout)
00878 #endif
00879
00880 FPUTS_BOTH ("Options:\n");
00881 FPUTS_BOTH (" -A Set alert mode: fast, full, console, or none "
00882 " (alert file alerts only)\n");
00883 FPUTS_UNIX (" \"unsock\" enables UNIX socket logging (experimental).\n");
00884 FPUTS_BOTH (" -b Log packets in tcpdump format (much faster!)\n");
00885 FPUTS_BOTH (" -c <rules> Use Rules File <rules>\n");
00886 FPUTS_BOTH (" -C Print out payloads with character data only (no hex)\n");
00887 FPUTS_BOTH (" -d Dump the Application Layer\n");
00888 FPUTS_UNIX (" -D Run Snort in background (daemon) mode\n");
00889 FPUTS_BOTH (" -e Display the second layer header info\n");
00890 FPUTS_WIN32(" -E Log alert messages to NT Eventlog. (Win32 only)\n");
00891 FPUTS_BOTH (" -f Turn off fflush() calls after binary log writes\n");
00892 FPUTS_BOTH (" -F <bpf> Read BPF filters from file <bpf>\n");
00893 FPUTS_UNIX (" -g <gname> Run snort gid as <gname> group (or gid) after initialization\n");
00894 FPUTS_BOTH (" -G <0xid> Log Identifier (to uniquely id events for multiple snorts)\n");
00895 FPUTS_BOTH (" -h <hn> Home network = <hn>\n");
00896 #ifdef NFNETLINKQ
00897 FPUTS_UNIX (" -H <q-num> NFNETLINK QUEUE this snort listens on (0-65535) - multiple snorts\n");
00898 #endif
00899 FPUTS_BOTH (" -i <if> Listen on interface <if>\n");
00900 FPUTS_BOTH (" -I Add Interface name to alert output\n");
00901 #ifdef GIDS
00902 #ifdef IPFW
00903 FPUTS_BOTH (" -J <port> ipfw divert socket <port> to listen on vice libpcap (FreeBSD only)\n");
00904 #endif
00905 #endif
00906 FPUTS_BOTH (" -k <mode> Checksum mode (all,noip,notcp,noudp,noicmp,none)\n");
00907 FPUTS_BOTH (" -K <mode> Logging mode (pcap[default],ascii,none)\n");
00908 FPUTS_BOTH (" -l <ld> Log to directory <ld>\n");
00909 FPUTS_BOTH (" -L <file> Log to this tcpdump file\n");
00910 FPUTS_UNIX (" -m <umask> Set umask = <umask>\n");
00911 FPUTS_BOTH (" -n <cnt> Exit after receiving <cnt> packets\n");
00912 FPUTS_BOTH (" -N Turn off logging (alerts still work)\n");
00913 FPUTS_BOTH (" -o Change the rule testing order to Pass|Alert|Log\n");
00914 FPUTS_BOTH (" -O Obfuscate the logged IP addresses\n");
00915 FPUTS_BOTH (" -p Disable promiscuous mode sniffing\n");
00916 fprintf(stdout, " -P <snap> Set explicit snaplen of packet (default: %d)\n",
00917 SNAPLEN);
00918 FPUTS_BOTH (" -q Quiet. Don't show banner and status report\n");
00919 #ifdef GIDS
00920 #ifndef IPFW
00921 FPUTS_BOTH (" -Q Use ip_queue for input vice libpcap (iptables only)\n");
00922 #endif
00923 #endif
00924 FPUTS_BOTH (" -r <tf> Read and process tcpdump file <tf>\n");
00925 FPUTS_BOTH (" -R <id> Include 'id' in snort_intf<id>.pid file name\n");
00926 FPUTS_BOTH (" -s Log alert messages to syslog\n");
00927 FPUTS_BOTH (" -S <n=v> Set rules file variable n equal to value v\n");
00928 FPUTS_UNIX (" -t <dir> Chroots process to <dir> after initialization\n");
00929 FPUTS_BOTH (" -T Test and report on the current Snort configuration\n");
00930 FPUTS_UNIX (" -u <uname> Run snort uid as <uname> user (or uid) after initialization\n");
00931 FPUTS_BOTH (" -U Use UTC for timestamps\n");
00932 FPUTS_BOTH (" -v Be verbose\n");
00933 FPUTS_BOTH (" -V Show version number\n");
00934 FPUTS_WIN32(" -W Lists available interfaces. (Win32 only)\n");
00935 #ifdef DLT_IEEE802_11
00936 FPUTS_BOTH (" -w Dump 802.11 management and control frames\n");
00937 #endif
00938 FPUTS_BOTH (" -X Dump the raw packet data starting at the link layer\n");
00939 FPUTS_BOTH (" -y Include year in timestamp in the alert and log files\n");
00940 FPUTS_BOTH (" -Z Set the performonitor preprocessor file path and name\n");
00941 FPUTS_BOTH (" -z Set assurance mode, match on established sesions (for TCP)\n");
00942 FPUTS_BOTH (" -? Show this information\n");
00943 FPUTS_BOTH ("<Filter Options> are standard BPF options, as seen in TCPDump\n");
00944
00945 #undef FPUTS_WIN32
00946 #undef FPUTS_UNIX
00947 #undef FPUTS_BOTH
00948
00949 return 0;
00950 }
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 extern char *optarg;
00965 extern int optind,opterr,optopt;
00966
00967 int ParseCmdLine(int argc, char *argv[])
00968 {
00969 int ch;
00970 int read_bpf = 0;
00971 char bpf_file[STD_BUF];
00972 char *eq_n;
00973 char *eq_p;
00974 char errorbuf[PCAP_ERRBUF_SIZE];
00975 int umaskchange = 1;
00976 int defumask = 0;
00977 #ifdef WIN32
00978 char *devicet;
00979 int adaplen;
00980 #endif
00981 char *valid_options;
00982 #ifndef WIN32
00983 int i;
00984 #endif
00985 int isName = 0;
00986
00987 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Parsing command line...\n"););
00988
00989 pv.promisc_flag = 1;
00990
00991
00992 username = NULL;
00993 groupname = NULL;
00994 pv.pidfile_suffix[0] = 0;
00995
00996
00997
00998
00999
01000
01001
01002 optopt = 0;
01003
01004 #ifndef WIN32
01005 #ifdef GIDS
01006 #ifndef IPFW
01007 #ifdef NFNETLINKQ
01008 valid_options = "?A:bB:c:CdDefF:g:G:h:H:i:Ik:K:l:L:m:n:NoOpP:qQr:R:sS:t:Tu:UvVwXyzZ:";
01009 #else
01010 valid_options = "?A:bB:c:CdDefF:g:G:h:i:Ik:K:l:L:m:n:NoOpP:qQr:R:sS:t:Tu:UvVwXyzZ:";
01011 #endif
01012
01013 #else
01014 valid_options = "?A:bB:c:CdDefF:g:G:h:i:IJ:k:K:l:L:m:n:NoOpP:qr:R:sS:t:Tu:UvVwXyzZ:";
01015 #endif
01016 #else
01017
01018 valid_options = "?A:bB:c:CdDefF:g:G:h:i:Ik:K:l:L:m:n:NoOpP:qQr:R:sS:t:Tu:UvVwXyzZ:";
01019 #endif
01020 #else
01021
01022
01023 valid_options = "?A:bB:c:CdeEfF:G:h:i:Ik:K:l:L:n:NoOpP:qr:R:sS:TUvVwWXyzZ:";
01024 #endif
01025
01026
01027 while((ch = getopt(argc, argv, valid_options)) != -1)
01028 {
01029 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Processing cmd line switch: %c\n", ch););
01030 switch(ch)
01031 {
01032 case 'A':
01033 if(!strcasecmp(optarg, "none"))
01034 {
01035 pv.alert_mode = ALERT_NONE;
01036 }
01037 else if(!strcasecmp(optarg, "full"))
01038 {
01039 pv.alert_mode = ALERT_FULL;
01040 }
01041 else if(!strcasecmp(optarg, "fast"))
01042 {
01043 pv.alert_mode = ALERT_FAST;
01044 }
01045 else if(!strcasecmp(optarg, "console"))
01046 {
01047 pv.alert_mode = ALERT_STDOUT;
01048 }
01049 else if(!strcasecmp(optarg, "cmg"))
01050 {
01051 pv.alert_mode = ALERT_CMG;
01052
01053 pv.log_mode = LOG_NONE;
01054 pv.log_cmd_override = 1;
01055
01056 pv.show2hdr_flag = 1;
01057
01058 pv.data_flag = 1;
01059 }
01060 else if(!strcasecmp(optarg, "unsock"))
01061 {
01062 pv.alert_mode = ALERT_UNSOCK;
01063 }
01064 else
01065 {
01066 FatalError("Unknown command line alert option: %s\n", optarg);
01067 }
01068
01069
01070
01071
01072 pv.alert_cmd_override = 1;
01073 break;
01074
01075 case 'b':
01076
01077 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Tcpdump logging mode "
01078 "active\n"););
01079 pv.log_mode = LOG_PCAP;
01080 pv.log_cmd_override = 1;
01081 break;
01082
01083 case 'B':
01084 pv.obfuscation_flag = 1;
01085 GenObfuscationMask(optarg);
01086 break;
01087
01088 case 'c':
01089 if(!(pv.config_file = strdup(optarg)))
01090 FatalError("Out of memory processing command line\n");
01091 break;
01092
01093 case 'C':
01094 pv.char_data_flag = 1;
01095 break;
01096
01097 case 'd':
01098 pv.data_flag = 1;
01099 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Data Flag active\n"););
01100 break;
01101
01102 case 'D':
01103 #ifdef WIN32
01104 FatalError("Setting the Daemon mode is not supported in the "
01105 "WIN32 port of snort! Use 'snort /SERVICE ...' "
01106 "instead\n");
01107 #endif
01108 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Daemon mode flag set\n"););
01109 pv.daemon_flag = 1;
01110 flow_set_daemon();
01111 pv.quiet_flag = 1;
01112 if (pv.test_mode_flag)
01113 {
01114 FatalError("Cannot use test mode and daemon mode together."
01115 "\nTo verify configuration run first in test "
01116 "mode and then restart in daemon mode\n");
01117 }
01118 break;
01119
01120 case 'e':
01121 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Show 2nd level active\n"););
01122 pv.show2hdr_flag = 1;
01123 break;
01124
01125 #ifdef WIN32
01126 case 'E':
01127 pv.alert_mode = ALERT_SYSLOG;
01128 pv.syslog_remote_flag = 0;
01129 pv.alert_cmd_override = 1;
01130 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Logging alerts to Event "
01131 "Log\n"););
01132 break;
01133 #endif
01134 case 'f':
01135 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Pcap linebuffering "
01136 "activated\n"););
01137 pv.line_buffer_flag = 1;
01138 break;
01139
01140 case 'F':
01141 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Tcpdump logging mode "
01142 "active\n"););
01143 strlcpy(bpf_file, optarg, STD_BUF);
01144 read_bpf = 1;
01145 break;
01146
01147 case 'g':
01148 #ifdef WIN32
01149 FatalError("Setting the group id is not supported in the WIN32 port of snort!\n");
01150 #else
01151 if(groupname != NULL)
01152 free(groupname);
01153 if((groupname = calloc(strlen(optarg) + 1, 1)) == NULL)
01154 FatalPrintError("malloc");
01155
01156 bcopy(optarg, groupname, strlen(optarg));
01157
01158 isName = 0;
01159 for (i=0;i<strlen(groupname);i++)
01160 {
01161 if (isdigit(groupname[i]) == 0)
01162 {
01163 isName = 1;
01164 break;
01165 }
01166 }
01167 if (((groupid = atoi(groupname)) == 0) || isName)
01168 {
01169 gr = getgrnam(groupname);
01170 if(gr == NULL)
01171 FatalError("Group \"%s\" unknown\n", groupname);
01172
01173 groupid = gr->gr_gid;
01174 }
01175 #endif
01176 break;
01177
01178 case 'G':
01179 if (!strncmp(optarg, "0x", 2))
01180 {
01181 if (!sscanf(optarg, "0x%x", &pv.event_log_id))
01182 {
01183 pv.event_log_id = 0;
01184 }
01185 }
01186 else
01187 {
01188 char *endPtr;
01189 pv.event_log_id = strtoul(optarg, &endPtr, 0);
01190 if (endPtr == optarg)
01191 {
01192 FatalError("Snort log identifier invalid: %s\n",
01193 optarg);
01194 }
01195 }
01196 if (pv.event_log_id > 0xFFFF)
01197 {
01198 FatalError("Snort log identifier invalid: %d. It must "
01199 "be no larger than a 2 byte value\n",
01200 pv.event_log_id);
01201 }
01202 else
01203 {
01204 u_int32_t id = pv.event_log_id;
01205 pv.event_log_id = id << 16;
01206 }
01207 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Log ID: 0x%x\n", pv.event_log_id););
01208 break;
01209
01210 case 'h':
01211
01212
01213 GenHomenet(optarg);
01214 break;
01215
01216 #ifdef NFNETLINKQ
01217 case 'H':
01218 nfqueue_num = 0;
01219 nfqueue_num = atoi(optarg) % 65536;
01220 break;
01221 #endif
01222
01223 case 'i':
01224 if(pv.interface)
01225 {
01226 FatalError("Cannot specify more than one network "
01227 "interface on the command line.\n");
01228 }
01229 #ifdef WIN32
01230
01231
01232
01233
01234
01235
01236
01237 devicet = NULL;
01238 adaplen = atoi(optarg);
01239 if( adaplen > 0 )
01240 {
01241 devicet = pcap_lookupdev(errorbuf);
01242 if ( devicet == NULL )
01243 {
01244 perror(errorbuf);
01245 exit(1);
01246 }
01247
01248 pv.interface = GetAdapterFromList(devicet, adaplen);
01249 if ( pv.interface == NULL )
01250 {
01251 LogMessage("Invalid interface '%d'.\n", atoi(optarg));
01252 exit(1);
01253 }
01254
01255
01256 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Interface = %s\n",
01257 PRINT_INTERFACE(pv.interface)));
01258 }
01259 else
01260 #endif
01261
01262
01263
01264 {
01265 pv.interface = (char *)malloc(strlen(optarg) + 1);
01266
01267 strlcpy(pv.interface, optarg, strlen(optarg)+1);
01268 DEBUG_WRAP(DebugMessage(DEBUG_INIT,
01269 "Interface = %s\n",
01270 PRINT_INTERFACE(pv.interface)););
01271 }
01272 break;
01273
01274 case 'I':
01275 pv.alert_interface_flag = 1;
01276 break;
01277
01278 #ifdef GIDS
01279 #ifdef IPFW
01280 case 'J':
01281 LogMessage("Reading from ipfw divert socket\n");
01282 pv.inline_flag = 1;
01283 pv.divert_port = atoi(optarg);
01284 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Divert port set to: %d\n", pv.divert_port););
01285 LogMessage("IPFW Divert port set to: %d\n", pv.divert_port);
01286 pv.promisc_flag = 0;
01287 pv.interface = NULL;
01288 break;
01289 #endif
01290 #endif
01291
01292
01293 case 'k':
01294 if(!strcasecmp(optarg, "all"))
01295 {
01296 pv.checksums_mode = DO_IP_CHECKSUMS | DO_TCP_CHECKSUMS |
01297 DO_UDP_CHECKSUMS | DO_ICMP_CHECKSUMS;
01298 }
01299 else if(!strcasecmp(optarg, "noip"))
01300 {
01301 pv.checksums_mode ^= DO_IP_CHECKSUMS;
01302 }
01303 else if(!strcasecmp(optarg, "notcp"))
01304 {
01305 pv.checksums_mode ^= DO_TCP_CHECKSUMS;
01306 }
01307 else if(!strcasecmp(optarg, "noudp"))
01308 {
01309 pv.checksums_mode ^= DO_UDP_CHECKSUMS;
01310 }
01311 else if(!strcasecmp(optarg, "noicmp"))
01312 {
01313 pv.checksums_mode ^= DO_ICMP_CHECKSUMS;
01314 }
01315 if(!strcasecmp(optarg, "none"))
01316 {
01317 pv.checksums_mode = 0;
01318 }
01319 break;
01320
01321 case 'K':
01322 if(!strcasecmp(optarg, "none"))
01323 {
01324 pv.log_mode = LOG_NONE;
01325 pv.log_cmd_override = 1;
01326 }
01327 else if(!strcasecmp(optarg, "pcap"))
01328 {
01329 pv.log_mode = LOG_PCAP;
01330 pv.log_cmd_override = 1;
01331 }
01332 else if(!strcasecmp(optarg, "ascii"))
01333 {
01334 pv.log_mode = LOG_ASCII;
01335 pv.log_cmd_override = 1;
01336 }
01337 else
01338 {
01339 FatalError("Unknown command line log option: %s\n", optarg);
01340 }
01341 break;
01342
01343 case 'l':
01344 if(!(pv.log_dir = strdup(optarg)))
01345 {
01346 FatalError("Out of memory processing command line\n");
01347 }
01348
01349 if(access(pv.log_dir, 2) != 0)
01350 {
01351 FatalError("log directory '%s' does not exist\n",
01352 pv.log_dir);
01353 }
01354 break;
01355
01356 case 'L':
01357
01358 if (strlen(optarg) < 256)
01359 {
01360 pv.log_mode = LOG_PCAP;
01361 pv.binLogFile = strdup(optarg);
01362 pv.log_cmd_override = 1;
01363 }
01364 else
01365 {
01366 FatalError("ParseCmdLine, log file: %s, > than 256 characters\n",
01367 optarg);
01368 }
01369 break;
01370
01371 case 'm':
01372 #ifdef WIN32
01373 FatalError("Setting the umask is not supported in the "
01374 "WIN32 port of snort!\n");
01375 #endif
01376 {
01377 char *p;
01378 long val = 0;
01379
01380 umaskchange = 0;
01381
01382 val = strtol(optarg, &p, 8);
01383 if (*p != '\0' || val < 0 || (val & ~FILEACCESSBITS))
01384 {
01385 FatalError("bad umask %s\n", optarg);
01386 }
01387 else
01388 {
01389 defumask = val;
01390 }
01391 }
01392 break;
01393
01394 case 'n':
01395 pv.pkt_cnt = atoi(optarg);
01396 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Exiting after %d packets\n", pv.pkt_cnt););
01397 break;
01398
01399 case 'N':
01400 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Logging deactivated\n"););
01401 pv.log_mode = LOG_NONE;
01402 pv.log_cmd_override = 1;
01403 break;
01404
01405 case 'o':
01406
01407 pv.rules_order_flag = 1;
01408 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Rule application order changed to Pass->Alert->Log\n"););
01409 break;
01410
01411 case 'O':
01412
01413 pv.obfuscation_flag = 1;
01414 break;
01415
01416 case 'p':
01417 pv.promisc_flag = 0;
01418 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Promiscuous mode disabled!\n"););
01419 break;
01420
01421 case 'P':
01422 pv.pkt_snaplen = atoi(optarg);
01423 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Snaplength of Packets set to: %d\n", pv.pkt_snaplen););
01424 break;
01425
01426 case 'q':
01427 pv.quiet_flag = 1;
01428 break;
01429
01430 case 'Q':
01431 LogMessage("Reading from iptables\n");
01432 pv.inline_flag = 1;
01433 break;
01434
01435 case 'r':
01436
01437 strlcpy(pv.readfile, optarg, STD_BUF);
01438 pv.readmode_flag = 1;
01439 if(argc == 3)
01440 {
01441 LogMessage("No run mode specified, defaulting to verbose mode\n");
01442 pv.verbose_flag = 1;
01443 pv.data_flag = 1;
01444 }
01445 break;
01446
01447 case 'R':
01448 if (strlen(optarg) < MAX_PIDFILE_SUFFIX && strlen(optarg) > 0)
01449 {
01450 if (!strstr(optarg, "..") && !(strstr(optarg, "/")))
01451 {
01452 snprintf(pv.pidfile_suffix, MAX_PIDFILE_SUFFIX, "%s",
01453 optarg);
01454 }
01455 else
01456 {
01457 FatalError("ERROR: illegal pidfile suffix: %s\n",
01458 optarg);
01459 }
01460 }
01461 else
01462 {
01463 FatalError("ERROR: pidfile suffix length problem: %d\n",
01464 strlen(optarg) );
01465 }
01466 break;
01467
01468 case 's':
01469 pv.alert_mode = ALERT_SYSLOG;
01470 #ifndef WIN32
01471
01472
01473
01474 pv.alert_cmd_override = 1;
01475 #else
01476 pv.alert_cmd_override = 0;
01477 pv.syslog_remote_flag = 1;
01478 #endif
01479 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Logging alerts to "
01480 "syslog\n"););
01481 break;
01482
01483 case 'S':
01484 if((eq_p = strchr(optarg, '=')) != NULL)
01485 {
01486 struct VarEntry *p;
01487 int namesize = eq_p-optarg;
01488 eq_n = calloc(namesize+2, sizeof(char));
01489 strlcpy(eq_n, optarg, namesize+1);
01490 p = VarDefine(eq_n, eq_p + 1);
01491 p->flags |= VAR_STATIC;
01492 free(eq_n);
01493 }
01494 else
01495 {
01496 FatalError("Format for command line variable definitions "
01497 "is:\n -S var=value\n");
01498 }
01499 break;
01500
01501 case 't':
01502 #ifdef WIN32
01503 FatalError("Setting the chroot directory is not supported in "
01504 "the WIN32 port of snort!\n");
01505 #endif
01506 if(!(pv.chroot_dir = strdup(optarg)))
01507 FatalError("Out of memory processing command line\n");
01508 break;
01509
01510 case 'T':
01511 pv.test_mode_flag = 1;
01512 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Snort starting in test mode...\n"););
01513 if (pv.daemon_flag)
01514 {
01515 FatalError("Cannot use test mode and daemon mode together."
01516 "\nTo verify configuration run first in test "
01517 "mode and then restart in daemon mode\n");
01518 }
01519 break;
01520
01521 case 'u':
01522 #ifdef WIN32
01523 FatalError("Setting the user id is not "
01524 "supported in the WIN32 port of snort!\n");
01525 #else
01526 if((username = calloc(strlen(optarg) + 1, 1)) == NULL)
01527 FatalPrintError("malloc");
01528
01529 bcopy(optarg, username, strlen(optarg));
01530
01531 isName = 0;
01532 for (i=0;i<strlen(username);i++)
01533 {
01534 if (isdigit(username[i]) == 0)
01535 {
01536 isName = 1;
01537 break;
01538 }
01539 }
01540
01541 if (((userid = atoi(username)) == 0) || isName)
01542 {
01543 pw = getpwnam(username);
01544 if(pw == NULL)
01545 FatalError("User \"%s\" unknown\n", username);
01546
01547 userid = pw->pw_uid;
01548 }
01549 else
01550 {
01551 pw = getpwuid(userid);
01552 if(pw == NULL)
01553 FatalError(
01554 "Can not obtain username for uid: %lu\n",
01555 (u_long) userid);
01556 }
01557
01558 if(groupname == NULL)
01559 {
01560 char name[256];
01561
01562 snprintf(name, 255, "%lu", (u_long) pw->pw_gid);
01563
01564 if((groupname = calloc(strlen(name) + 1, 1)) == NULL)
01565 {
01566 FatalPrintError("malloc");
01567 }
01568 groupid = pw->pw_gid;
01569 }
01570 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "UserID: %lu GroupID: %lu\n",
01571 (unsigned long) userid, (unsigned long) groupid););
01572 #endif
01573 break;
01574
01575 case 'U':
01576 pv.use_utc = 1;
01577 break;
01578
01579 case 'v':
01580 pv.verbose_flag = 1;
01581 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Verbose Flag active\n"););
01582 break;
01583
01584 case 'V':
01585
01586 DisplayBanner();
01587 exit(0);
01588
01589 #ifdef WIN32
01590 case 'W':
01591 if ((pv.interface = pcap_lookupdev(errorbuf)) == NULL)
01592 perror(errorbuf);
01593
01594 DisplayBanner();
01595 PrintDeviceList(pv.interface);
01596 exit(0);
01597 break;
01598 #endif
01599
01600 #ifdef DLT_IEEE802_11
01601 case 'w':
01602 pv.showwifimgmt_flag = 1;
01603 break;
01604 #endif
01605
01606 case 'X':
01607 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Verbose packet bytecode dumps enabled\n"););
01608 pv.verbose_bytedump_flag = 1;
01609 break;
01610
01611 case 'y':
01612 pv.include_year = 1;
01613 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Enabled year in timestamp\n"););
01614 break;
01615
01616 case 'z':
01617 LogMessage("WARNING: The -z option will be deprecated in the "
01618 "next release of snort.\n Use the 'stateful' "
01619 "configuration option in snort.conf\n");
01620 pv.assurance_mode = ASSURE_EST;
01621 break;
01622
01623 case 'Z':
01624 SetPerfmonitorFile(optarg);
01625 break;
01626
01627 case '?':
01628 DisplayBanner();
01629 ShowUsage(progname);
01630
01631 if(optopt)
01632 exit(1);
01633
01634 exit(0);
01635 }
01636 }
01637
01638
01639
01640
01641 if (umaskchange)
01642 {
01643 umask(077);
01644 }
01645 else
01646 {
01647 umask(defumask);
01648 }
01649
01650
01651 if(read_bpf)
01652 {
01653
01654 pv.pcap_cmd = read_infile(bpf_file);
01655 }
01656 else
01657 {
01658
01659 pv.pcap_cmd = copy_argv(&argv[optind]);
01660 }
01661
01662 #ifndef MUST_SPECIFY_DEVICE
01663 if((pv.interface == NULL) && !pv.readmode_flag)
01664 {
01665 #ifdef GIDS
01666 if (!InlineMode())
01667 {
01668 #endif
01669 pv.interface = pcap_lookupdev(errorbuf);
01670
01671 if(pv.interface == NULL)
01672 FatalError( "Failed to lookup for interface: %s."
01673 " Please specify one with -i switch\n", errorbuf);
01674 else
01675 LogMessage("***\n*** interface device lookup found: %s\n***\n",pv.interface);
01676 #ifdef GIDS
01677 }
01678 #endif
01679 }
01680 #else
01681 if((pv.interface == NULL) && !pv.readmode_flag && !pv.test_mode_flag)
01682 {
01683 FatalError( "You must specify a network interface (-i), "
01684 "a capture file (-r), or the test flag (-T)\n");
01685 }
01686
01687 #endif
01688 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "pcap_cmd is %s\n",
01689 pv.pcap_cmd !=NULL ? pv.pcap_cmd : "NULL"););
01690 return 0;
01691 }
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703 int SetPktProcessor()
01704 {
01705 #ifdef GIDS
01706 if (InlineMode())
01707 {
01708
01709 #ifndef IPFW
01710 if(!pv.quiet_flag)
01711 LogMessage("Setting the Packet Processor to decode packets "
01712 "from iptables\n");
01713
01714 grinder = DecodeIptablesPkt;
01715 #else
01716 if(!pv.quiet_flag)
01717 LogMessage("Setting the Packet Processor to decode packets "
01718 "from ipfw divert\n");
01719
01720 grinder = DecodeIpfwPkt;
01721 #endif
01722
01723 return 0;
01724
01725 }
01726 #endif
01727
01728 switch(datalink)
01729 {
01730 case DLT_EN10MB:
01731 if(!pv.readmode_flag)
01732 {
01733 if(!pv.quiet_flag)
01734 LogMessage("Decoding Ethernet on interface %s\n",
01735 PRINT_INTERFACE(pv.interface));
01736 }
01737
01738 grinder = DecodeEthPkt;
01739 break;
01740
01741 #ifdef DLT_IEEE802_11
01742 case DLT_IEEE802_11:
01743 if (!pv.readmode_flag)
01744 {
01745 if (!pv.quiet_flag)
01746 LogMessage("Decoding IEEE 802.11 on interface %s\n",
01747 PRINT_INTERFACE(pv.interface));
01748 }
01749
01750 grinder = DecodeIEEE80211Pkt;
01751 break;
01752 #endif
01753 #ifdef DLT_ENC
01754 case DLT_ENC:
01755 if (!pv.readmode_flag)
01756 {
01757 if (!pv.quiet_flag)
01758 LogMessage("Decoding Encapsulated data on interface %s\n",
01759 PRINT_INTERFACE(pv.interface));
01760 }
01761
01762 grinder = DecodeEncPkt;
01763 break;
01764
01765 #else
01766 case 13:
01767 #endif
01768 case DLT_IEEE802:
01769 if(!pv.readmode_flag)
01770 {
01771 if(!pv.quiet_flag)
01772 LogMessage("Decoding Token Ring on interface %s\n",
01773 PRINT_INTERFACE(pv.interface));
01774 }
01775
01776 grinder = DecodeTRPkt;
01777
01778 break;
01779
01780 case DLT_FDDI:
01781 if(!pv.readmode_flag)
01782 {
01783 if(!pv.quiet_flag)
01784 LogMessage("Decoding FDDI on interface %s\n",
01785 PRINT_INTERFACE(pv.interface));
01786 }
01787
01788 grinder = DecodeFDDIPkt;
01789
01790 break;
01791
01792 #ifdef DLT_CHDLC
01793 case DLT_CHDLC:
01794 if (!pv.readmode_flag && !pv.quiet_flag)
01795 LogMessage("Decoding Cisco HDLC on interface %s\n",
01796 PRINT_INTERFACE(pv.interface));
01797
01798 grinder = DecodeChdlcPkt;
01799
01800 break;
01801 #endif
01802
01803 case DLT_SLIP:
01804 if(!pv.readmode_flag)
01805 {
01806 if(!pv.quiet_flag)
01807 LogMessage("Decoding Slip on interface %s\n",
01808 PRINT_INTERFACE(pv.interface));
01809 }
01810
01811 if(pv.show2hdr_flag == 1)
01812 {
01813 LogMessage("Second layer header parsing for this datalink "
01814 "isn't implemented yet\n");
01815
01816 pv.show2hdr_flag = 0;
01817 }
01818
01819 grinder = DecodeSlipPkt;
01820
01821 break;
01822
01823 case DLT_PPP:
01824 if(!pv.readmode_flag)
01825 {
01826 if(!pv.quiet_flag)
01827 LogMessage("Decoding PPP on interface %s\n",
01828 PRINT_INTERFACE(pv.interface));
01829 }
01830
01831 if(pv.show2hdr_flag == 1)
01832 {
01833
01834 LogMessage("Second layer header parsing for this datalink "
01835 "isn't implemented yet\n");
01836 pv.show2hdr_flag = 0;
01837 }
01838
01839 grinder = DecodePppPkt;
01840
01841 break;
01842
01843 #ifdef DLT_PPP_SERIAL
01844 case DLT_PPP_SERIAL:
01845 if(!pv.readmode_flag)
01846 {
01847 if(!pv.quiet_flag)
01848 LogMessage("Decoding PPP on interface %s\n",
01849 PRINT_INTERFACE(pv.interface));
01850 }
01851
01852 if(pv.show2hdr_flag == 1)
01853 {
01854
01855 LogMessage("Second layer header parsing for this datalink "
01856 "isn't implemented yet\n");
01857 pv.show2hdr_flag = 0;
01858 }
01859
01860 grinder = DecodePppSerialPkt;
01861
01862 break;
01863 #endif
01864
01865 #ifdef DLT_LINUX_SLL
01866 case DLT_LINUX_SLL:
01867 if(!pv.readmode_flag)
01868 {
01869 if(!pv.quiet_flag)
01870 LogMessage("Decoding 'ANY' on interface %s\n",
01871 PRINT_INTERFACE(pv.interface));
01872 }
01873
01874 grinder = DecodeLinuxSLLPkt;
01875
01876 break;
01877 #endif
01878
01879 #ifdef DLT_PFLOG
01880 case DLT_PFLOG:
01881 if(!pv.readmode_flag)
01882 {
01883 if(!pv.quiet_flag)
01884 LogMessage("Decoding OpenBSD PF log on interface %s\n",
01885 PRINT_INTERFACE(pv.interface));
01886 }
01887
01888 grinder = DecodePflog;
01889
01890 break;
01891 #endif
01892
01893 #ifdef DLT_OLDPFLOG
01894 case DLT_OLDPFLOG:
01895 if(!pv.readmode_flag)
01896 {
01897 if(!pv.quiet_flag)
01898 LogMessage("Decoding old OpenBSD PF log on interface %s\n",
01899 PRINT_INTERFACE(pv.interface));
01900 }
01901
01902 grinder = DecodeOldPflog;
01903
01904 break;
01905 #endif
01906
01907 #ifdef DLT_LOOP
01908 case DLT_LOOP:
01909 #endif
01910 case DLT_NULL:
01911
01912
01913 if(!pv.readmode_flag)
01914 {
01915 if(!pv.quiet_flag)
01916 {
01917 LogMessage("Decoding LoopBack on interface %s\n",
01918 PRINT_INTERFACE(pv.interface));
01919 }
01920 }
01921
01922 if(pv.show2hdr_flag == 1)
01923 {
01924 LogMessage("Data link layer header parsing for this network "
01925 " type isn't implemented yet\n");
01926 pv.show2hdr_flag = 0;
01927 }
01928 grinder = DecodeNullPkt;
01929
01930 break;
01931
01932 #ifdef DLT_RAW
01933
01934 case DLT_RAW:
01935 if(!pv.readmode_flag)
01936 {
01937 if(!pv.quiet_flag)
01938 LogMessage("Decoding raw data on interface %s\n",
01939 PRINT_INTERFACE(pv.interface));
01940 }
01941
01942 if(pv.show2hdr_flag == 1)
01943 {
01944 LogMessage("There's no second layer header available for "
01945 "this datalink\n");
01946 pv.show2hdr_flag = 0;
01947 }
01948 grinder = DecodeRawPkt;
01949
01950 break;
01951 #endif
01952
01953
01954
01955
01956 #ifdef DLT_I4L_RAWIP
01957 case DLT_I4L_RAWIP:
01958 if (! pv.readmode_flag && !pv.quiet_flag)
01959 LogMessage("Decoding I4L-rawip on interface %s\n",
01960 PRINT_INTERFACE(pv.interface));
01961
01962 grinder = DecodeI4LRawIPPkt;
01963
01964 break;
01965 #endif
01966
01967 #ifdef DLT_I4L_IP
01968 case DLT_I4L_IP:
01969 if (! pv.readmode_flag && !pv.quiet_flag)
01970 LogMessage("Decoding I4L-ip on interface %s\n",
01971 PRINT_INTERFACE(pv.interface));
01972
01973 grinder = DecodeEthPkt;
01974
01975 break;
01976 #endif
01977
01978 #ifdef DLT_I4L_CISCOHDLC
01979 case DLT_I4L_CISCOHDLC:
01980 if (! pv.readmode_flag && !pv.quiet_flag)
01981 LogMessage("Decoding I4L-cisco-h on interface %s\n",
01982 PRINT_INTERFACE(pv.interface));
01983
01984 grinder = DecodeI4LCiscoIPPkt;
01985
01986 break;
01987 #endif
01988
01989 default:
01990 ErrorMessage("\n%s cannot handle data link type %d\n",
01991 progname, datalink);
01992 CleanExit(1);
01993 }
01994
01995 return 0;
01996 }
01997
01998
01999
02000
02001
02002
02003
02004 static struct timeval starttime;
02005 static struct timeval endtime;
02006 void *InterfaceThread(void *arg)
02007 {
02008 struct timezone tz;
02009
02010 bzero((char *) &tz, sizeof(tz));
02011 gettimeofday(&starttime, &tz);
02012
02013
02014 if(pcap_loop(pd, pv.pkt_cnt, (pcap_handler) PcapProcessPacket, NULL) < 0)
02015 {
02016 if(pv.daemon_flag)
02017 syslog(LOG_PID | LOG_CONS | LOG_DAEMON,
02018 "pcap_loop: %s", pcap_geterr(pd));
02019 else
02020 ErrorMessage("pcap_loop: %s\n", pcap_geterr(pd));
02021
02022 CleanExit(1);
02023 }
02024
02025 pv.done_processing = 1;
02026
02027 CleanExit(0);
02028
02029 return NULL;
02030 }
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046 int OpenPcap()
02047 {
02048 bpf_u_int32 localnet, netmask;
02049 struct bpf_program fcode;
02050 char errorbuf[PCAP_ERRBUF_SIZE];
02051 bpf_u_int32 defaultnet = 0xFFFFFF00;
02052
02053
02054 if(pv.interface == NULL)
02055 {
02056 if (!pv.readmode_flag)
02057 {
02058 DEBUG_WRAP(DebugMessage(DEBUG_INIT,
02059 "pv.interface is NULL, looking up interface.... "););
02060
02061 pv.interface = pcap_lookupdev(errorbuf);
02062
02063 DEBUG_WRAP(DebugMessage(DEBUG_INIT,
02064 "found interface %s\n", PRINT_INTERFACE(pv.interface)););
02065
02066 if(pv.interface == NULL)
02067 {
02068 FatalError("OpenPcap() interface lookup: \n\t%s\n",
02069 errorbuf);
02070 }
02071 }
02072 else
02073 {
02074
02075
02076 pv.interface = "[reading from a file]";
02077 }
02078 }
02079
02080 if(!pv.quiet_flag)
02081 {
02082 if (!pv.readmode_flag)
02083 LogMessage("\nInitializing Network Interface %s\n",
02084 PRINT_INTERFACE(pv.interface));
02085 else
02086 LogMessage("TCPDUMP file reading mode.\n");
02087 }
02088
02089 if (!pv.readmode_flag)
02090 {
02091 if(pv.pkt_snaplen)
02092 {
02093 if(pv.pkt_snaplen < MIN_SNAPLEN)
02094
02095 {
02096
02097
02098
02099 snaplen = MIN_SNAPLEN;
02100 }
02101 else
02102 {
02103 snaplen = pv.pkt_snaplen;
02104 }
02105 }
02106 else
02107 {
02108 snaplen = SNAPLEN;
02109 }
02110
02111 DEBUG_WRAP(DebugMessage(DEBUG_INIT,
02112 "snaplength info: set=%d/compiled=%d/wanted=%d\n",
02113 snaplen, SNAPLEN, pv.pkt_snaplen););
02114
02115
02116 pd = pcap_open_live(pv.interface, snaplen,
02117 pv.promisc_flag ? PROMISC : 0, READ_TIMEOUT, errorbuf);
02118
02119 }
02120 else
02121 {
02122
02123 if (!pv.quiet_flag)
02124 {
02125 LogMessage("Reading network traffic from \"%s\" file.\n",
02126 pv.readfile);
02127 }
02128
02129 pd = pcap_open_offline(pv.readfile, errorbuf);
02130
02131
02132 if(pd == NULL)
02133 {
02134 FatalError("unable to open file \"%s\" for readback: %s\n",
02135 pv.readfile, errorbuf);
02136 }
02137
02138
02139
02140
02141 snaplen = pcap_snapshot(pd);
02142
02143 if(!pv.quiet_flag)
02144 LogMessage("snaplen = %d\n", snaplen);
02145 }
02146
02147
02148 if(pd == NULL)
02149 {
02150 if(strstr(errorbuf, "Permission denied"))
02151 {
02152 FatalError("You don't have permission to"
02153 " sniff.\nTry doing this as root.\n");
02154 }
02155 else
02156 {
02157 FatalError("OpenPcap() device %s open: \n\t%s\n",
02158 PRINT_INTERFACE(pv.interface), errorbuf);
02159 }
02160 }
02161
02162 if(pcap_lookupnet(pv.interface, &localnet, &netmask, errorbuf) < 0)
02163 {
02164 if (!pv.readmode_flag)
02165 {
02166 ErrorMessage("OpenPcap() device %s network lookup: \n"
02167 "\t%s\n",
02168 PRINT_INTERFACE(pv.interface), errorbuf);
02169
02170 }
02171
02172
02173
02174
02175 netmask = htonl(defaultnet);
02176 }
02177 else
02178 {
02179 DefineIfaceVar(PRINT_INTERFACE(pv.interface),
02180 (u_char *) &localnet,
02181 (u_char *) &netmask);
02182 }
02183
02184
02185 if(pcap_compile(pd, &fcode, pv.pcap_cmd, 1, netmask) < 0)
02186 {
02187 FatalError("OpenPcap() FSM compilation failed: \n\t%s\n"
02188 "PCAP command: %s\n", pcap_geterr(pd), pv.pcap_cmd);
02189 }
02190
02191 if(pcap_setfilter(pd, &fcode) < 0)
02192 {
02193 FatalError("OpenPcap() setfilter: \n\t%s\n",
02194 pcap_geterr(pd));
02195 }
02196
02197
02198 datalink = pcap_datalink(pd);
02199
02200 if(datalink < 0)
02201 {
02202 FatalError("OpenPcap() datalink grab: \n\t%s\n",
02203 pcap_geterr(pd));
02204 }
02205 return 0;
02206 }
02207
02208
02209
02210
02211
02212 static char *ConfigFileSearch()
02213 {
02214 struct stat st;
02215 int i;
02216 char *conf_files[]={"/etc/snort.conf", "./snort.conf", NULL};
02217 char *fname = NULL;
02218 char *home_dir = NULL;
02219 char *rval = NULL;
02220
02221 i = 0;
02222
02223
02224 while(conf_files[i])
02225 {
02226 fname = conf_files[i];
02227
02228 if(stat(fname, &st) != -1)
02229 {
02230 if(!(rval = strdup(fname)))
02231 FatalError("Out of memory searching for config file\n");
02232 break;
02233 }
02234 i++;
02235 }
02236
02237
02238 if(!rval)
02239 {
02240 if((home_dir = getenv("HOME")))
02241 {
02242
02243 fname = (char *)malloc(strlen(home_dir) + strlen("/.snortrc") + 1);
02244 if(!fname)
02245 FatalError("Out of memory searching for config file\n");
02246
02247 if(stat(fname, &st) != -1)
02248 rval = fname;
02249 else
02250 free(fname);
02251 }
02252 }
02253
02254 return rval;
02255 }
02256
02257 static int ProcessAlertCommandLine()
02258 {
02259
02260 if(!pv.alert_cmd_override)
02261 {
02262
02263 ActivateOutputPlugin("alert_full", NULL);
02264 }
02265 else
02266 {
02267 switch(pv.alert_mode)
02268 {
02269 case ALERT_FAST:
02270 ActivateOutputPlugin("alert_fast", NULL);
02271 break;
02272
02273 case ALERT_FULL:
02274 ActivateOutputPlugin("alert_full", NULL);
02275 break;
02276
02277 case ALERT_NONE:
02278 SetOutputList(NoAlert, NT_OUTPUT_ALERT, NULL);
02279 break;
02280
02281 case ALERT_UNSOCK:
02282 ActivateOutputPlugin("alert_unixsock", NULL);
02283 break;
02284
02285 case ALERT_STDOUT:
02286 ActivateOutputPlugin("alert_fast", "stdout");
02287 break;
02288
02289 case ALERT_CMG:
02290 ActivateOutputPlugin("alert_fast", "stdout packet");
02291 break;
02292
02293 case ALERT_SYSLOG:
02294 ActivateOutputPlugin("alert_syslog", NULL);
02295 break;
02296
02297 default:
02298 FatalError("Unknown alert mode %u\n", pv.alert_mode);
02299 break;
02300 }
02301 }
02302
02303 return 0;
02304 }
02305
02306 static int ProcessLogCommandLine()
02307 {
02308 if(!pv.log_cmd_override)
02309 {
02310 ActivateOutputPlugin("log_tcpdump", NULL);
02311 }
02312 else
02313 {
02314 switch(pv.log_mode)
02315 {
02316 case LOG_ASCII:
02317 ActivateOutputPlugin("log_ascii", NULL);
02318 break;
02319
02320 case LOG_PCAP:
02321 if(pv.binLogFile)
02322 ActivateOutputPlugin("log_tcpdump", pv.binLogFile);
02323 else
02324 ActivateOutputPlugin("log_tcpdump", NULL);
02325 break;
02326
02327 case LOG_NONE:
02328 SetOutputList(NoLog, NT_OUTPUT_LOG, NULL);
02329 break;
02330
02331 default:
02332 FatalError("Unknown log mode %u\n", pv.log_mode);
02333 }
02334 }
02335
02336 return 0;
02337 }
02338
02339
02340
02341 static void SigTermHandler(int signal)
02342 {
02343 CleanExit(0);
02344 }
02345
02346 static void SigIntHandler(int signal)
02347 {
02348 CleanExit(0);
02349 }
02350
02351 static void SigQuitHandler(int signal)
02352 {
02353 CleanExit(0);
02354 }
02355
02356 static void SigHupHandler(int signal)
02357 {
02358 Restart();
02359 }
02360
02361 static void SigUsrHandler(int signal)
02362 {
02363 int quiet_flag;
02364 #ifndef WIN32
02365 #if defined(LINUX) || defined(FREEBSD) || defined(OPENBSD) || defined(SOLARIS)
02366 sigset_t set;
02367
02368
02369 sigemptyset(&set);
02370 sigprocmask(SIG_SETMASK, &set, NULL);
02371 #else
02372 sigsetmask(0);
02373 #endif
02374 #endif
02375
02376 quiet_flag = pv.quiet_flag;
02377 pv.quiet_flag = 0;
02378
02379 if ( signal == SIGUSR1 )
02380 {
02381 DropStats(0);
02382 }
02383
02384 else if ( signal == SIGNAL_SNORT_ROTATE_STATS )
02385 {
02386 pv.rotate_perf_file = 1;
02387 }
02388
02389 pv.quiet_flag = quiet_flag;
02390 }
02391
02392
02393
02394
02395
02396
02397 void SigCantHupHandler(int signal)
02398 {
02399 LogMessage("Reload via Signal HUP does not work if you aren't root or are chroot'ed\n");
02400 }
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413 extern PluginSignalFuncNode *PluginShutdownList;
02414 extern PluginSignalFuncNode *PluginCleanExitList;
02415 extern PluginSignalFuncNode *PluginRestartList;
02416
02417 void CleanExit(int exit_val)
02418 {
02419 PluginSignalFuncNode *idx = NULL;
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429 static int already_exiting = 0;
02430 if( already_exiting != 0 )
02431 {
02432 return;
02433 }
02434 already_exiting = 1;
02435
02436 idx = PluginShutdownList;
02437 while(idx)
02438 {
02439 idx->func(SIGQUIT, idx->arg);
02440 idx = idx->next;
02441 }
02442
02443 if (pv.done_processing)
02444 {
02445 struct timeval difftime;
02446 struct timezone tz;
02447
02448 bzero((char *) &tz, sizeof(tz));
02449 gettimeofday(&endtime, &tz);
02450
02451 TIMERSUB(&endtime, &starttime, &difftime);
02452
02453 printf("Run time for packet processing was %lu.%lu seconds\n",
02454 (unsigned long)difftime.tv_sec, (unsigned long)difftime.tv_usec);
02455 }
02456
02457 #ifdef TIMESTATS
02458 alarm(0);
02459 #endif
02460
02461
02462 if(!pv.test_mode_flag)
02463 {
02464 fpShowEventStats();
02465 DropStats(0);
02466 }
02467
02468
02469 idx = PluginCleanExitList;
02470
02471
02472
02473 #ifdef GIDS
02474 #ifndef IPFW
02475 if (InlineMode())
02476 {
02477
02478 #ifndef NFNETLINKQ
02479 if (ipqh)
02480 {
02481 ipq_destroy_handle(ipqh);
02482 }
02483 #else
02484 if(qhndl)
02485 {
02486 nfq_destroy_queue(qhndl);
02487 nfq_close(nfqh);
02488 }
02489 #endif
02490
02491 RejectFuRestart();
02492
02493 if(BaitAndSwitchIsRunning())
02494 {
02495 LogMessage("Going to try to restore iptables rules %s\n",restorecmd);
02496
02497 if(system(restorecmd) !=0)
02498 {
02499 LogMessage("iptables restore cmd failed restore manually\n");
02500 }
02501 else
02502 {
02503 LogMessage("iptables rules restored ok now oink oink exit\n");
02504 }
02505 }
02506
02507
02508 }
02509 #else
02510 if (divert_socket)
02511 {
02512 close(divert_socket);
02513 }
02514
02515 #endif
02516 #endif
02517
02518 while(idx)
02519 {
02520 idx->func(SIGQUIT, idx->arg);
02521 idx = idx->next;
02522 }
02523
02524
02525
02526
02527 #ifdef GIDS
02528 if (pd && !InlineMode())
02529 #else
02530 if (pd)
02531 #endif
02532 pcap_close(pd);
02533
02534 LogMessage("Snort exiting\n");
02535
02536
02537 if(pv.pid_filename)
02538 unlink(pv.pid_filename);
02539
02540
02541 exit(exit_val);
02542 }
02543
02544 static void Restart()
02545 {
02546 PluginSignalFuncNode *idx = NULL;
02547
02548
02549 if(!pv.test_mode_flag)
02550 {
02551 fpShowEventStats();
02552 DropStats(0);
02553 }
02554
02555
02556
02557 idx = PluginRestartList;
02558
02559
02560
02561 #ifdef GIDS
02562 #ifndef IPFW
02563 if (InlineMode())
02564 {
02565
02566 #ifndef NFNETLINKQ
02567 if (ipqh)
02568 {
02569 ipq_destroy_handle(ipqh);
02570 }
02571 #else
02572 if(qhndl)
02573 {
02574 nfq_destroy_queue(qhndl);
02575 nfq_close(nfqh);
02576 }
02577 #endif
02578
02579 RejectFuRestart();
02580
02581 if(BaitAndSwitchIsRunning())
02582 {
02583 LogMessage("Going to try to restore iptables rules %s\n",restorecmd);
02584
02585 if(system(restorecmd) !=0)
02586 {
02587 LogMessage("iptables restore cmd failed restore manually\n");
02588 }
02589 else
02590 {
02591 LogMessage("iptables rules restored ok now oink oink exit\n");
02592 }
02593 }
02594
02595
02596 }
02597 #else
02598 if (divert_socket)
02599 {
02600 close(divert_socket);
02601 }
02602
02603 #endif
02604 #endif
02605
02606
02607 while(idx)
02608 {
02609 idx->func(SIGHUP, idx->arg);
02610 idx = idx->next;
02611 }
02612
02613
02614
02615
02616 if(pd)
02617 pcap_close(pd);
02618
02619
02620
02621 if(pv.pid_filename)
02622 unlink(pv.pid_filename);
02623 LogMessage("Restarting Snort\n");
02624
02625
02626 #ifdef PARANOID
02627 execv(progname, progargs);
02628 #else
02629 execvp(progname, progargs);
02630 #endif
02631
02632
02633 LogMessage("Restarting %s failed: %s\n", progname, strerror(errno));
02634 exit(1);
02635 }
02636