00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024
00025 #include <sys/types.h>
00026 #ifndef WIN32
00027 #include <sys/socket.h>
00028 #include <netinet/in.h>
00029 #include <arpa/inet.h>
00030 #endif
00031 #include <stdarg.h>
00032 #include <syslog.h>
00033 #include <errno.h>
00034 #include <sys/stat.h>
00035 #include <time.h>
00036 #include <signal.h>
00037 #include <unistd.h>
00038 #ifndef WIN32
00039 #include <grp.h>
00040 #include <pwd.h>
00041 #include <netdb.h>
00042 #include <limits.h>
00043 #endif
00044 #include <fcntl.h>
00045
00046 #ifdef HAVE_STRINGS_H
00047 #include <strings.h>
00048 #endif
00049
00050 #include "snort.h"
00051 #include "mstring.h"
00052 #include "debug.h"
00053 #include "util.h"
00054 #include "parser.h"
00055 #include "inline.h"
00056
00057 #ifdef WIN32
00058 #include "win32/WIN32-Code/name.h"
00059 #endif
00060
00061 #ifdef PATH_MAX
00062 #define PATH_MAX_UTIL PATH_MAX
00063 #else
00064 #define PATH_MAX_UTIL 1024
00065 #endif
00066
00067 #ifdef TIMESTATS
00068 extern long start_time;
00069 extern float prev_pkts;
00070 #endif
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 void GenHomenet(char *netdata)
00083 {
00084 struct in_addr net;
00085 char **toks;
00086 int num_toks;
00087 int nmask;
00088
00089
00090 toks = mSplit(netdata, "/", 2, &num_toks, 0);
00091
00092 if(num_toks > 1)
00093 {
00094
00095 nmask = atoi(toks[1]);
00096
00097 if((nmask > 0) && (nmask < 33))
00098 {
00099 pv.netmask = netmasks[nmask];
00100 }
00101 else
00102 {
00103 FatalError("Bad CIDR block [%s:%d], 1 to 32 please!\n",
00104 toks[1], nmask);
00105 }
00106 }
00107 else
00108 {
00109 FatalError("No netmask specified for home network!\n");
00110 }
00111
00112 pv.netmask = htonl(pv.netmask);
00113
00114 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "homenet netmask = %#8lX\n", pv.netmask););
00115
00116
00117 if((net.s_addr = inet_addr(toks[0])) == -1)
00118 {
00119 FatalError("Homenet (%s) didn't translate\n",
00120 toks[0]);
00121 }
00122 else
00123 {
00124 #ifdef DEBUG
00125 struct in_addr sin;
00126
00127 DebugMessage(DEBUG_INIT, "Net = %s (%X)\n", inet_ntoa(net), net.s_addr);
00128 #endif
00129
00130 pv.homenet = ((u_long) net.s_addr & pv.netmask);
00131
00132 #ifdef DEBUG
00133 sin.s_addr = pv.homenet;
00134 DebugMessage(DEBUG_INIT, "Homenet = %s (%X)\n", inet_ntoa(sin), sin.s_addr);
00135 #endif
00136 }
00137
00138 mSplitFree(&toks, num_toks);
00139 }
00140
00141
00142
00143 void GenObfuscationMask(char *netdata)
00144 {
00145 struct in_addr net;
00146 char **toks;
00147 int num_toks;
00148 int nmask;
00149
00150 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Got obfus data: %s\n", netdata););
00151
00152
00153 toks = mSplit(netdata, "/", 2, &num_toks, 0);
00154
00155 if(num_toks > 1)
00156 {
00157
00158 nmask = atoi(toks[1]);
00159
00160 if((nmask > 0) && (nmask < 33))
00161 {
00162 pv.obfuscation_mask = netmasks[nmask];
00163 }
00164 else
00165 {
00166 FatalError("Bad CIDR block in obfuscation mask [%s:%d], "
00167 "1 to 32 please!\n", toks[1], pv.obfuscation_mask);
00168 }
00169 }
00170 else
00171 {
00172 FatalError("No netmask specified for obsucation mask!\n");
00173 }
00174
00175 pv.obfuscation_mask = htonl(pv.obfuscation_mask);
00176
00177 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "obfuscation netmask = %#8lX\n",
00178 pv.obfuscation_mask););
00179
00180
00181 if((net.s_addr = inet_addr(toks[0])) == -1)
00182 {
00183 FatalError("Obfuscation mask (%s) didn't translate\n",
00184 toks[0]);
00185 }
00186 else
00187 {
00188 struct in_addr sin;
00189
00190 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Obfuscation Net = %s (%X)\n",
00191 inet_ntoa(net), net.s_addr););
00192
00193
00194 pv.obfuscation_net = ((u_long) net.s_addr & pv.obfuscation_mask);
00195
00196 sin.s_addr = pv.obfuscation_net;
00197 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Obfuscation Net = %s (%X)\n",
00198 inet_ntoa(sin), sin.s_addr););
00199 pv.obfuscation_mask = ~pv.obfuscation_mask;
00200 }
00201
00202 mSplitFree(&toks, num_toks);
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 void DefineIfaceVar(char *iname, u_char * network, u_char * netmask)
00215 {
00216 char valbuf[32];
00217 char varbuf[BUFSIZ];
00218
00219 snprintf(varbuf, BUFSIZ, "%s_ADDRESS", iname);
00220
00221 snprintf(valbuf, 32, "%d.%d.%d.%d/%d.%d.%d.%d",
00222 network[0] & 0xff, network[1] & 0xff, network[2] & 0xff,
00223 network[3] & 0xff, netmask[0] & 0xff, netmask[1] & 0xff,
00224 netmask[2] & 0xff, netmask[3] & 0xff);
00225
00226 VarDefine(varbuf, valbuf);
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 float CalcPct(float cnt, float total)
00243 {
00244 float pct;
00245
00246 if(cnt > 0.0)
00247 pct = cnt / total;
00248 else
00249 return 0.0;
00250
00251 pct *= 100.0;
00252
00253 return pct;
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 int DisplayBanner()
00269 {
00270 char * info;
00271
00272 info = getenv("HOSTTYPE");
00273 if( !info )
00274 {
00275 info="";
00276 }
00277
00278 fprintf(stderr, "\n"
00279 " ,,_ -*> Snort_Inline! <*-\n"
00280 " o\" )~ Version %s (Build %s) %s\n"
00281 " '''' By Martin Roesch & The Snort Team: http://www.snort.org/team.html\n"
00282 " (C) Copyright 1998-2005 Sourcefire Inc., et al.\n"
00283 " Snort_Inline Mod by William Metcalf, Victor Julien, Nick Rogness,\n"
00284 " Dave Remien, Rob McMillen and Jed Haile\n"
00285 " NOTE: Snort's default output has changed in version 2.4.1!\n"
00286 " The default logging mode is now PCAP, use \"-K ascii\" to activate\n"
00287 " the old default logging mode.\n"
00288 "\n"
00289 , VERSION, BUILD, info);
00290
00291 return 0;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 void ts_print(register const struct timeval *tvp, char *timebuf)
00311 {
00312 register int s;
00313 int localzone;
00314 time_t Time;
00315 struct timeval tv;
00316 struct timezone tz;
00317 struct tm *lt;
00318
00319
00320 if(!tvp)
00321 {
00322
00323 bzero((char *) &tz, sizeof(tz));
00324 gettimeofday(&tv, &tz);
00325 tvp = &tv;
00326 }
00327
00328 localzone = thiszone;
00329
00330
00331
00332
00333 if(pv.use_utc)
00334 localzone = 0;
00335
00336 s = (tvp->tv_sec + localzone) % 86400;
00337 Time = (tvp->tv_sec + localzone) - s;
00338
00339 lt = gmtime(&Time);
00340
00341 if(pv.include_year)
00342 {
00343 (void) snprintf(timebuf, TIMEBUF_SIZE,
00344 "%02d/%02d/%02d-%02d:%02d:%02d.%06u ",
00345 lt->tm_mon + 1, lt->tm_mday, lt->tm_year - 100,
00346 s / 3600, (s % 3600) / 60, s % 60,
00347 (u_int) tvp->tv_usec);
00348 }
00349 else
00350 {
00351 (void) snprintf(timebuf, TIMEBUF_SIZE,
00352 "%02d/%02d-%02d:%02d:%02d.%06u ", lt->tm_mon + 1,
00353 lt->tm_mday, s / 3600, (s % 3600) / 60, s % 60,
00354 (u_int) tvp->tv_usec);
00355 }
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 int gmt2local(time_t t)
00373 {
00374 register int dt, dir;
00375 register struct tm *gmt, *loc;
00376 struct tm sgmt;
00377
00378 if(t == 0)
00379 t = time(NULL);
00380
00381 gmt = &sgmt;
00382 *gmt = *gmtime(&t);
00383 loc = localtime(&t);
00384
00385 dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 +
00386 (loc->tm_min - gmt->tm_min) * 60;
00387
00388 dir = loc->tm_year - gmt->tm_year;
00389
00390 if(dir == 0)
00391 dir = loc->tm_yday - gmt->tm_yday;
00392
00393 dt += dir * 24 * 60 * 60;
00394
00395 return(dt);
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 char *copy_argv(char **argv)
00414 {
00415 char **p;
00416 u_int len = 0;
00417 char *buf;
00418 char *src, *dst;
00419 void ftlerr(char *,...);
00420
00421 p = argv;
00422 if(*p == 0)
00423 return 0;
00424
00425 while(*p)
00426 len += strlen(*p++) + 1;
00427
00428 buf = (char *) malloc(len);
00429
00430 if(buf == NULL)
00431 {
00432 FatalError("malloc() failed: %s\n", strerror(errno));
00433 }
00434 p = argv;
00435 dst = buf;
00436
00437 while((src = *p++) != NULL)
00438 {
00439 while((*dst++ = *src++) != '\0');
00440 dst[-1] = ' ';
00441 }
00442
00443 dst[-1] = '\0';
00444
00445 return buf;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 int strip(char *data)
00462 {
00463 int size;
00464 char *end;
00465 char *idx;
00466
00467 idx = data;
00468 end = data + strlen(data);
00469 size = end - idx;
00470
00471 while(idx != end)
00472 {
00473 if((*idx == '\n') ||
00474 (*idx == '\r'))
00475 {
00476 *idx = 0;
00477 size--;
00478 }
00479 if(*idx == '\t')
00480 {
00481 *idx = ' ';
00482 }
00483 idx++;
00484 }
00485
00486 return size;
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 extern u_long netmasks[33];
00504
00505 void InitNetmasks()
00506 {
00507 netmasks[0] = 0x0;
00508 netmasks[1] = 0x80000000;
00509 netmasks[2] = 0xC0000000;
00510 netmasks[3] = 0xE0000000;
00511 netmasks[4] = 0xF0000000;
00512 netmasks[5] = 0xF8000000;
00513 netmasks[6] = 0xFC000000;
00514 netmasks[7] = 0xFE000000;
00515 netmasks[8] = 0xFF000000;
00516 netmasks[9] = 0xFF800000;
00517 netmasks[10] = 0xFFC00000;
00518 netmasks[11] = 0xFFE00000;
00519 netmasks[12] = 0xFFF00000;
00520 netmasks[13] = 0xFFF80000;
00521 netmasks[14] = 0xFFFC0000;
00522 netmasks[15] = 0xFFFE0000;
00523 netmasks[16] = 0xFFFF0000;
00524 netmasks[17] = 0xFFFF8000;
00525 netmasks[18] = 0xFFFFC000;
00526 netmasks[19] = 0xFFFFE000;
00527 netmasks[20] = 0xFFFFF000;
00528 netmasks[21] = 0xFFFFF800;
00529 netmasks[22] = 0xFFFFFC00;
00530 netmasks[23] = 0xFFFFFE00;
00531 netmasks[24] = 0xFFFFFF00;
00532 netmasks[25] = 0xFFFFFF80;
00533 netmasks[26] = 0xFFFFFFC0;
00534 netmasks[27] = 0xFFFFFFE0;
00535 netmasks[28] = 0xFFFFFFF0;
00536 netmasks[29] = 0xFFFFFFF8;
00537 netmasks[30] = 0xFFFFFFFC;
00538 netmasks[31] = 0xFFFFFFFE;
00539 netmasks[32] = 0xFFFFFFFF;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 void PrintError(char *str)
00552 {
00553 if(pv.daemon_flag)
00554 syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "%s:%m", str);
00555 else
00556 perror(str);
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 void ErrorMessage(const char *format,...)
00571 {
00572 char buf[STD_BUF+1];
00573 va_list ap;
00574
00575 va_start(ap, format);
00576
00577 if(pv.daemon_flag)
00578 {
00579 vsnprintf(buf, STD_BUF, format, ap);
00580 syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "%s", buf);
00581 }
00582 else
00583 {
00584 vfprintf(stderr, format, ap);
00585 }
00586 va_end(ap);
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 void LogMessage(const char *format,...)
00600 {
00601 char buf[STD_BUF+1];
00602 va_list ap;
00603
00604 if(pv.quiet_flag && !pv.daemon_flag)
00605 return;
00606
00607 va_start(ap, format);
00608
00609 if(pv.daemon_flag)
00610 {
00611 vsnprintf(buf, STD_BUF, format, ap);
00612 syslog(LOG_DAEMON | LOG_NOTICE, "%s", buf);
00613 }
00614 else
00615 {
00616 vfprintf(stderr, format, ap);
00617 }
00618 va_end(ap);
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
00632 void CreateApplicationEventLogEntry(const char *msg)
00633 {
00634 HANDLE hEventLog;
00635 char* pEventSourceName = "SnortService";
00636
00637
00638
00639
00640 AddEventSource(pEventSourceName);
00641 hEventLog = RegisterEventSource(NULL, pEventSourceName);
00642 if (hEventLog == NULL)
00643 {
00644
00645 return;
00646 }
00647
00648 if (!ReportEvent(hEventLog,
00649 EVENTLOG_ERROR_TYPE,
00650 0,
00651 EVMSG_SIMPLE,
00652 NULL,
00653 1,
00654 0,
00655 &msg,
00656 NULL))
00657 {
00658
00659 }
00660
00661 DeregisterEventSource(hEventLog);
00662 }
00663 #endif
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 void FatalError(const char *format,...)
00678 {
00679 char buf[STD_BUF+1];
00680 va_list ap;
00681
00682 va_start(ap, format);
00683
00684 vsnprintf(buf, STD_BUF, format, ap);
00685
00686 if(pv.daemon_flag)
00687 {
00688 syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "FATAL ERROR: %s", buf);
00689 }
00690 else
00691 {
00692 fprintf(stderr, "ERROR: %s", buf);
00693 fprintf(stderr,"Fatal Error, Quitting..\n");
00694 #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
00695 CreateApplicationEventLogEntry(buf);
00696 #endif
00697 }
00698
00699 exit(1);
00700 }
00701
00702 void FatalPrintError(char *msg)
00703 {
00704 PrintError(msg);
00705 exit(1);
00706 }
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 void CreatePidFile(char *intf)
00720 {
00721 FILE *pid_file;
00722 struct stat pt;
00723 #ifdef WIN32
00724 char dir[STD_BUF + 1];
00725 #endif
00726
00727 if (!pv.readmode_flag)
00728 {
00729 if(!pv.quiet_flag)
00730 {
00731 LogMessage("Checking PID path...\n");
00732 }
00733 #ifndef _PATH_VARRUN
00734 #ifndef WIN32
00735 strlcpy(_PATH_VARRUN, "/var/run/", 10);
00736 #else
00737 if (GetCurrentDirectory(sizeof (dir)-1, dir))
00738 strncpy (_PATH_VARRUN, dir, sizeof(dir)-1);
00739 #endif
00740 #else
00741 if(!pv.quiet_flag)
00742 {
00743 LogMessage("PATH_VARRUN is set to %s on this operating system\n",
00744 _PATH_VARRUN);
00745 }
00746 #endif
00747
00748 stat(_PATH_VARRUN, &pt);
00749
00750 if(!S_ISDIR(pt.st_mode) || access(_PATH_VARRUN, W_OK) == -1)
00751 {
00752 LogMessage("WARNING: _PATH_VARRUN is invalid, trying "
00753 "/var/log...\n");
00754 strncpy(pv.pid_path, "/var/log/", strlen("/var/log/"));
00755 stat(pv.pid_path, &pt);
00756
00757 if(!S_ISDIR(pt.st_mode) || access(pv.pid_path, W_OK) == -1)
00758 {
00759 LogMessage("WARNING: %s is invalid, logging Snort "
00760 "PID path to log directory (%s)\n", pv.pid_path,
00761 pv.log_dir);
00762 CheckLogDir();
00763 snprintf(pv.pid_path, STD_BUF, "%s/", pv.log_dir);
00764 }
00765 }
00766 else
00767 {
00768 LogMessage("PID path stat checked out ok, PID path set to %s\n", _PATH_VARRUN);
00769 strlcpy(pv.pid_path, _PATH_VARRUN, STD_BUF);
00770 }
00771 }
00772
00773 if(intf == NULL || pv.pid_path == NULL)
00774 {
00775
00776
00777
00778 FatalError("CreatePidFile() failed to lookup interface or pid_path is unknown!\n");
00779 }
00780
00781 snprintf(pv.pid_filename, STD_BUF, "%s/snort_%s%s.pid", pv.pid_path, intf,
00782 pv.pidfile_suffix);
00783
00784 pid_file = fopen(pv.pid_filename, "w");
00785
00786 if(pid_file)
00787 {
00788 int pid = (int) getpid();
00789
00790 LogMessage("Writing PID \"%d\" to file \"%s\"\n", pid, pv.pid_filename);
00791 fprintf(pid_file, "%d\n", pid);
00792 fclose(pid_file);
00793 }
00794 else
00795 {
00796 ErrorMessage("Failed to create pid file %s", pv.pid_filename);
00797 pv.pid_filename[0] = 0;
00798 }
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 void SetUidGid(void)
00814 {
00815 #ifndef WIN32
00816
00817 if(groupname != NULL)
00818 {
00819 if(InlineMode())
00820 {
00821 ErrorMessage("Cannot set uid and gid when running Snort in "
00822 "inline mode.\n");
00823
00824 return;
00825 }
00826
00827 if(setgid(groupid) < 0)
00828 FatalError("Can not set gid: %lu\n", (u_long) groupid);
00829
00830 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Set gid to %lu\n", groupid););
00831 }
00832 if(username != NULL)
00833 {
00834 if(InlineMode())
00835 {
00836 ErrorMessage("Cannot set uid and gid when running Snort in "
00837 "inline mode.\n");
00838
00839 return;
00840 }
00841
00842 if(getuid() == 0 && initgroups(username, groupid) < 0)
00843 FatalError("Can not initgroups(%s,%lu)",
00844 username, (u_long) groupid);
00845
00846
00847 endgrent();
00848 endpwent();
00849
00850 if(setuid(userid) < 0)
00851 FatalError("Can not set uid: %lu\n", (u_long) userid);
00852 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Set gid to %lu\n", groupid););
00853 }
00854 #endif
00855
00856 return;
00857 }
00858
00859 #ifdef TIMESTATS
00860
00861 void DropHourlyStats(int trap)
00862 {
00863 struct pcap_stat ps;
00864
00865 const int secs_per_min = 60;
00866 const int secs_per_hr = 3600;
00867
00868 unsigned int dhs_ppm = 0, dhs_pps = 0;
00869 unsigned int curr_pkts = 0;
00870 unsigned int curr_drop_pkts = 0;
00871
00872 if (pcap_stats(pd, &ps))
00873 {
00874 pcap_perror(pd, "pcap_stats");
00875 }
00876 else
00877 {
00878 static unsigned int prev_pkts;
00879 static unsigned int prev_drop_pkts;
00880
00881
00882 curr_pkts = ps.ps_recv - prev_pkts;
00883 curr_drop_pkts = ps.ps_drop - prev_drop_pkts;
00884
00885 LogMessage("\n");
00886 LogMessage("Hourly Statistics Report\n");
00887 LogMessage("\n");
00888
00889 dhs_ppm = curr_pkts / secs_per_min;
00890 dhs_pps = curr_pkts / secs_per_hr;
00891
00892 LogMessage("Packet analysis time averages:\n");
00893 LogMessage("\n");
00894 LogMessage("Packets Received per hour is: %10u\n", curr_pkts);
00895 LogMessage("Packets Received per minute is: %10u\n", dhs_ppm);
00896 LogMessage("Packets Received per second is: %10u\n", dhs_pps);
00897 LogMessage("Packets Dropped in the last hour: %10u\n", curr_drop_pkts);
00898 LogMessage("\n");
00899
00900 prev_pkts = ps.ps_recv;
00901 prev_drop_pkts = ps.ps_drop;
00902
00903 }
00904
00905 alarm(secs_per_hr);
00906
00907 }
00908
00909
00910 void TimeStats(struct pcap_stat *ps)
00911 {
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 long end_time = 0L, total_secs = 0L;
00939
00940 const int SECONDS_PER_DAY = 86400;
00941 const int SECONDS_PER_HOUR = 3600;
00942 const int SECONDS_PER_MIN = 60;
00943
00944 int days = 0, hrs = 0, mins = 0, secs = 0, ival = 0;
00945 int pps = 0, ppm = 0, pph = 0, ppd = 0;
00946 int int_total_secs = 0;
00947
00948 int hflag = 0, mflag = 0;
00949
00950 end_time = time(&end_time);
00951 total_secs = end_time - start_time;
00952
00953 ival = total_secs;
00954 int_total_secs = ival;
00955
00956 days = ival / SECONDS_PER_DAY;
00957 ival = ival % SECONDS_PER_DAY;
00958 hrs = ival / SECONDS_PER_HOUR;
00959 ival = ival % SECONDS_PER_HOUR;
00960 mins = ival / SECONDS_PER_MIN;
00961 secs = ival % SECONDS_PER_MIN;
00962
00963 if (total_secs)
00964 pps = (ps->ps_recv / int_total_secs);
00965 else
00966 pps = ps->ps_recv;
00967
00968 LogMessage("Snort ran for %d Days %d Hours %d Minutes %d Seconds\n", days, hrs, mins, secs);
00969
00970 if (days + hrs + mins + secs > 0) {
00971 LogMessage("Packet analysis time averages:\n\n");
00972 }
00973
00974 if (days > 0) {
00975 ppd = (ps->ps_recv / (int_total_secs / SECONDS_PER_DAY));
00976 LogMessage("Snort Analyzed %d Packets Per Day\n", ppd);
00977 hflag = 1;
00978 }
00979
00980 if (hrs > 0 || hflag == 1) {
00981 pph = (ps->ps_recv / (int_total_secs / SECONDS_PER_HOUR));
00982 LogMessage("Snort Analyzed %d Packets Per Hour\n", pph);
00983 mflag = 1;
00984 }
00985
00986 if (mins > 0 || mflag == 1) {
00987 ppm = (ps->ps_recv / (int_total_secs / SECONDS_PER_MIN));
00988 LogMessage("Snort Analyzed %d Packets Per Minute\n", ppm);
00989 }
00990
00991 LogMessage("Snort Analyzed %d Packets Per Second\n", pps);
00992 LogMessage(" \n");
00993
00994 }
00995 #endif
00996
00997
00998 void DropStats(int iParamIgnored)
00999 {
01000 struct pcap_stat ps;
01001 float drop = 0.0;
01002 float recv = 0.0;
01003
01004 #ifndef TIMESTATS
01005 if(pv.quiet_flag)
01006 return;
01007 #endif
01008
01009 puts("\n\n===============================================================================\n");
01010
01011
01012
01013
01014
01015 if(pv.readmode_flag || InlineMode())
01016 {
01017
01018
01019 recv = (float) (pc.tcp
01020 + pc.udp
01021 + pc.icmp
01022 + pc.arp
01023 + pc.ipx
01024 + pc.eapol
01025 + pc.ipv6
01026 + pc.ethloopback
01027 + pc.other
01028 + pc.discards
01029 + pc.frags
01030 + pc.rebuild_element
01031 - pc.rebuilt_frags
01032 - pc.frag_timeout);
01033
01034 printf("Snort processed %u packets.\n", (unsigned int) recv);
01035 }
01036 else
01037 {
01038
01039 if(pcap_stats(pd, &ps))
01040 {
01041 pcap_perror(pd, "pcap_stats");
01042 }
01043 else
01044 {
01045 recv = (float) ps.ps_recv;
01046 drop = (float) ps.ps_drop;
01047
01048 #ifdef TIMESTATS
01049 {
01050 int oldQFlag = pv.quiet_flag;
01051 pv.quiet_flag = 0;
01052 TimeStats(&ps);
01053 pv.quiet_flag = oldQFlag;
01054 }
01055 #endif
01056
01057 LogMessage("Snort received %u packets\n", ps.ps_recv);
01058 LogMessage(" Analyzed: %u(%.3f%%)\n", ps.ps_recv - ps.ps_drop,
01059 ps.ps_recv?CalcPct((float)(ps.ps_recv-ps.ps_drop),
01060 (float) ps.ps_recv):0);
01061 LogMessage(" Dropped: %u(%.3f%%)\n", ps.ps_drop,
01062 ps.ps_recv?CalcPct((float)ps.ps_drop, (float) ps.ps_recv):0);
01063 }
01064 }
01065
01066 LogMessage("================================================"
01067 "===============================\n");
01068
01069 LogMessage("Breakdown by protocol:\n");
01070 LogMessage(" TCP: %-10lu (%.3f%%)%-*s\n",
01071 pc.tcp, CalcPct((float) pc.tcp, recv),
01072 CalcPct((float)pc.tcp,recv + drop)<10?10:9 , " ");
01073 LogMessage(" UDP: %-10lu (%.3f%%)%-*s\n",
01074 pc.udp, CalcPct((float) pc.udp, recv),
01075 CalcPct((float)pc.udp,recv + drop)<10?10:9, " ");
01076 LogMessage(" ICMP: %-10lu (%.3f%%)%-*s\n",
01077 pc.icmp, CalcPct((float) pc.icmp, recv),
01078 CalcPct((float)pc.icmp,recv + drop)<10?10:9, " ");
01079 LogMessage(" ARP: %-10lu (%.3f%%)\n",
01080 pc.arp, CalcPct((float) pc.arp, recv));
01081 LogMessage(" EAPOL: %-10lu (%.3f%%)\n",
01082 pc.eapol, CalcPct((float) pc.eapol, recv));
01083 LogMessage(" IPv6: %-10lu (%.3f%%)\n",
01084 pc.ipv6, CalcPct((float) pc.ipv6, recv));
01085 LogMessage("ETHLOOP: %-10lu (%.3f%%)\n",
01086 pc.ethloopback, CalcPct((float) pc.ethloopback, recv));
01087 LogMessage(" IPX: %-10lu (%.3f%%)\n",
01088 pc.ipx, CalcPct((float) pc.ipx, recv));
01089 LogMessage(" FRAG: %-10lu (%.3f%%)%-*s\n",
01090 pc.frags, CalcPct((float) pc.frags, recv),
01091 CalcPct((float)pc.udp,recv + drop)<10?10:9, " ");
01092 LogMessage(" OTHER: %-10lu (%.3f%%)\n",
01093 pc.other, CalcPct((float) pc.other, recv));
01094 LogMessage("DISCARD: %-10lu (%.3f%%)\n",
01095 pc.discards, CalcPct((float) pc.discards, recv));
01096
01097 LogMessage("================================================"
01098 "===============================\n");
01099 LogMessage("Action Stats:\n");
01100 LogMessage("ALERTS: %u\n", pc.alert_pkts);
01101 LogMessage("LOGGED: %u\n", pc.log_pkts);
01102 LogMessage("PASSED: %u\n", pc.pass_pkts);
01103
01104 #ifdef DLT_IEEE802_11
01105 if(datalink == DLT_IEEE802_11)
01106 {
01107 LogMessage("================================================"
01108 "===============================\n");
01109 LogMessage("Wireless Stats:\n");
01110 LogMessage("Breakdown by type:\n");
01111 LogMessage(" Management Packets: %-10lu (%.3f%%)\n",
01112 pc.wifi_mgmt, CalcPct((float) pc.wifi_mgmt, recv));
01113 LogMessage(" Control Packets: %-10lu (%.3f%%)\n",
01114 pc.wifi_control, CalcPct((float) pc.wifi_control, recv));
01115 LogMessage(" Data Packets: %-10lu (%.3f%%)\n",
01116 pc.wifi_data, CalcPct((float) pc.wifi_data, recv));
01117 }
01118 #endif
01119
01120 if(pc.frags > 0)
01121 {
01122 LogMessage("================================================"
01123 "===============================\n");
01124 LogMessage("Fragmentation Stats:\n");
01125 LogMessage("Fragmented IP Packets: %-10lu (%.3f%%)\n",
01126 pc.frags, CalcPct((float) pc.frags, recv));
01127 LogMessage(" Fragment Trackers: %-10lu\n",
01128 pc.frag_trackers);
01129 LogMessage(" Rebuilt IP Packets: %-10lu\n",
01130 pc.rebuilt_frags);
01131 LogMessage(" Frag elements used: %-10lu\n",
01132 pc.rebuild_element);
01133 LogMessage("Discarded(incomplete): %-10lu\n",
01134 pc.frag_incomp);
01135 LogMessage(" Discarded(timeout): %-10lu\n",
01136 pc.frag_timeout);
01137 LogMessage(" Frag2 memory faults: %-10lu\n",
01138 pc.frag_mem_faults);
01139 }
01140
01141 if(pc.tcp_stream_pkts > 0)
01142 {
01143 LogMessage("=============================================="
01144 "=================================\n");
01145 LogMessage("TCP Stream Reassembly Stats:\n");
01146 LogMessage(" TCP Packets Used: %-10lu (%-3.3f%%)\n",
01147 pc.tcp_stream_pkts,
01148 CalcPct((float) pc.tcp_stream_pkts, recv));
01149 LogMessage(" Stream Trackers: %-10lu\n", pc.tcp_streams);
01150 LogMessage(" Stream flushes: %-10lu\n", pc.rebuilt_tcp);
01151 LogMessage(" Segments used: %-10lu\n", pc.rebuilt_segs);
01152 LogMessage(" Stream4 Memory Faults: %-10lu\n",
01153 pc.str_mem_faults);
01154 }
01155
01156 LogMessage("=============================================="
01157 "=================================\n");
01158
01159 return;
01160 }
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 void InitProtoNames()
01175 {
01176 int i;
01177 struct protoent *pt;
01178 unsigned char *tmp;
01179 u_char protoname[11];
01180
01181 for(i = 0; i < 256; i++)
01182 {
01183 pt = getprotobynumber(i);
01184
01185 if(pt)
01186 {
01187 protocol_names[i] = strdup(pt->p_name);
01188
01189 tmp = protocol_names[i];
01190
01191 for(tmp = protocol_names[i]; *tmp != 0; tmp++)
01192 *tmp = (unsigned char) toupper(*tmp);
01193 }
01194 else
01195 {
01196 snprintf(protoname, 10, "PROTO%03d", i);
01197 protocol_names[i] = strdup(protoname);
01198 }
01199 }
01200 }
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 void CleanupProtoNames()
01214 {
01215 int i;
01216
01217 for(i = 0; i < 256; i++)
01218 {
01219 if( protocol_names[i] != NULL )
01220 {
01221 free( protocol_names[i] );
01222 protocol_names[i] = NULL;
01223 }
01224 }
01225 }
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238 char *read_infile(char *fname)
01239 {
01240 register int fd, cc;
01241 register char *cp, *cmt;
01242 struct stat buf;
01243
01244 fd = open(fname, O_RDONLY);
01245
01246 if(fd < 0)
01247 FatalError("can't open %s: %s\n", fname, pcap_strerror(errno));
01248
01249 if(fstat(fd, &buf) < 0)
01250 FatalError("can't stat %s: %s\n", fname, pcap_strerror(errno));
01251
01252 cp = malloc((u_int) buf.st_size + 1);
01253
01254 cc = read(fd, cp, (int) buf.st_size);
01255
01256 if(cc < 0)
01257 FatalError("read %s: %s\n", fname, pcap_strerror(errno));
01258
01259 if(cc != buf.st_size)
01260 FatalError("short read %s (%d != %d)\n", fname, cc, (int) buf.st_size);
01261
01262 cp[(int) buf.st_size] = '\0';
01263
01264 close(fd);
01265
01266
01267
01268
01269
01270 while((cmt = strchr(cp, '#')) != NULL)
01271 {
01272 while (*cmt != '\r' && *cmt != '\n' && *cmt != '\0')
01273 {
01274 *cmt++ = ' ';
01275 }
01276 }
01277
01278
01279 return(cp);
01280 }
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 void CheckLogDir(void)
01297 {
01298 struct stat st;
01299 char log_dir[STD_BUF];
01300
01301 snprintf(log_dir, STD_BUF, "%s", pv.log_dir);
01302 stat(log_dir, &st);
01303
01304 if(!S_ISDIR(st.st_mode) || access(log_dir, W_OK) == -1)
01305 {
01306 FatalError("\n[!] ERROR: "
01307 "Can not get write access to logging directory \"%s\".\n"
01308 "(directory doesn't exist or permissions are set incorrectly\n"
01309
01310
01311
01312
01313 "or it is not a directory at all)\n\n",
01314 log_dir);
01315 }
01316 }
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330 void GoDaemon(void)
01331 {
01332 #ifndef WIN32
01333 pid_t fs;
01334
01335 LogMessage("Initializing daemon mode\n");
01336
01337 if(getppid() != 1)
01338 {
01339 fs = fork();
01340
01341 if(fs > 0)
01342 exit(0);
01343
01344 if(fs < 0)
01345 {
01346 perror("fork");
01347 exit(1);
01348 }
01349 setsid();
01350 }
01351
01352 close(0);
01353 close(1);
01354 close(2);
01355
01356 #ifdef DEBUG
01357 open("/tmp/snort.debug", O_CREAT | O_RDWR);
01358 #else
01359 open("/dev/null", O_RDWR);
01360 #endif
01361
01362 dup(0);
01363 dup(0);
01364 #endif
01365 return;
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392 void *SPAlloc(unsigned long size, struct _SPMemControl *spmc)
01393 {
01394 void *tmp;
01395
01396 spmc->mem_usage += size;
01397
01398 if(spmc->mem_usage > spmc->memcap)
01399 {
01400 spmc->sp_func(spmc);
01401 }
01402
01403 tmp = (void *) calloc(size, sizeof(char));
01404
01405 if(tmp == NULL)
01406 {
01407 FatalError("Unable to allocate memory! (%lu requested, %lu in use)\n",
01408 size, spmc->mem_usage);
01409 }
01410
01411 return tmp;
01412 }
01413
01414
01415 void *SnortAlloc(unsigned long size)
01416 {
01417 void *tmp;
01418
01419 tmp = (void *) calloc(size, sizeof(char));
01420
01421 if(tmp == NULL)
01422 {
01423 FatalError("Unable to allocate memory! (%lu requested)\n", size);
01424 }
01425
01426 return tmp;
01427 }
01428
01429
01430
01431
01432
01433
01434
01435 void SetChroot(char *directory, char **logstore)
01436 {
01437 #ifdef WIN32
01438 FatalError("SetChroot() should not be called under Win32!\n");
01439 #else
01440 char *absdir;
01441 int abslen;
01442 char *logdir;
01443
01444 if(!directory || !logstore)
01445 {
01446 FatalError("Null parameter passed\n");
01447 }
01448
01449 logdir = *logstore;
01450
01451 if(logdir == NULL || *logdir == '\0')
01452 {
01453 FatalError("Null log directory\n");
01454 }
01455
01456 DEBUG_WRAP(DebugMessage(DEBUG_INIT,"SetChroot: %s\n",
01457 CurrentWorkingDir()););
01458
01459 logdir = GetAbsolutePath(logdir);
01460
01461 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "SetChroot: %s\n",
01462 CurrentWorkingDir()));
01463
01464 logdir = strdup(logdir);
01465
01466 if(logdir == NULL)
01467 {
01468 FatalError("SetChroot: Out of memory");
01469 }
01470
01471
01472 if(chdir(directory) != 0)
01473 {
01474 FatalError("SetChroot: Can not chdir to \"%s\": %s\n", directory,
01475 strerror(errno));
01476 }
01477
01478
01479 absdir = CurrentWorkingDir();
01480
01481 if(absdir == NULL)
01482 {
01483 FatalError("NULL Chroot found\n");
01484 }
01485
01486 abslen = strlen(absdir);
01487
01488 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "ABS: %s %d\n", absdir, abslen););
01489
01490
01491 if(chroot(absdir) < 0)
01492 {
01493 FatalError("Can not chroot to \"%s\": absolute: %s: %s\n",
01494 directory, absdir, strerror(errno));
01495 }
01496
01497 DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chroot success (%s ->", absdir););
01498 DEBUG_WRAP(DebugMessage(DEBUG_INIT,"%s)\n ", CurrentWorkingDir()););
01499
01500
01501 if(chdir("/") < 0)
01502 {
01503 FatalError("Can not chdir to \"/\" after chroot: %s\n",
01504 strerror(errno));
01505 }
01506
01507 DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chdir success (%s)\n",
01508 CurrentWorkingDir()););
01509
01510
01511 if(strncmp(absdir, logdir, strlen(absdir)))
01512 {
01513 FatalError("Absdir is not a subset of the logdir");
01514 }
01515
01516 if(abslen >= strlen(logdir))
01517 {
01518 *logstore = "/";
01519 }
01520 else
01521 {
01522 *logstore = logdir + abslen;
01523 }
01524
01525 DEBUG_WRAP(DebugMessage(DEBUG_INIT,"new logdir from %s to %s\n",
01526 logdir, *logstore));
01527
01528
01529 signal(SIGHUP, SigCantHupHandler);
01530 #endif
01531 }
01532
01533
01534
01535
01536
01537
01538 char *CurrentWorkingDir(void)
01539 {
01540 static char buf[PATH_MAX_UTIL + 1];
01541
01542 if(getcwd((char *) buf, PATH_MAX_UTIL) == NULL)
01543 {
01544 return NULL;
01545 }
01546
01547 buf[PATH_MAX_UTIL] = '\0';
01548
01549 return (char *) buf;
01550 }
01551
01552
01553
01554
01555 char *GetAbsolutePath(char *dir)
01556 {
01557 char *savedir, *dirp;
01558 static char buf[PATH_MAX_UTIL + 1];
01559
01560 if(dir == NULL)
01561 {
01562 return NULL;
01563 }
01564
01565 savedir = strdup(CurrentWorkingDir());
01566
01567 if(savedir == NULL)
01568 {
01569 return NULL;
01570 }
01571
01572 if(chdir(dir) < 0)
01573 {
01574 LogMessage("Can't change to directory: %s\n", dir);
01575 free(savedir);
01576 return NULL;
01577 }
01578
01579 dirp = CurrentWorkingDir();
01580
01581 if(dirp == NULL)
01582 {
01583 LogMessage("Unable to access current directory\n");
01584 free(savedir);
01585 return NULL;
01586 }
01587 else
01588 {
01589 strncpy(buf, dirp, PATH_MAX_UTIL);
01590 buf[PATH_MAX_UTIL] = '\0';
01591 }
01592
01593 if(chdir(savedir) < 0)
01594 {
01595 LogMessage("Can't change back to directory: %s\n", dir);
01596 free(savedir);
01597 return NULL;
01598 }
01599
01600 free(savedir);
01601 return (char *) buf;
01602 }
01603