diff options
Diffstat (limited to 'config/snort-dev/patches/spoink_patch/2.8.6/util.c')
-rw-r--r-- | config/snort-dev/patches/spoink_patch/2.8.6/util.c | 3233 |
1 files changed, 0 insertions, 3233 deletions
diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/util.c b/config/snort-dev/patches/spoink_patch/2.8.6/util.c deleted file mode 100644 index b2d3b38b..00000000 --- a/config/snort-dev/patches/spoink_patch/2.8.6/util.c +++ /dev/null @@ -1,3233 +0,0 @@ -/* $Id$ */ -/* -** Copyright (C) 2002-2010 Sourcefire, Inc. -** Copyright (C) 2002 Martin Roesch <roesch@sourcefire.com> -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License Version 2 as -** published by the Free Software Foundation. You may not use, modify or -** distribute this program under any other version of the GNU General -** Public License. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> - -#ifndef WIN32 -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/wait.h> -#include <dirent.h> -#include <fnmatch.h> -#endif /* !WIN32 */ - -#include <stdarg.h> -#include <syslog.h> -#include <errno.h> -#include <sys/stat.h> -#include <time.h> -#include <signal.h> -#include <unistd.h> - -#ifndef WIN32 -#include <grp.h> -#include <pwd.h> -#include <netdb.h> -#include <limits.h> -#endif /* !WIN32 */ - -#include <fcntl.h> - -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif - -#ifdef ZLIB -#include <zlib.h> -#endif - -#include "snort.h" -#include "mstring.h" -#include "debug.h" -#include "util.h" -#include "parser.h" -#include "inline.h" -#include "build.h" -#include "plugbase.h" -#include "sf_types.h" -#include "sflsq.h" -#include "ipv6_port.h" - -#include "pcre.h" - -#include "mpse.h" - -#include "ppm.h" - -#ifdef TARGET_BASED -#include "sftarget_reader.h" -#endif - -#ifdef WIN32 -#include "win32/WIN32-Code/name.h" -#endif - -#include "stream5_common.h" - -#ifdef PATH_MAX -#define PATH_MAX_UTIL PATH_MAX -#else -#define PATH_MAX_UTIL 1024 -#endif /* PATH_MAX */ - -extern Stream5Stats s5stats; -extern int datalink; -extern pcap_t *pcap_handle; -extern PreprocStatsFuncNode *preproc_stats_funcs; - -static PcapPktStats pkt_stats; - -/* - * you may need to adjust this on the systems which don't have standard - * paths defined - */ -#ifndef _PATH_VARRUN -static char _PATH_VARRUN[STD_BUF]; -#endif - - -#ifdef NAME_MAX -#define NAME_MAX_UTIL NAME_MAX -#else -#define NAME_MAX_UTIL 256 -#endif /* NAME_MAX */ - -#define FILE_MAX_UTIL (PATH_MAX_UTIL + NAME_MAX_UTIL) - -/**************************************************************************** - * - * Function: CalcPct(uint64_t, uint64_t) - * - * Purpose: Calculate the percentage of a value compared to a total - * - * Arguments: cnt => the numerator in the equation - * total => the denominator in the calculation - * - * Returns: pct -> the percentage of cnt to value - * - ****************************************************************************/ -double CalcPct(uint64_t cnt, uint64_t total) -{ - double pct = 0.0; - - if (total == 0.0) - { - pct = (double)cnt; - } - else - { - pct = (double)cnt / (double)total; - } - - pct *= 100.0; - - return pct; -} - - -/**************************************************************************** - * - * Function: DisplayBanner() - * - * Purpose: Show valuable proggie info - * - * Arguments: None. - * - * Returns: 0 all the time - * - ****************************************************************************/ -int DisplayBanner(void) -{ - const char * info; - const char * pcre_ver; -#ifdef ZLIB - const char * zlib_ver; -#endif - - info = getenv("HOSTTYPE"); - if( !info ) - { - info=""; - } - - pcre_ver = pcre_version(); -#ifdef ZLIB - zlib_ver = zlib_version; -#endif - - LogMessage("\n"); - LogMessage(" ,,_ -*> Snort! <*-\n"); - LogMessage(" o\" )~ Version %s%s%s (Build %s) %s %s\n", - VERSION, -#ifdef SUP_IP6 - " IPv6", -#else - "", -#endif -#ifdef GRE - " GRE", -#else - "", -#endif - BUILD, -#ifdef GIDS - "inline", -#else - "", -#endif - info); - LogMessage(" '''' By Martin Roesch & The Snort Team: http://www.snort.org/snort/snort-team\n"); - LogMessage(" Copyright (C) 1998-2010 Sourcefire, Inc., et al.\n"); - LogMessage(" Using PCRE version: %s\n", pcre_ver); -#ifdef ZLIB - LogMessage(" Using ZLIB version: %s\n", zlib_ver); -#endif - LogMessage("\n"); - LogMessage(" ___ Built Date for Snort on Pfsense 2.0 is May 25 2010.\n"); - LogMessage(" ___/ f \\ Orion IPS Output Code Copyright (C) 2009-2010 Robert Zelaya.\n"); - LogMessage("/ p \\___/Sense\n"); - LogMessage("\\___/ \\\n"); - LogMessage(" \\___/ Using Snort.org dynamic plugins and Orion IPS source.\n"); - LogMessage("\n"); - - return 0; -} - - - -/**************************************************************************** - * - * Function: ts_print(register const struct, char *) - * - * Purpose: Generate a time stamp and stuff it in a buffer. This one has - * millisecond precision. Oh yeah, I ripped this code off from - * TCPdump, props to those guys. - * - * Arguments: timeval => clock struct coming out of libpcap - * timebuf => buffer to stuff timestamp into - * - * Returns: void function - * - ****************************************************************************/ -void ts_print(register const struct timeval *tvp, char *timebuf) -{ - register int s; - int localzone; - time_t Time; - struct timeval tv; - struct timezone tz; - struct tm *lt; /* place to stick the adjusted clock data */ - - /* if null was passed, we use current time */ - if(!tvp) - { - /* manual page (for linux) says tz is never used, so.. */ - bzero((char *) &tz, sizeof(tz)); - gettimeofday(&tv, &tz); - tvp = &tv; - } - - localzone = snort_conf->thiszone; - - /* - ** If we're doing UTC, then make sure that the timezone is correct. - */ - if (ScOutputUseUtc()) - localzone = 0; - - s = (tvp->tv_sec + localzone) % 86400; - Time = (tvp->tv_sec + localzone) - s; - - lt = gmtime(&Time); - - if (ScOutputIncludeYear()) - { - (void) SnortSnprintf(timebuf, TIMEBUF_SIZE, - "%02d/%02d/%02d-%02d:%02d:%02d.%06u ", - lt->tm_mon + 1, lt->tm_mday, lt->tm_year - 100, - s / 3600, (s % 3600) / 60, s % 60, - (u_int) tvp->tv_usec); - } - else - { - (void) SnortSnprintf(timebuf, TIMEBUF_SIZE, - "%02d/%02d-%02d:%02d:%02d.%06u ", lt->tm_mon + 1, - lt->tm_mday, s / 3600, (s % 3600) / 60, s % 60, - (u_int) tvp->tv_usec); - } -} - - - -/**************************************************************************** - * - * Function: gmt2local(time_t) - * - * Purpose: Figures out how to adjust the current clock reading based on the - * timezone you're in. Ripped off from TCPdump. - * - * Arguments: time_t => offset from GMT - * - * Returns: offset seconds from GMT - * - ****************************************************************************/ -int gmt2local(time_t t) -{ - register int dt, dir; - register struct tm *gmt, *loc; - struct tm sgmt; - - if(t == 0) - t = time(NULL); - - gmt = &sgmt; - *gmt = *gmtime(&t); - loc = localtime(&t); - - dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + - (loc->tm_min - gmt->tm_min) * 60; - - dir = loc->tm_year - gmt->tm_year; - - if(dir == 0) - dir = loc->tm_yday - gmt->tm_yday; - - dt += dir * 24 * 60 * 60; - - return(dt); -} - - - - -/**************************************************************************** - * - * Function: copy_argv(u_char **) - * - * Purpose: Copies a 2D array (like argv) into a flat string. Stolen from - * TCPDump. - * - * Arguments: argv => 2D array to flatten - * - * Returns: Pointer to the flat string - * - ****************************************************************************/ -char *copy_argv(char **argv) -{ - char **p; - u_int len = 0; - char *buf; - char *src, *dst; - //void ftlerr(char *,...); - - p = argv; - if(*p == 0) - return 0; - - while(*p) - len += strlen(*p++) + 1; - - buf = (char *) calloc(1,len); - - if(buf == NULL) - { - FatalError("calloc() failed: %s\n", strerror(errno)); - } - p = argv; - dst = buf; - - while((src = *p++) != NULL) - { - while((*dst++ = *src++) != '\0'); - dst[-1] = ' '; - } - - dst[-1] = '\0'; - - /* Check for an empty string */ - dst = buf; - while (isspace((int)*dst)) - dst++; - - if (strlen(dst) == 0) - { - free(buf); - buf = NULL; - } - - return buf; -} - - -/**************************************************************************** - * - * Function: strip(char *) - * - * Purpose: Strips a data buffer of CR/LF/TABs. Replaces CR/LF's with - * NULL and TABs with spaces. - * - * Arguments: data => ptr to the data buf to be stripped - * - * Returns: void - * - * 3/7/07 - changed to return void - use strlen to get size of string - * - * Note that this function will turn all '\n' and '\r' into null chars - * so, e.g. 'Hello\nWorld\n' => 'Hello\x00World\x00' - * note that the string is now just 'Hello' and the length is shortened - * by more than just an ending '\n' or '\r' - ****************************************************************************/ -void strip(char *data) -{ - int size; - char *end; - char *idx; - - idx = data; - end = data + strlen(data); - size = end - idx; - - while(idx != end) - { - if((*idx == '\n') || - (*idx == '\r')) - { - *idx = 0; - size--; - } - if(*idx == '\t') - { - *idx = ' '; - } - idx++; - } -} - -/* - * Function: ErrorMessage(const char *, ...) - * - * Purpose: Print a message to stderr. - * - * Arguments: format => the formatted error string to print out - * ... => format commands/fillers - * - * Returns: void function - */ -void ErrorMessage(const char *format,...) -{ - char buf[STD_BUF+1]; - va_list ap; - - if (snort_conf == NULL) - return; - - va_start(ap, format); - - if (ScDaemonMode() || ScLogSyslog()) - { - vsnprintf(buf, STD_BUF, format, ap); - buf[STD_BUF] = '\0'; - syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "%s", buf); - } - else - { - vfprintf(stderr, format, ap); - } - va_end(ap); -} - -/* - * Function: LogMessage(const char *, ...) - * - * Purpose: Print a message to stderr or with logfacility. - * - * Arguments: format => the formatted error string to print out - * ... => format commands/fillers - * - * Returns: void function - */ -void LogMessage(const char *format,...) -{ - char buf[STD_BUF+1]; - va_list ap; - - if (snort_conf == NULL) - return; - - if (ScLogQuiet() && !ScDaemonMode() && !ScLogSyslog()) - return; - - va_start(ap, format); - - if (ScDaemonMode() || ScLogSyslog()) - { - vsnprintf(buf, STD_BUF, format, ap); - buf[STD_BUF] = '\0'; - syslog(LOG_DAEMON | LOG_NOTICE, "%s", buf); - } - else - { - vfprintf(stderr, format, ap); - } - - va_end(ap); -} - -/* - * Function: CreateApplicationEventLogEntry(const char *) - * - * Purpose: Add an entry to the Win32 "Application" EventLog - * - * Arguments: szMessage => the formatted error string to print out - * - * Returns: void function - */ -#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) -void CreateApplicationEventLogEntry(const char *msg) -{ - HANDLE hEventLog; - char* pEventSourceName = "SnortService"; - - /* prepare to write to Application log on local host - * with Event Source of SnortService - */ - AddEventSource(pEventSourceName); - hEventLog = RegisterEventSource(NULL, pEventSourceName); - if (hEventLog == NULL) - { - /* Could not register the event source. */ - return; - } - - if (!ReportEvent(hEventLog, /* event log handle */ - EVENTLOG_ERROR_TYPE, /* event type */ - 0, /* category zero */ - EVMSG_SIMPLE, /* event identifier */ - NULL, /* no user security identifier */ - 1, /* one substitution string */ - 0, /* no data */ - &msg, /* pointer to array of strings */ - NULL)) /* pointer to data */ - { - /* Could not report the event. */ - } - - DeregisterEventSource(hEventLog); -} -#endif /* WIN32 && ENABLE_WIN32_SERVICE */ - - -/* - * Function: FatalError(const char *, ...) - * - * Purpose: When a fatal error occurs, this function prints the error message - * and cleanly shuts down the program - * - * Arguments: format => the formatted error string to print out - * ... => format commands/fillers - * - * Returns: void function - */ -NORETURN void FatalError(const char *format,...) -{ - char buf[STD_BUF+1]; - va_list ap; - - va_start(ap, format); - vsnprintf(buf, STD_BUF, format, ap); - va_end(ap); - - buf[STD_BUF] = '\0'; - - if ((snort_conf != NULL) && (ScDaemonMode() || ScLogSyslog())) - { - syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "FATAL ERROR: %s", buf); - } - else - { - fprintf(stderr, "ERROR: %s", buf); - fprintf(stderr,"Fatal Error, Quitting..\n"); -#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) - CreateApplicationEventLogEntry(buf); -#endif - } - - exit(1); -} - - -/**************************************************************************** - * - * Function: CreatePidFile(char *) - * - * Purpose: Creates a PID file - * - * Arguments: Interface opened. - * - * Returns: void function - * - ****************************************************************************/ -static FILE *pid_lockfile = NULL; -static FILE *pid_file = NULL; -void CreatePidFile(char *intf) -{ - struct stat pt; - int pid = (int) getpid(); -#ifdef WIN32 - char dir[STD_BUF + 1]; -#endif - - if (!ScReadMode()) - { - LogMessage("Checking PID path...\n"); - - if (strlen(snort_conf->pid_path) != 0) - { - if((stat(snort_conf->pid_path, &pt) == -1) || - !S_ISDIR(pt.st_mode) || access(snort_conf->pid_path, W_OK) == -1) - { -#ifndef WIN32 - /* Save this just in case it's reset with LogMessage call */ - int err = errno; - - LogMessage("WARNING: %s is invalid, trying " - "/var/run...\n", snort_conf->pid_path); - if (err) - { - LogMessage("Previous Error, errno=%d, (%s)\n", - err, strerror(err) == NULL ? "Unknown error" : strerror(err)); - } -#endif - memset(snort_conf->pid_path, 0, sizeof(snort_conf->pid_path)); - } - else - { - LogMessage("PID path stat checked out ok, " - "PID path set to %s\n", snort_conf->pid_path); - } - } - - if (strlen(snort_conf->pid_path) == 0) - { -#ifndef _PATH_VARRUN -# ifndef WIN32 - SnortStrncpy(_PATH_VARRUN, "/var/run/", sizeof(_PATH_VARRUN)); -# else - if (GetCurrentDirectory(sizeof(dir) - 1, dir)) - SnortStrncpy(_PATH_VARRUN, dir, sizeof(_PATH_VARRUN)); -# endif /* WIN32 */ -#else - LogMessage("PATH_VARRUN is set to %s on this operating " - "system\n", _PATH_VARRUN); -#endif /* _PATH_VARRUN */ - - stat(_PATH_VARRUN, &pt); - - if(!S_ISDIR(pt.st_mode) || access(_PATH_VARRUN, W_OK) == -1) - { - LogMessage("WARNING: _PATH_VARRUN is invalid, trying " - "/var/log...\n"); - SnortStrncpy(snort_conf->pid_path, "/var/log/", sizeof(snort_conf->pid_path)); - stat(snort_conf->pid_path, &pt); - - if(!S_ISDIR(pt.st_mode) || access(snort_conf->pid_path, W_OK) == -1) - { - LogMessage("WARNING: %s is invalid, logging Snort " - "PID path to log directory (%s)\n", snort_conf->pid_path, - snort_conf->log_dir); - CheckLogDir(); - SnortSnprintf(snort_conf->pid_path, sizeof(snort_conf->pid_path), - "%s/", snort_conf->log_dir); - } - } - else - { - LogMessage("PID path stat checked out ok, " - "PID path set to %s\n", _PATH_VARRUN); - SnortStrncpy(snort_conf->pid_path, _PATH_VARRUN, sizeof(snort_conf->pid_path)); - } - } - } - - if(intf == NULL || strlen(snort_conf->pid_path) == 0) - { - /* snort_conf->pid_path should have some value by now - * so let us just be sane. */ - FatalError("CreatePidFile() failed to lookup interface or pid_path is unknown!\n"); - } - - SnortSnprintf(snort_conf->pid_filename, sizeof(snort_conf->pid_filename), - "%s/snort_%s%s.pid", snort_conf->pid_path, intf, snort_conf->pidfile_suffix); - -#ifndef WIN32 - if (!ScNoLockPidFile()) - { - char pid_lockfilename[STD_BUF+1]; - int lock_fd; - - /* First, lock the PID file */ - SnortSnprintf(pid_lockfilename, STD_BUF, "%s.lck", snort_conf->pid_filename); - pid_lockfile = fopen(pid_lockfilename, "w"); - - if (pid_lockfile) - { - struct flock lock; - lock_fd = fileno(pid_lockfile); - - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - - if (fcntl(lock_fd, F_SETLK, &lock) == -1) - { - ClosePidFile(); - FatalError("Failed to Lock PID File \"%s\" for PID \"%d\"\n", snort_conf->pid_filename, pid); - } - } - } -#endif - - /* Okay, were able to lock PID file, now open and write PID */ - pid_file = fopen(snort_conf->pid_filename, "w"); - if(pid_file) - { - LogMessage("Writing PID \"%d\" to file \"%s\"\n", pid, snort_conf->pid_filename); - fprintf(pid_file, "%d\n", pid); - fflush(pid_file); - } - else - { - ErrorMessage("Failed to create pid file %s", snort_conf->pid_filename); - snort_conf->pid_filename[0] = 0; - } -} - -/**************************************************************************** - * - * Function: ClosePidFile(char *) - * - * Purpose: Releases lock on a PID file - * - * Arguments: None - * - * Returns: void function - * - ****************************************************************************/ -void ClosePidFile(void) -{ - if (pid_file) - { - fclose(pid_file); - pid_file = NULL; - } - if (pid_lockfile) - { - fclose(pid_lockfile); - pid_lockfile = NULL; - } -} - -/**************************************************************************** - * - * Function: SetUidGid() - * - * Purpose: Sets safe UserID and GroupID if needed - * - * Arguments: none - * - * Returns: void function - * - ****************************************************************************/ -void SetUidGid(int user_id, int group_id) -{ -#ifndef WIN32 - - if ((group_id != -1) && (getgid() != (gid_t)group_id)) - { - if (!InlineModeSetPrivsAllowed()) - { - ErrorMessage("Cannot set uid and gid when running Snort in " - "inline mode.\n"); - return; - } - - if (setgid(group_id) < 0) - FatalError("Cannot set gid: %d\n", group_id); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Set gid to %d\n", group_id);); - } - - if ((user_id != -1) && (getuid() != (uid_t)user_id)) - { - struct passwd *pw = getpwuid(user_id); - - if (!InlineModeSetPrivsAllowed()) - { - ErrorMessage("Cannot set uid and gid when running Snort in " - "inline mode.\n"); - return; - } - - if (pw != NULL) - { - /* getpwuid and initgroups may use the same static buffers */ - char *username = SnortStrdup(pw->pw_name); - - if ((getuid() == 0) && (initgroups(username, group_id) < 0)) - { - free(username); - FatalError("Can not initgroups(%s,%d)", - username, group_id); - } - - free(username); - } - - /** just to be on a safe side... **/ - endgrent(); - endpwent(); - - if (setuid(user_id) < 0) - FatalError("Can not set uid: %d\n", user_id); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Set uid to %d\n", user_id);); - } -#endif /* WIN32 */ -} - -#ifdef TIMESTATS - -static IntervalStats istats = {0}; -time_t start_time; - -void InitTimeStats(void) -{ - start_time = time(NULL); -} - -void ResetTimeStats(void) -{ - memset(&istats, 0, sizeof(istats)); -} - -/* This function prints out stats based on a configurable time - * interval. It is an indication on how well snort is */ -/* processing packets, including types, drops, etc */ -void DropStatsPerTimeInterval(void) -{ - double per_sec, per_minute, per_hour; - uint64_t recv, drop; - uint64_t total = 0; - uint32_t timestats_interval = ScTimestatsInterval(); - -#ifdef PCAP_CLOSE - if (UpdatePcapPktStats(0) != -1) -#else - if (UpdatePcapPktStats() != -1) -#endif - { - recv = GetPcapPktStatsRecv(); - drop = GetPcapPktStatsDrop(); - - istats.recv = recv - istats.recv_total; - istats.recv_total = recv; - - istats.drop = drop - istats.drop_total; - istats.drop_total = drop; - - /* calculate received packets by type */ - istats.tcp = pc.tcp - istats.tcp_total; - istats.tcp_total = pc.tcp; - - istats.udp = pc.udp - istats.udp_total; - istats.udp_total = pc.udp; - - istats.icmp = pc.icmp - istats.icmp_total; - istats.icmp_total = pc.icmp; - - istats.arp = pc.arp - istats.arp_total; - istats.arp_total = pc.arp; - -#ifdef GRE - istats.ip4ip4 = pc.ip4ip4 - istats.ip4ip4_total; - istats.ip4ip4_total = pc.ip4ip4; - - istats.ip4ip6 = pc.ip4ip6 - istats.ip4ip6_total; - istats.ip4ip6_total = pc.ip4ip6; - - istats.ip6ip4 = pc.ip6ip4 - istats.ip6ip4_total; - istats.ip6ip4_total = pc.ip6ip4; - - istats.ip6ip6 = pc.ip6ip6 - istats.ip6ip6_total; - istats.ip6ip6_total = pc.ip6ip6; - - istats.gre = pc.gre - istats.gre_total; - istats.gre_total = pc.gre; - - istats.gre_ip = pc.gre_ip - istats.gre_ip_total; - istats.gre_ip_total = pc.gre_ip; - - istats.gre_eth = pc.gre_eth - istats.gre_eth_total; - istats.gre_eth_total = pc.gre_eth; - - istats.gre_arp = pc.gre_arp - istats.gre_arp_total; - istats.gre_arp_total = pc.gre_arp; - - istats.gre_ipv6 = pc.gre_ipv6 - istats.gre_ipv6_total; - istats.gre_ipv6_total = pc.gre_ipv6; - - istats.gre_ipx = pc.gre_ipx - istats.gre_ipx_total; - istats.gre_ipx_total = pc.gre_ipx; - - istats.gre_loopback = pc.gre_loopback - istats.gre_loopback_total; - istats.gre_loopback_total = pc.gre_loopback; - - istats.gre_vlan = pc.gre_vlan - istats.gre_vlan_total; - istats.gre_vlan_total = pc.gre_vlan; - - istats.gre_ppp = pc.gre_ppp - istats.gre_ppp_total; - istats.gre_ppp_total = pc.gre_ppp; -#endif - -#ifdef DLT_IEEE802_11 /* if we are tracking wireless, add this to output */ - istats.wifi_mgmt = pc.wifi_mgmt - istats.wifi_mgmt_total; - istats.wifi_mgmt_total = pc.wifi_mgmt; - - istats.wifi_control = pc.wifi_control - istats.wifi_control_total; - istats.wifi_control_total = pc.wifi_control; - - istats.wifi_data = pc.wifi_data - istats.wifi_data_total; - istats.wifi_data_total = pc.wifi_data; -#endif - - istats.ipx = pc.ipx - istats.ipx_total; - istats.ipx_total = pc.ipx; - - istats.eapol = pc.eapol - istats.eapol_total; - istats.eapol_total = pc.eapol; - - istats.ipv6 = pc.ipv6 - istats.ipv6_total; - istats.ipv6_total = pc.ipv6; - - istats.ethloopback = pc.ethloopback - istats.ethloopback_total; - istats.ethloopback_total = pc.ethloopback; - - istats.other = pc.other - istats.other_total; - istats.other_total = pc.other; - - istats.discards = pc.discards - istats.discards_total; - istats.discards_total = pc.discards; - - if (pc.frags > 0) /* do we have any fragmented packets being seen? */ - { - istats.frags = pc.frags - istats.frags_total; - istats.frags_total = pc.frags; - - istats.frag_trackers = pc.frag_trackers - istats.frag_trackers_total; - istats.frag_trackers_total = pc.frag_trackers; - - istats.frag_rebuilt = pc.rebuilt_frags - istats.frag_rebuilt_total; - istats.frag_rebuilt_total = pc.rebuilt_frags; - - istats.frag_element = pc.rebuild_element - istats.frag_element_total; - istats.frag_element_total = pc.rebuild_element; - - istats.frag_incomp = pc.frag_incomp - istats.frag_incomp_total; - istats.frag_incomp_total = pc.frag_incomp; - - istats.frag_timeout = pc.frag_timeout - istats.frag_timeout_total; - istats.frag_timeout_total = pc.frag_timeout; - - istats.frag_mem_faults = pc.frag_mem_faults - istats.frag_mem_faults_total; - istats.frag_mem_faults_total = pc.frag_mem_faults; - } - - if (pc.tcp_stream_pkts > 0) /* do we have TCP stream re-assembly going on? */ - { - istats.tcp_str_packets = pc.tcp_stream_pkts - istats.tcp_str_packets_total; - istats.tcp_str_packets_total = pc.tcp_stream_pkts; - - istats.tcp_str_trackers = pc.tcp_streams - istats.tcp_str_trackers_total; - istats.tcp_str_trackers_total = pc.tcp_streams; - - istats.tcp_str_flushes = pc.rebuilt_tcp - istats.tcp_str_flushes_total; - istats.tcp_str_flushes_total = pc.rebuilt_tcp; - - istats.tcp_str_segs_used = pc.rebuilt_segs - istats.tcp_str_segs_used_total; - istats.tcp_str_segs_used_total = pc.rebuilt_segs; - - istats.tcp_str_segs_queued = pc.queued_segs - istats.tcp_str_segs_queued_total; - istats.tcp_str_segs_queued_total = pc.queued_segs; - - istats.tcp_str_mem_faults = pc.str_mem_faults - istats.tcp_str_mem_faults_total; - istats.tcp_str_mem_faults_total = pc.str_mem_faults; - } - - istats.processed = pc.total_processed - istats.processed_total; - istats.processed_total = pc.total_processed; - total = istats.processed; - - /* prepare packet type per time interval routine */ - LogMessage("================================================" - "===============================\n"); - - LogMessage("\n"); - LogMessage("Statistics Report (last %d seconds)\n", timestats_interval); - LogMessage("\n"); - - per_sec = (double)istats.recv / (double)timestats_interval; - - LogMessage("Packet Wire Totals:\n"); - LogMessage("Packets received: " FMTu64("13") "\n", istats.recv); - - if (timestats_interval >= SECONDS_PER_HOUR) - { - per_hour = (double)(istats.recv * SECONDS_PER_HOUR) / (double)timestats_interval; - LogMessage(" per hour: %13.2f\n", per_hour); - } - if (timestats_interval >= SECONDS_PER_MIN) - { - per_minute = (double)(istats.recv * SECONDS_PER_MIN) / (double)timestats_interval; - LogMessage(" per minute: %13.2f\n", per_minute); - } - LogMessage(" per second: %13.2f\n", per_sec); - LogMessage(" Packets dropped: " FMTu64("13") "\n", istats.drop); - LogMessage("\n"); - LogMessage("Packet Breakdown by Protocol (includes rebuilt packets):\n"); - - LogMessage(" TCP: " FMTu64("10") " (%.3f%%)\n", - istats.tcp, CalcPct(istats.tcp, total)); - LogMessage(" UDP: " FMTu64("10") " (%.3f%%)\n", - istats.udp, CalcPct(istats.udp, total)); - LogMessage(" ICMP: " FMTu64("10") " (%.3f%%)\n", - istats.icmp, CalcPct(istats.icmp, total)); - LogMessage(" ARP: " FMTu64("10") " (%.3f%%)\n", - istats.arp, CalcPct(istats.arp, total)); -#ifndef NO_NON_ETHER_DECODER - LogMessage(" EAPOL: " FMTu64("10") " (%.3f%%)\n", - istats.eapol, CalcPct(istats.eapol, total)); -#endif - LogMessage(" IPv6: " FMTu64("10") " (%.3f%%)\n", - istats.ipv6, CalcPct(istats.ipv6, total)); - LogMessage(" ETHLOOP: " FMTu64("10") " (%.3f%%)\n", - istats.ethloopback, CalcPct(istats.ethloopback, total)); - LogMessage(" IPX: " FMTu64("10") " (%.3f%%)\n", - istats.ipx, CalcPct(istats.ipx, total)); - -#ifdef GRE - LogMessage(" IP4/IP4: " FMTu64("-10") " (%.3f%%)\n", - istats.ip4ip4, CalcPct(istats.ip4ip4, total)); - LogMessage(" IP4/IP6: " FMTu64("-10") " (%.3f%%)\n", - istats.ip4ip6, CalcPct(istats.ip4ip6, total)); - LogMessage(" IP6/IP4: " FMTu64("-10") " (%.3f%%)\n", - istats.ip6ip4, CalcPct(istats.ip6ip4, total)); - LogMessage(" IP6/IP6: " FMTu64("-10") " (%.3f%%)\n", - istats.ip6ip6, CalcPct(istats.ip6ip6, total)); - LogMessage(" GRE: " FMTu64("10") " (%.3f%%)\n", - istats.gre, CalcPct(istats.gre, total)); - LogMessage(" GRE ETH: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_eth, CalcPct(istats.gre_eth, total)); - LogMessage("GRE VLAN: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_vlan, CalcPct(istats.gre_vlan, total)); - LogMessage(" GRE IP: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_ip, CalcPct(istats.gre_ip, total)); - LogMessage("GRE IPv6: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_ipv6, CalcPct(istats.gre_ipv6, total)); - LogMessage("GRE PPTP: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_ppp, CalcPct(istats.gre_ppp, total)); - LogMessage(" GRE ARP: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_arp, CalcPct(istats.gre_arp, total)); - LogMessage(" GRE IPX: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_ipx, CalcPct(istats.gre_ipx, total)); - LogMessage("GRE LOOP: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_loopback, CalcPct(istats.gre_loopback, total)); -#endif - - LogMessage(" FRAG: " FMTu64("10") " (%.3f%%)\n", - istats.frags, CalcPct(istats.frags, total)); - LogMessage(" OTHER: " FMTu64("10") " (%.3f%%)\n", - istats.other, CalcPct(istats.other, total)); - LogMessage(" DISCARD: " FMTu64("10") " (%.3f%%)\n", - istats.discards, CalcPct(istats.discards, total)); - LogMessage(" Total: " FMTu64("10") "\n", total); - - LogMessage("\n"); - - - /* handle case where wireless is enabled... */ - -#ifndef NO_NON_ETHER_DECODER -#ifdef DLT_IEEE802_11 - if (datalink == DLT_IEEE802_11) - { - LogMessage("\n"); - LogMessage("Wireless Stats:\n\n"); - LogMessage("Management Packets: " FMTu64("10") " (%.3f%%)\n", - istats.wifi_mgmt, CalcPct(istats.wifi_mgmt, total)); - LogMessage(" Control Packets: " FMTu64("10") " (%.3f%%)\n", - istats.wifi_control, CalcPct(istats.wifi_control, total)); - LogMessage(" Data Packets: " FMTu64("10") " (%.3f%%)\n", - istats.wifi_data, CalcPct(istats.wifi_data, total)); - LogMessage("\n"); - } - -#endif /* if wireless is enabled... */ -#endif // NO_NON_ETHER_DECODER - - /* handle case where we have snort seeing fragmented packets */ - - if (pc.frags > 0) /* begin if (pc.frags > 0) */ - { - LogMessage("\n"); - LogMessage("Fragmentation Stats:\n\n"); - LogMessage("Fragmented IP Packets: " FMTu64("10") "\n", istats.frags); - LogMessage(" Fragment Trackers: " FMTu64("10") "\n", istats.frag_trackers); - LogMessage(" Rebuilt IP Packets: " FMTu64("10") "\n", istats.frag_rebuilt); - LogMessage(" Frag Elements Used: " FMTu64("10") "\n", istats.frag_element); - LogMessage("Discarded(incomplete): " FMTu64("10") "\n", istats.frag_incomp); - LogMessage(" Discarded(timeout): " FMTu64("10") "\n", istats.frag_timeout); - LogMessage(" Frag2 memory faults: " FMTu64("10") "\n", istats.frag_mem_faults); - LogMessage("\n"); - } /* end if (pc.frags > 0) */ - - /* handle TCP stream re-assy stuff here */ - - if (pc.tcp_stream_pkts > 0) - { - LogMessage("\n"); - LogMessage("TCP Stream Reassembly Stats:\n\n"); - LogMessage(" TCP Packets Used: " FMTu64("10") "\n", istats.tcp_str_packets); - LogMessage(" Stream Trackers: " FMTu64("10") "\n", istats.tcp_str_trackers); - LogMessage(" Stream Flushes: " FMTu64("10") "\n", istats.tcp_str_flushes); - LogMessage(" Stream Segments Used: " FMTu64("10") "\n", istats.tcp_str_segs_used); - LogMessage("Stream Segments Queued: " FMTu64("10") "\n", istats.tcp_str_segs_queued); - LogMessage(" Stream4 Memory Faults: " FMTu64("10") "\n", istats.tcp_str_mem_faults); - LogMessage("\n"); - } - - //mpse_print_qinfo(); - - } /* end if pcap_stats(ps, &ps) */ - - alarm(timestats_interval); /* reset the alarm to go off again */ -} - -/* print out stats on how long snort ran */ -void TimeStats(void) -{ - -/* - * variable definitions for improved statistics handling - * - * end_time = time which snort finished running (unix epoch) - * total_secs = total amount of time snort ran - * int_total_secs = used to eliminate casts from this function (temp. var) - * days = number of days snort ran - * hrs = number of hrs snort ran - * mins = number of minutes snort ran - * secs = number of seconds snort ran - * - * ival = temp. variable for integer/modulus math - * ppd = packets per day processed - * pph = packets per hour processed - * ppm = packets per minute processed - * pps = packets per second processed - * - * hflag = used to flag when hrs = zero, but days > 0 - * mflag = used to flag when min = zero, but hrs > 0 - * - */ - - time_t end_time, total_secs; - uint32_t days = 0, hrs = 0, mins = 0, secs = 0, tmp = 0; - uint64_t pps = 0, ppm = 0, pph = 0, ppd = 0; - uint32_t int_total_secs = 0; - char hflag = 0, mflag = 0; - - - end_time = time(NULL); /* grab epoch for end time value (in seconds) */ - total_secs = end_time - start_time; /* total_secs is how many seconds snort ran for */ - - tmp = (uint32_t)total_secs; - int_total_secs = tmp; /* used for cast elimination */ - - days = tmp / SECONDS_PER_DAY; /* 86400 is number of seconds in a day */ - tmp = tmp % SECONDS_PER_DAY; /* grab remainder to process hours */ - hrs = tmp / SECONDS_PER_HOUR; /* 3600 is number of seconds in a(n) hour */ - tmp = tmp % SECONDS_PER_HOUR; /* grab remainder to process minutes */ - mins = tmp / SECONDS_PER_MIN; /* 60 is number of seconds in a minute */ - secs = tmp % SECONDS_PER_MIN; /* grab remainder to process seconds */ - - if (total_secs) - pps = (pc.total_from_pcap / int_total_secs); - else - pps = pc.total_from_pcap; /* guard against division by zero */ - - /* Use ErrorMessage because this is logged whether - * or not logging quietly */ - ErrorMessage("Snort ran for %u Days %u Hours %u Minutes %u Seconds\n", - days, hrs, mins, secs); - - if (days > 0) - { - ppd = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_DAY)); - ErrorMessage("Snort Analyzed " STDu64 " Packets Per Day\n", ppd); - hflag = 1; - } - - if (hrs > 0 || hflag == 1) - { - pph = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_HOUR)); - ErrorMessage("Snort Analyzed " STDu64 " Packets Per Hour\n", pph); - mflag = 1; - } - - if (mins > 0 || mflag == 1) - { - ppm = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_MIN)); - ErrorMessage("Snort Analyzed " STDu64 " Packets Per Minute\n", ppm); - } - - ErrorMessage("Snort Analyzed " STDu64 " Packets Per Second\n", pps); - ErrorMessage("\n"); -} -#endif /* TIMESTATS */ - - -#ifdef PCAP_CLOSE -int UpdatePcapPktStats(int cacheReturn) -#else -int UpdatePcapPktStats(void) -#endif -{ - struct pcap_stat ps; - uint32_t recv, drop; - static char not_initialized = 1; - -#ifdef PCAP_CLOSE - static int priorReturn = 0; - static int returnWasCached = 0; - - if ( !cacheReturn && returnWasCached ) - { - returnWasCached = 0; - return priorReturn; - } - priorReturn = -1; - returnWasCached = cacheReturn; -#endif - - if (not_initialized) - { - memset(&pkt_stats, 0, sizeof(PcapPktStats)); - not_initialized = 0; - } - - if ((pcap_handle == NULL) || ScReadMode()) - return -1; - - if (pcap_stats(pcap_handle, &ps) == -1) - { - pcap_perror(pcap_handle, "pcap_stats"); - return -1; - } - - recv = (uint32_t)ps.ps_recv; - drop = (uint32_t)ps.ps_drop; - -#ifdef LINUX_LIBPCAP_DOUBLES_STATS - recv /= 2; - drop /= 2; -#endif - -#ifdef LIBPCAP_ACCUMULATES - /* pcap recv wrapped */ - if (recv < pkt_stats.wrap_recv) - pkt_stats.recv += (uint64_t)UINT32_MAX; - - /* pcap drop wrapped */ - if (drop < pkt_stats.wrap_drop) - pkt_stats.drop += (uint64_t)UINT32_MAX; - - pkt_stats.wrap_recv = recv; - pkt_stats.wrap_drop = drop; -#else - pkt_stats.recv += (uint64_t)recv; - pkt_stats.drop += (uint64_t)drop; -#endif /* LIBPCAP_ACCUMULATES */ - -#ifdef PCAP_CLOSE - priorReturn = 0; -#endif - return 0; -} - -uint64_t GetPcapPktStatsRecv(void) -{ - return pkt_stats.recv + (uint64_t)pkt_stats.wrap_recv; -} - -uint64_t GetPcapPktStatsDrop(void) -{ - return pkt_stats.drop + (uint64_t)pkt_stats.wrap_drop; -} - - -#ifdef PCAP_CLOSE -/* exiting should be 0 for if not exiting, 1 if restarting, and 2 if exiting */ -#else -/* exiting should be 0 for if not exiting and 1 if exiting */ -#endif -void DropStats(int exiting) -{ - PreprocStatsFuncNode *idx; - uint64_t total = 0; - uint64_t pkts_recv; - uint64_t pkts_drop; - - total = pc.total_processed; - -#ifdef PPM_MGR - PPM_PRINT_SUMMARY(&snort_conf->ppm_cfg); -#endif - - LogMessage("================================================" - "===============================\n"); - -#ifdef TIMESTATS - TimeStats(); /* how long did snort run? */ -#endif - - if (ScReadMode() -#ifdef GIDS - || ScAdapterInlineMode() -#endif - ) - { - LogMessage("Snort processed " STDu64 " packets.\n", total); - } - else - { -#ifdef PCAP_CLOSE - if (exiting < 2 && (pcap_handle == NULL)) -#else - if (pcap_handle == NULL) -#endif - { - LogMessage("Snort received 0 packets\n"); - } - else - { -#ifdef PCAP_CLOSE - if (UpdatePcapPktStats(0) != -1) -#else - if (UpdatePcapPktStats() != -1) -#endif - { - pkts_recv = GetPcapPktStatsRecv(); - pkts_drop = GetPcapPktStatsDrop(); - - LogMessage("Packet Wire Totals:\n"); - LogMessage(" Received: " FMTu64("12") "\n", pkts_recv); - LogMessage(" Analyzed: " FMTu64("12") " (%.3f%%)\n", pc.total_from_pcap, - CalcPct(pc.total_from_pcap, pkts_recv)); - LogMessage(" Dropped: " FMTu64("12") " (%.3f%%)\n", pkts_drop, - CalcPct(pkts_drop, pkts_recv)); - LogMessage("Outstanding: " FMTu64("12") " (%.3f%%)\n", - pkts_recv - pkts_drop - pc.total_from_pcap, - CalcPct((pkts_recv - pkts_drop - pc.total_from_pcap), pkts_recv)); - } - else - { - LogMessage("Unable to calculate percentages for stats\n"); - LogMessage("Total number of packets Analyzed: " FMTu64("12") "\n", pc.total_from_pcap); - } - } - } - - LogMessage("================================================" - "===============================\n"); - - LogMessage("Breakdown by protocol (includes rebuilt packets):\n"); - - LogMessage(" ETH: " FMTu64("-10") " (%.3f%%)\n", - pc.eth, CalcPct(pc.eth, total)); - LogMessage(" ETHdisc: " FMTu64("-10") " (%.3f%%)\n", - pc.ethdisc, CalcPct(pc.ethdisc, total)); -#ifdef GIDS -#ifndef IPFW - LogMessage(" IPTables: " FMTu64("-10") " (%.3f%%)\n", - pc.iptables, CalcPct(pc.iptables, total)); -#else - LogMessage(" IPFW: " FMTu64("-10") " (%.3f%%)\n", - pc.ipfw, CalcPct(pc.ipfw, total)); -#endif /* IPFW */ -#endif /* GIDS */ - LogMessage(" VLAN: " FMTu64("-10") " (%.3f%%)\n", - pc.vlan, CalcPct(pc.vlan, total)); - - if (pc.nested_vlan != 0) - LogMessage("Nested VLAN: " FMTu64("-10") " (%.3f%%)\n", - pc.nested_vlan, CalcPct(pc.nested_vlan, total)); - - LogMessage(" IPV6: " FMTu64("-10") " (%.3f%%)\n", - pc.ipv6, CalcPct(pc.ipv6, total)); - LogMessage(" IP6 EXT: " FMTu64("-10") " (%.3f%%)\n", - pc.ip6ext, CalcPct(pc.ip6ext, total)); - LogMessage(" IP6opts: " FMTu64("-10") " (%.3f%%)\n", - pc.ipv6opts, CalcPct(pc.ipv6opts, total)); - LogMessage(" IP6disc: " FMTu64("-10") " (%.3f%%)\n", - pc.ipv6disc, CalcPct(pc.ipv6disc, total)); - - LogMessage(" IP4: " FMTu64("-10") " (%.3f%%)\n", - pc.ip, CalcPct(pc.ip, total)); - LogMessage(" IP4disc: " FMTu64("-10") " (%.3f%%)\n", - pc.ipdisc, CalcPct(pc.ipdisc, total)); - - LogMessage(" TCP 6: " FMTu64("-10") " (%.3f%%)\n", - pc.tcp6, CalcPct(pc.tcp6, total)); - LogMessage(" UDP 6: " FMTu64("-10") " (%.3f%%)\n", - pc.udp6, CalcPct(pc.udp6, total)); - LogMessage(" ICMP6: " FMTu64("-10") " (%.3f%%)\n", - pc.icmp6, CalcPct(pc.icmp6, total)); - LogMessage(" ICMP-IP: " FMTu64("-10") " (%.3f%%)\n", - pc.embdip, CalcPct(pc.embdip, total)); - - LogMessage(" TCP: " FMTu64("-10") " (%.3f%%)\n", - pc.tcp, CalcPct(pc.tcp, total)); - LogMessage(" UDP: " FMTu64("-10") " (%.3f%%)\n", - pc.udp, CalcPct(pc.udp, total)); - LogMessage(" ICMP: " FMTu64("-10") " (%.3f%%)\n", - pc.icmp, CalcPct(pc.icmp, total)); - - LogMessage(" TCPdisc: " FMTu64("-10") " (%.3f%%)\n", - pc.tdisc, CalcPct(pc.tdisc, total)); - LogMessage(" UDPdisc: " FMTu64("-10") " (%.3f%%)\n", - pc.udisc, CalcPct(pc.udisc, total)); - LogMessage(" ICMPdis: " FMTu64("-10") " (%.3f%%)\n", - pc.icmpdisc, CalcPct(pc.icmpdisc, total)); - - LogMessage(" FRAG: " FMTu64("-10") " (%.3f%%)\n", - pc.frags, CalcPct(pc.frags, total)); - LogMessage(" FRAG 6: " FMTu64("-10") " (%.3f%%)\n", - pc.frag6, CalcPct(pc.frag6, total)); - - LogMessage(" ARP: " FMTu64("-10") " (%.3f%%)\n", - pc.arp, CalcPct(pc.arp, total)); -#ifndef NO_NON_ETHER_DECODER - LogMessage(" EAPOL: " FMTu64("-10") " (%.3f%%)\n", - pc.eapol, CalcPct(pc.eapol, total)); -#endif - LogMessage(" ETHLOOP: " FMTu64("-10") " (%.3f%%)\n", - pc.ethloopback, CalcPct(pc.ethloopback, total)); - LogMessage(" IPX: " FMTu64("-10") " (%.3f%%)\n", - pc.ipx, CalcPct(pc.ipx, total)); -#ifdef GRE - LogMessage("IPv4/IPv4: " FMTu64("-10") " (%.3f%%)\n", - pc.ip4ip4, CalcPct(pc.ip4ip4, total)); - LogMessage("IPv4/IPv6: " FMTu64("-10") " (%.3f%%)\n", - pc.ip4ip6, CalcPct(pc.ip4ip6, total)); - LogMessage("IPv6/IPv4: " FMTu64("-10") " (%.3f%%)\n", - pc.ip6ip4, CalcPct(pc.ip6ip4, total)); - LogMessage("IPv6/IPv6: " FMTu64("-10") " (%.3f%%)\n", - pc.ip6ip6, CalcPct(pc.ip6ip6, total)); - LogMessage(" GRE: " FMTu64("-10") " (%.3f%%)\n", - pc.gre, CalcPct(pc.gre, total)); - LogMessage(" GRE ETH: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_eth, CalcPct(pc.gre_eth, total)); - LogMessage(" GRE VLAN: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_vlan, CalcPct(pc.gre_vlan, total)); - LogMessage(" GRE IPv4: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ip, CalcPct(pc.gre_ip, total)); - LogMessage(" GRE IPv6: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ipv6, CalcPct(pc.gre_ipv6, total)); - LogMessage("GRE IP6 E: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ipv6ext, CalcPct(pc.gre_ipv6ext, total)); - LogMessage(" GRE PPTP: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ppp, CalcPct(pc.gre_ppp, total)); - LogMessage(" GRE ARP: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_arp, CalcPct(pc.gre_arp, total)); - LogMessage(" GRE IPX: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ipx, CalcPct(pc.gre_ipx, total)); - LogMessage(" GRE LOOP: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_loopback, CalcPct(pc.gre_loopback, total)); -#endif /* GRE */ -#ifdef MPLS - LogMessage(" MPLS: " FMTu64("-10") " (%.3f%%)\n", - pc.mpls, CalcPct(pc.mpls, total)); -#endif - LogMessage(" OTHER: " FMTu64("-10") " (%.3f%%)\n", - pc.other, CalcPct(pc.other, total)); - LogMessage(" DISCARD: " FMTu64("-10") " (%.3f%%)\n", - pc.discards, CalcPct(pc.discards, total)); - LogMessage("InvChkSum: " FMTu64("-10") " (%.3f%%)\n", - pc.invalid_checksums, CalcPct(pc.invalid_checksums, total)); - - LogMessage(" S5 G 1: " FMTu64("-10") " (%.3f%%)\n", - pc.s5tcp1, CalcPct(pc.s5tcp1, total)); - LogMessage(" S5 G 2: " FMTu64("-10") " (%.3f%%)\n", - pc.s5tcp2, CalcPct(pc.s5tcp2, total)); - - LogMessage(" Total: " FMTu64("-10") "\n", total); - - LogMessage("================================================" - "===============================\n"); - - LogMessage("Action Stats:\n"); - LogMessage("ALERTS: " STDu64 "\n", pc.alert_pkts); - LogMessage("LOGGED: " STDu64 "\n", pc.log_pkts); - LogMessage("PASSED: " STDu64 "\n", pc.pass_pkts); - -#ifdef TARGET_BASED - if (ScIdsMode() && IsAdaptiveConfigured(getDefaultPolicy(), 0)) - { - LogMessage("================================================" - "===============================\n"); - LogMessage("Attribute Table Stats:\n"); - LogMessage(" Number Entries: %u\n", SFAT_NumberOfHosts()); - LogMessage(" Table Reloaded: " STDu64 "\n", pc.attribute_table_reloads); - } -#endif /* TARGET_BASED */ - - //mpse_print_qinfo(); - -#ifndef NO_NON_ETHER_DECODER -#ifdef DLT_IEEE802_11 - if(datalink == DLT_IEEE802_11) - { - LogMessage("================================================" - "===============================\n"); - LogMessage("Wireless Stats:\n"); - LogMessage("Breakdown by type:\n"); - LogMessage(" Management Packets: " FMTu64("-10") " (%.3f%%)\n", - pc.wifi_mgmt, CalcPct(pc.wifi_mgmt, total)); - LogMessage(" Control Packets: " FMTu64("-10") " (%.3f%%)\n", - pc.wifi_control, CalcPct(pc.wifi_control, total)); - LogMessage(" Data Packets: " FMTu64("-10") " (%.3f%%)\n", - pc.wifi_data, CalcPct(pc.wifi_data, total)); - } -#endif /* DLT_IEEE802_11 */ -#endif // NO_NON_ETHER_DECODER - - for (idx = preproc_stats_funcs; idx != NULL; idx = idx->next) - { - LogMessage("==============================================" - "=================================\n"); - -#ifdef PCAP_CLOSE - idx->func(exiting ? 1 : 0); -#else - idx->func(exiting); -#endif - } - - LogMessage("==============================================" - "=================================\n"); - - return; -} - -/**************************************************************************** - * - * Function: CleanupProtoNames() - * - * Purpose: Frees the protocol names - * - * Arguments: None. - * - * Returns: void function - * - ****************************************************************************/ -void CleanupProtoNames(void) -{ - int i; - - for(i = 0; i < 256; i++) - { - if( protocol_names[i] != NULL ) - { - free( protocol_names[i] ); - protocol_names[i] = NULL; - } - } -} - -/**************************************************************************** - * - * Function: read_infile(char *) - * - * Purpose: Reads the BPF filters in from a file. Ripped from tcpdump. - * - * Arguments: fname => the name of the file containing the BPF filters - * - * Returns: the processed BPF string - * - ****************************************************************************/ -char *read_infile(char *fname) -{ - register int fd, cc; - register char *cp, *cmt; - struct stat buf; - - fd = open(fname, O_RDONLY); - - if(fd < 0) - FatalError("can't open %s: %s\n", fname, pcap_strerror(errno)); - - if(fstat(fd, &buf) < 0) - FatalError("can't stat %s: %s\n", fname, pcap_strerror(errno)); - - cp = (char *)SnortAlloc(((u_int)buf.st_size + 1) * sizeof(char)); - - cc = read(fd, cp, (int) buf.st_size); - - if(cc < 0) - FatalError("read %s: %s\n", fname, pcap_strerror(errno)); - - if(cc != buf.st_size) - FatalError("short read %s (%d != %d)\n", fname, cc, (int) buf.st_size); - - cp[(int) buf.st_size] = '\0'; - - close(fd); - - /* Treat everything upto the end of the line as a space - * so that we can put comments in our BPF filters - */ - - while((cmt = strchr(cp, '#')) != NULL) - { - while (*cmt != '\r' && *cmt != '\n' && *cmt != '\0') - { - *cmt++ = ' '; - } - } - - /** LogMessage("BPF filter file: %s\n", fname); **/ - - return(cp); -} - - - /**************************************************************************** - * - * Function: CheckLogDir() - * - * Purpose: CyberPsychotic sez: basically we only check if logdir exist and - * writable, since it might screw the whole thing in the middle. Any - * other checks could be performed here as well. - * - * Arguments: None. - * - * Returns: void function - * - ****************************************************************************/ -void CheckLogDir(void) -{ - struct stat st; - - if (snort_conf->log_dir == NULL) - return; - - if (stat(snort_conf->log_dir, &st) == -1) - FatalError("Stat check on log dir failed: %s.\n", strerror(errno)); - - if (!S_ISDIR(st.st_mode) || (access(snort_conf->log_dir, W_OK) == -1)) - { - FatalError("Can not get write access to logging directory \"%s\". " - "(directory doesn't exist or permissions are set incorrectly " - "or it is not a directory at all)\n", - snort_conf->log_dir); - } -} - -/* Signal handler for child process signaling the parent - * that is is ready */ -static int parent_wait = 1; -static void SigChildReadyHandler(int signal) -{ -#ifdef DEBUG - LogMessage("Received Signal from Child\n"); -#endif - parent_wait = 0; -} - -/**************************************************************************** - * - * Function: GoDaemon() - * - * Purpose: Puts the program into daemon mode, nice and quiet like.... - * - * Arguments: None. - * - * Returns: void function - * - ****************************************************************************/ -void GoDaemon(void) -{ -#ifndef WIN32 - int exit_val = 0; - pid_t fs; - - LogMessage("Initializing daemon mode\n"); - - if (ScDaemonRestart()) - return; - - /* Don't daemonize if we've already daemonized and - * received a SIGHUP. */ - if(getppid() != 1) - { - /* Register signal handler that parent can trap signal */ - signal(SIGNAL_SNORT_CHILD_READY, SigChildReadyHandler); - if (errno != 0) errno=0; - - /* now fork the child */ - fs = fork(); - - if(fs > 0) - { - /* Parent */ - - /* Don't exit quite yet. Wait for the child - * to signal that is there and created the PID - * file. - */ - while (parent_wait) - { - /* Continue waiting until receiving signal from child */ - int status; - if (waitpid(fs, &status, WNOHANG) == fs) - { - /* If the child is gone, parent should go away, too */ - if (WIFEXITED(status)) - { - LogMessage("Child exited unexpectedly\n"); - exit_val = -1; - break; - } - - if (WIFSIGNALED(status)) - { - LogMessage("Child terminated unexpectedly\n"); - exit_val = -2; - break; - } - } -#ifdef DEBUG - LogMessage("Parent waiting for child...\n"); -#endif - - sleep(1); - } - - LogMessage("Daemon parent exiting\n"); - - exit(exit_val); /* parent */ - } - - if(fs < 0) - { - /* Daemonizing failed... */ - perror("fork"); - exit(1); - } - - /* Child */ - setsid(); - } - - close(0); - close(1); - close(2); - -#ifdef DEBUG - /* redirect stdin/stdout/stderr to a file */ - open("/tmp/snort.debug", O_CREAT | O_RDWR); /* stdin, fd 0 */ - - /* Change ownership to that which we will drop privileges to */ - if ((snort_conf->user_id != -1) || (snort_conf->group_id != -1)) - { - uid_t user_id = getuid(); - gid_t group_id = getgid(); - - if (snort_conf->user_id != -1) - user_id = snort_conf->user_id; - if (snort_conf->group_id != -1) - group_id = snort_conf->group_id; - - chown("/tmp/snort.debug", user_id, group_id); - } -#else - /* redirect stdin/stdout/stderr to /dev/null */ - (void)open("/dev/null", O_RDWR); /* stdin, fd 0 */ -#endif - - dup(0); /* stdout, fd 0 => fd 1 */ - dup(0); /* stderr, fd 0 => fd 2 */ - - SignalWaitingParent(); - -#endif /* ! WIN32 */ -} - -/* Signal the parent that child is ready */ -void SignalWaitingParent(void) -{ -#ifndef WIN32 - pid_t parentpid = getppid(); -#ifdef DEBUG - LogMessage("Signaling parent %d from child %d\n", parentpid, getpid()); -#endif - - if (kill(parentpid, SIGNAL_SNORT_CHILD_READY)) - { - LogMessage("Daemon initialized, failed to signal parent pid: %d, failure: %d, %s\n", parentpid, errno, strerror(errno)); - } - else - { - LogMessage("Daemon initialized, signaled parent pid: %d\n", parentpid); - } -#endif -} - -/* This function has been moved into mstring.c, since that -* is where the allocation actually occurs. It has been -* renamed to mSplitFree(). -* -void FreeToks(char **toks, int num_toks) -{ - if (toks) - { - if (num_toks > 0) - { - do - { - num_toks--; - free(toks[num_toks]); - } while(num_toks); - } - free(toks); - } -} -*/ - - -/* Self preserving memory allocator */ -void *SPAlloc(unsigned long size, struct _SPMemControl *spmc) -{ - void *tmp; - - spmc->mem_usage += size; - - if(spmc->mem_usage > spmc->memcap) - { - spmc->sp_func(spmc); - } - - tmp = (void *) calloc(size, sizeof(char)); - - if(tmp == NULL) - { - FatalError("Unable to allocate memory! (%lu requested, %lu in use)\n", - size, spmc->mem_usage); - } - - return tmp; -} - -/* Guaranteed to be '\0' terminated even if truncation occurs. - * - * returns SNORT_SNPRINTF_SUCCESS if successful - * returns SNORT_SNPRINTF_TRUNCATION on truncation - * returns SNORT_SNPRINTF_ERROR on error - */ -int SnortSnprintf(char *buf, size_t buf_size, const char *format, ...) -{ - va_list ap; - int ret; - - if (buf == NULL || buf_size <= 0 || format == NULL) - return SNORT_SNPRINTF_ERROR; - - /* zero first byte in case an error occurs with - * vsnprintf, so buffer is null terminated with - * zero length */ - buf[0] = '\0'; - buf[buf_size - 1] = '\0'; - - va_start(ap, format); - - ret = vsnprintf(buf, buf_size, format, ap); - - va_end(ap); - - if (ret < 0) - return SNORT_SNPRINTF_ERROR; - - if (buf[buf_size - 1] != '\0' || (size_t)ret >= buf_size) - { - /* result was truncated */ - buf[buf_size - 1] = '\0'; - return SNORT_SNPRINTF_TRUNCATION; - } - - return SNORT_SNPRINTF_SUCCESS; -} - -/* Appends to a given string - * Guaranteed to be '\0' terminated even if truncation occurs. - * - * returns SNORT_SNPRINTF_SUCCESS if successful - * returns SNORT_SNPRINTF_TRUNCATION on truncation - * returns SNORT_SNPRINTF_ERROR on error - */ -int SnortSnprintfAppend(char *buf, size_t buf_size, const char *format, ...) -{ - int str_len; - int ret; - va_list ap; - - if (buf == NULL || buf_size <= 0 || format == NULL) - return SNORT_SNPRINTF_ERROR; - - str_len = SnortStrnlen(buf, buf_size); - - /* since we've already checked buf and buf_size an error - * indicates no null termination, so just start at - * beginning of buffer */ - if (str_len == SNORT_STRNLEN_ERROR) - { - buf[0] = '\0'; - str_len = 0; - } - - buf[buf_size - 1] = '\0'; - - va_start(ap, format); - - ret = vsnprintf(buf + str_len, buf_size - (size_t)str_len, format, ap); - - va_end(ap); - - if (ret < 0) - return SNORT_SNPRINTF_ERROR; - - if (buf[buf_size - 1] != '\0' || (size_t)ret >= buf_size) - { - /* truncation occured */ - buf[buf_size - 1] = '\0'; - return SNORT_SNPRINTF_TRUNCATION; - } - - return SNORT_SNPRINTF_SUCCESS; -} - -/* Guaranteed to be '\0' terminated even if truncation occurs. - * - * Arguments: dst - the string to contain the copy - * src - the string to copy from - * dst_size - the size of the destination buffer - * including the null byte. - * - * returns SNORT_STRNCPY_SUCCESS if successful - * returns SNORT_STRNCPY_TRUNCATION on truncation - * returns SNORT_STRNCPY_ERROR on error - * - * Note: Do not set dst[0] = '\0' on error since it's possible that - * dst and src are the same pointer - it will at least be null - * terminated in any case - */ -int SnortStrncpy(char *dst, const char *src, size_t dst_size) -{ - char *ret = NULL; - - if (dst == NULL || src == NULL || dst_size <= 0) - return SNORT_STRNCPY_ERROR; - - dst[dst_size - 1] = '\0'; - - ret = strncpy(dst, src, dst_size); - - /* Not sure if this ever happens but might as - * well be on the safe side */ - if (ret == NULL) - return SNORT_STRNCPY_ERROR; - - if (dst[dst_size - 1] != '\0') - { - /* result was truncated */ - dst[dst_size - 1] = '\0'; - return SNORT_STRNCPY_TRUNCATION; - } - - return SNORT_STRNCPY_SUCCESS; -} - -char *SnortStrndup(const char *src, size_t dst_size) -{ - char *ret = SnortAlloc(dst_size + 1); - int ret_val; - - ret_val = SnortStrncpy(ret, src, dst_size + 1); - - if(ret_val == SNORT_STRNCPY_ERROR) - { - free(ret); - return NULL; - } - - return ret; -} - -/* Determines whether a buffer is '\0' terminated and returns the - * string length if so - * - * returns the string length if '\0' terminated - * returns SNORT_STRNLEN_ERROR if not '\0' terminated - */ -int SnortStrnlen(const char *buf, int buf_size) -{ - int i = 0; - - if (buf == NULL || buf_size <= 0) - return SNORT_STRNLEN_ERROR; - - for (i = 0; i < buf_size; i++) - { - if (buf[i] == '\0') - break; - } - - if (i == buf_size) - return SNORT_STRNLEN_ERROR; - - return i; -} - -char * SnortStrdup(const char *str) -{ - char *copy = NULL; - - if (!str) - { - FatalError("Unable to duplicate string: NULL!\n"); - } - - copy = strdup(str); - - if (copy == NULL) - { - FatalError("Unable to duplicate string: %s!\n", str); - } - - return copy; -} - -/* - * Find first occurrence of char of accept in s, limited by slen. - * A 'safe' version of strpbrk that won't read past end of buffer s - * in cases that s is not NULL terminated. - * - * This code assumes 'accept' is a static string. - */ -const char *SnortStrnPbrk(const char *s, int slen, const char *accept) -{ - char ch; - const char *s_end; - if (!s || !*s || !accept || slen == 0) - return NULL; - - s_end = s + slen; - while (s < s_end) - { - ch = *s; - if (strchr(accept, ch)) - return s; - s++; - } - return NULL; -} - -/* - * Find first occurrence of searchstr in s, limited by slen. - * A 'safe' version of strstr that won't read past end of buffer s - * in cases that s is not NULL terminated. - */ -const char *SnortStrnStr(const char *s, int slen, const char *searchstr) -{ - char ch, nc; - int len; - if (!s || !*s || !searchstr || slen == 0) - return NULL; - - if ((ch = *searchstr++) != 0) - { - len = strlen(searchstr); - do - { - do - { - if ((nc = *s++) == 0) - { - return NULL; - } - slen--; - if (slen == 0) - return NULL; - } while (nc != ch); - if (slen - len < 0) - return NULL; - } while (memcmp(s, searchstr, len) != 0); - s--; - slen++; - } - return s; -} - -/* - * Find first occurrence of substring in s, ignore case. -*/ -const char *SnortStrcasestr(const char *s, const char *substr) -{ - char ch, nc; - int len; - - if (!s || !*s || !substr) - return NULL; - - if ((ch = *substr++) != 0) - { - ch = tolower((char)ch); - len = strlen(substr); - do - { - do - { - if ((nc = *s++) == 0) - { - return NULL; - } - } while ((char)tolower((uint8_t)nc) != ch); - } while (strncasecmp(s, substr, len) != 0); - s--; - } - return s; -} - -void *SnortAlloc(unsigned long size) -{ - void *tmp; - - tmp = (void *) calloc(size, sizeof(char)); - - if(tmp == NULL) - { - FatalError("Unable to allocate memory! (%lu requested)\n", size); - } - - return tmp; -} - -void * SnortAlloc2(size_t size, const char *format, ...) -{ - void *tmp; - - tmp = (void *)calloc(size, sizeof(char)); - - if(tmp == NULL) - { - va_list ap; - char buf[STD_BUF]; - - buf[STD_BUF - 1] = '\0'; - - va_start(ap, format); - - vsnprintf(buf, STD_BUF - 1, format, ap); - - va_end(ap); - - FatalError("%s", buf); - } - - return tmp; -} - -/** - * Chroot and adjust the snort_conf->log_dir reference - * - * @param directory directory to chroot to - * @param logstore ptr to snort_conf->log_dir which must be dynamically allocated - */ -void SetChroot(char *directory, char **logstore) -{ -#ifdef WIN32 - FatalError("SetChroot() should not be called under Win32!\n"); -#else - char *absdir; - size_t abslen; - char *logdir; - - if(!directory || !logstore) - { - FatalError("Null parameter passed\n"); - } - - logdir = *logstore; - - if(logdir == NULL || *logdir == '\0') - { - FatalError("Null log directory\n"); - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"SetChroot: %s\n", - CurrentWorkingDir());); - - logdir = GetAbsolutePath(logdir); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "SetChroot: %s\n", - CurrentWorkingDir())); - - logdir = SnortStrdup(logdir); - - /* We're going to reset logstore, so free it now */ - free(*logstore); - *logstore = NULL; - - /* change to the directory */ - if(chdir(directory) != 0) - { - FatalError("SetChroot: Can not chdir to \"%s\": %s\n", directory, - strerror(errno)); - } - - /* always returns an absolute pathname */ - absdir = CurrentWorkingDir(); - - if(absdir == NULL) - { - FatalError("NULL Chroot found\n"); - } - - abslen = strlen(absdir); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "ABS: %s %d\n", absdir, abslen);); - - /* make the chroot call */ - if(chroot(absdir) < 0) - { - FatalError("Can not chroot to \"%s\": absolute: %s: %s\n", - directory, absdir, strerror(errno)); - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chroot success (%s ->", absdir);); - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"%s)\n ", CurrentWorkingDir());); - - /* change to "/" in the new directory */ - if(chdir("/") < 0) - { - FatalError("Can not chdir to \"/\" after chroot: %s\n", - strerror(errno)); - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chdir success (%s)\n", - CurrentWorkingDir());); - - - if(strncmp(absdir, logdir, strlen(absdir))) - { - FatalError("Absdir is not a subset of the logdir"); - } - - if(abslen >= strlen(logdir)) - { - *logstore = SnortStrdup("/"); - } - else - { - *logstore = SnortStrdup(logdir + abslen); - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"new logdir from %s to %s\n", - logdir, *logstore)); - - LogMessage("Chroot directory = %s\n", directory); - -#if 0 - /* XXX XXX */ - /* install the I can't do this signal handler */ - signal(SIGHUP, SigCantHupHandler); -#endif -#endif /* !WIN32 */ -} - - -/** - * Return a ptr to the absolute pathname of snort. This memory must - * be copied to another region if you wish to save it for later use. - */ -char *CurrentWorkingDir(void) -{ - static char buf[PATH_MAX_UTIL + 1]; - - if(getcwd((char *) buf, PATH_MAX_UTIL) == NULL) - { - return NULL; - } - - buf[PATH_MAX_UTIL] = '\0'; - - return (char *) buf; -} - -/** - * Given a directory name, return a ptr to a static - */ -char *GetAbsolutePath(char *dir) -{ - char *savedir, *dirp; - static char buf[PATH_MAX_UTIL + 1]; - - if(dir == NULL) - { - return NULL; - } - - savedir = strdup(CurrentWorkingDir()); - - if(savedir == NULL) - { - return NULL; - } - - if(chdir(dir) < 0) - { - LogMessage("Can't change to directory: %s\n", dir); - free(savedir); - return NULL; - } - - dirp = CurrentWorkingDir(); - - if(dirp == NULL) - { - LogMessage("Unable to access current directory\n"); - free(savedir); - return NULL; - } - else - { - strncpy(buf, dirp, PATH_MAX_UTIL); - buf[PATH_MAX_UTIL] = '\0'; - } - - if(chdir(savedir) < 0) - { - LogMessage("Can't change back to directory: %s\n", dir); - free(savedir); - return NULL; - } - - free(savedir); - return (char *) buf; -} - - -#ifndef WIN32 -/* very slow sort - do not use at runtime! */ -SF_LIST * SortDirectory(const char *path) -{ - SF_LIST *dir_entries; - DIR *dir; - struct dirent *direntry; - int ret = 0; - - if (path == NULL) - return NULL; - - dir_entries = sflist_new(); - if (dir_entries == NULL) - { - ErrorMessage("Could not allocate new list for directory entries\n"); - return NULL; - } - - dir = opendir(path); - if (dir == NULL) - { - ErrorMessage("Error opening directory: %s: %s\n", - path, strerror(errno)); - sflist_free_all(dir_entries, free); - return NULL; - } - - /* Reset errno since we'll be checking it unconditionally */ - errno = 0; - - while ((direntry = readdir(dir)) != NULL) - { - char *node_entry_name, *dir_entry_name; - SF_LNODE *node; - - dir_entry_name = SnortStrdup(direntry->d_name); - - for (node = sflist_first_node(dir_entries); - node != NULL; - node = sflist_next_node(dir_entries)) - { - node_entry_name = (char *)node->ndata; - if (strcmp(dir_entry_name, node_entry_name) < 0) - break; - } - - if (node == NULL) - ret = sflist_add_tail(dir_entries, (NODE_DATA)dir_entry_name); - else - ret = sflist_add_before(dir_entries, node, (NODE_DATA)dir_entry_name); - - if (ret == -1) - { - ErrorMessage("Error adding directory entry to list\n"); - sflist_free_all(dir_entries, free); - closedir(dir); - return NULL; - } - } - - if (errno != 0) - { - ErrorMessage("Error reading directory: %s: %s\n", - path, strerror(errno)); - errno = 0; - sflist_free_all(dir_entries, free); - closedir(dir); - return NULL; - } - - closedir(dir); - - return dir_entries; -} - -int GetFilesUnderDir(const char *path, SF_QUEUE *dir_queue, const char *filter) -{ - SF_LIST *dir_entries; - char *direntry; - int ret = 0; - int num_files = 0; - - if ((path == NULL) || (dir_queue == NULL)) - return -1; - - dir_entries = SortDirectory(path); - if (dir_entries == NULL) - { - ErrorMessage("Error sorting entries in directory: %s\n", path); - return -1; - } - - for (direntry = (char *)sflist_first(dir_entries); - direntry != NULL; - direntry = (char *)sflist_next(dir_entries)) - { - char path_buf[PATH_MAX]; - struct stat file_stat; - - /* Don't look at dot files */ - if (strncmp(".", direntry, 1) == 0) - continue; - - ret = SnortSnprintf(path_buf, PATH_MAX, "%s%s%s", - path, path[strlen(path) - 1] == '/' ? "" : "/", direntry); - if (ret == SNORT_SNPRINTF_TRUNCATION) - { - ErrorMessage("Error copying file to buffer: Path too long\n"); - sflist_free_all(dir_entries, free); - return -1; - } - else if (ret != SNORT_SNPRINTF_SUCCESS) - { - ErrorMessage("Error copying file to buffer\n"); - sflist_free_all(dir_entries, free); - return -1; - } - - ret = stat(path_buf, &file_stat); - if (ret == -1) - { - ErrorMessage("Could not stat file: %s: %s\n", - path_buf, strerror(errno)); - sflist_free_all(dir_entries, free); - return -1; - } - - if (file_stat.st_mode & S_IFDIR) - { - ret = GetFilesUnderDir(path_buf, dir_queue, filter); - if (ret == -1) - { - sflist_free_all(dir_entries, free); - return -1; - } - - num_files += ret; - } - else if (file_stat.st_mode & S_IFREG) - { - if ((filter == NULL) || (fnmatch(filter, direntry, 0) == 0)) - { - char *file = SnortStrdup(path_buf); - - ret = sfqueue_add(dir_queue, (NODE_DATA)file); - if (ret == -1) - { - ErrorMessage("Could not append item to list: %s\n", file); - free(file); - sflist_free_all(dir_entries, free); - return -1; - } - - num_files++; - } - } - } - - sflist_free_all(dir_entries, free); - - return num_files; -} -#endif - -/**************************************************************************** - * - * Function: GetUniqueName(char * iface) - * - * Purpose: To return a string that has a high probability of being unique - * for a given sensor. - * - * Arguments: char * iface - The network interface you are sniffing - * - * Returns: A char * -- its a static char * so you should not free it - * - ***************************************************************************/ -char *GetUniqueName(char * iface) -{ - char * rptr; - static char uniq_name[256]; - - if (iface == NULL) LogMessage("Interface is NULL. Name may not be unique for the host\n"); -#ifndef WIN32 - rptr = GetIP(iface); - if(rptr == NULL || !strcmp(rptr, "unknown")) -#endif - { - SnortSnprintf(uniq_name, 255, "%s:%s\n",GetHostname(),iface); - rptr = uniq_name; - } - if (ScLogVerbose()) LogMessage("Node unique name is: %s\n", rptr); - return rptr; -} - -/**************************************************************************** - * - * Function: GetIP(char * iface) - * - * Purpose: To return a string representing the IP address for an interface - * - * Arguments: char * iface - The network interface you want to find an IP - * address for. - * - * Returns: A char * -- make sure you call free on this when you are done - * with it. - * - ***************************************************************************/ -char *GetIP(char * iface) -{ - struct ifreq ifr; - struct sockaddr_in *addr; - int s; -#ifdef SUP_IP6 - sfip_t ret; -#endif - - if(iface) - { - /* Set up a dummy socket just so we can use ioctl to find the - ip address of the interface */ - s = socket(PF_INET, SOCK_DGRAM, 0); - if(s == -1) - { - FatalError("Problem establishing socket to find IP address for interface: %s\n", iface); - } - - SnortStrncpy(ifr.ifr_name, iface, strlen(iface) + 1); - -#ifndef WIN32 - if(ioctl(s, SIOCGIFADDR, &ifr) < 0) return NULL; - else -#endif - { - addr = (struct sockaddr_in *) &ifr.ifr_broadaddr; - } - close(s); - -#ifdef SUP_IP6 -// XXX-IPv6 uses ioctl to populate a sockaddr_in structure ... but what if the interface only has an IPv6 address? - sfip_set_raw(&ret, addr, AF_INET); - return SnortStrdup(sfip_ntoa(&ret)); -#else - return SnortStrdup(inet_ntoa(addr->sin_addr)); -#endif - } - else - { - return "unknown"; - } -} - -/**************************************************************************** - * - * Function: GetHostname() - * - * Purpose: To return a string representing the hostname - * - * Arguments: None - * - * Returns: A static char * representing the hostname. - * - ***************************************************************************/ -char *GetHostname(void) -{ -#ifdef WIN32 - DWORD bufflen = 256; - static char buff[256]; - GetComputerName(buff, &bufflen); - return buff; -#else - char * error = "unknown"; - if(getenv("HOSTNAME")) return getenv("HOSTNAME"); - else if(getenv("HOST")) return getenv("HOST"); - else return error; -#endif -} - -/**************************************************************************** - * - * Function: GetTimestamp(register const struct timeval *tvp, int tz) - * - * Purpose: Get an ISO-8601 formatted timestamp for tvp within the tz - * timezone. - * - * Arguments: tvp is a timeval pointer. tz is a timezone. - * - * Returns: char * -- You must free this char * when you are done with it. - * - ***************************************************************************/ -char *GetTimestamp(register const struct timeval *tvp, int tz) -{ - struct tm *lt; /* localtime */ - char * buf; - int msec; - - buf = (char *)SnortAlloc(SMALLBUFFER * sizeof(char)); - - msec = tvp->tv_usec / 1000; - - if (ScOutputUseUtc()) - { - lt = gmtime((time_t *)&tvp->tv_sec); - SnortSnprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec, msec); - } - else - { - lt = localtime((time_t *)&tvp->tv_sec); - SnortSnprintf(buf, SMALLBUFFER, - "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz); - } - - return buf; -} - -/**************************************************************************** - * - * Function: GetLocalTimezone() - * - * Purpose: Find the offset from GMT for current host - * - * Arguments: none - * - * Returns: int representing the offset from GMT - * - ***************************************************************************/ -int GetLocalTimezone(void) -{ - time_t ut; - struct tm * ltm; - long seconds_away_from_utc; - - time(&ut); - ltm = localtime(&ut); - -#if defined(WIN32) || defined(SOLARIS) || defined(AIX) || defined(HPUX) - /* localtime() sets the global timezone variable, - which is defined in <time.h> */ - seconds_away_from_utc = timezone; -#else - seconds_away_from_utc = ltm->tm_gmtoff; -#endif - - return seconds_away_from_utc/3600; -} - -/**************************************************************************** - * - * Function: GetCurrentTimestamp() - * - * Purpose: Generate an ISO-8601 formatted timestamp for the current time. - * - * Arguments: none - * - * Returns: char * -- You must free this char * when you are done with it. - * - ***************************************************************************/ -char *GetCurrentTimestamp(void) -{ - struct tm *lt; - struct timezone tz; - struct timeval tv; - struct timeval *tvp; - char * buf; - int tzone; - int msec; - - buf = (char *)SnortAlloc(SMALLBUFFER * sizeof(char)); - - bzero((char *)&tz,sizeof(tz)); - gettimeofday(&tv,&tz); - tvp = &tv; - - msec = tvp->tv_usec/1000; - - if (ScOutputUseUtc()) - { - lt = gmtime((time_t *)&tvp->tv_sec); - SnortSnprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec, msec); - } - else - { - lt = localtime((time_t *)&tvp->tv_sec); - - tzone = GetLocalTimezone(); - - SnortSnprintf(buf, SMALLBUFFER, - "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tzone); - } - - return buf; -} - -/**************************************************************************** - * Function: base64(char * xdata, int length) - * - * Purpose: Insert data into the database - * - * Arguments: xdata => pointer to data to base64 encode - * length => how much data to encode - * - * Make sure you allocate memory for the output before you pass - * the output pointer into this function. You should allocate - * (1.5 * length) bytes to be safe. - * - * Returns: data base64 encoded as a char * - * - ***************************************************************************/ -char * base64(const u_char * xdata, int length) -{ - int count, cols, bits, c, char_count; - unsigned char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* 64 bytes */ - char * payloadptr; - char * output; - char_count = 0; - bits = 0; - cols = 0; - - output = (char *)SnortAlloc( ((unsigned int) (length * 1.5 + 4)) * sizeof(char) ); - - payloadptr = output; - - for(count = 0; count < length; count++) - { - c = xdata[count]; - - if(c > 255) - { - ErrorMessage("plugbase.c->base64(): encountered char > 255 (decimal %d)\n If you see this error message a char is more than one byte on your machine\n This means your base64 results can not be trusted", c); - } - - bits += c; - char_count++; - - if(char_count == 3) - { - *output = alpha[bits >> 18]; output++; - *output = alpha[(bits >> 12) & 0x3f]; output++; - *output = alpha[(bits >> 6) & 0x3f]; output++; - *output = alpha[bits & 0x3f]; output++; - cols += 4; - if(cols == 72) - { - *output = '\n'; output++; - cols = 0; - } - bits = 0; - char_count = 0; - } - else - { - bits <<= 8; - } - } - - if(char_count != 0) - { - bits <<= 16 - (8 * char_count); - *output = alpha[bits >> 18]; output++; - *output = alpha[(bits >> 12) & 0x3f]; output++; - if(char_count == 1) - { - *output = '='; output++; - *output = '='; output++; - } - else - { - *output = alpha[(bits >> 6) & 0x3f]; - output++; *output = '='; - output++; - } - } - *output = '\0'; - return payloadptr; -} - -/**************************************************************************** - * - * Function: ascii(u_char *xdata, int length) - * - * Purpose: This function takes takes a buffer "xdata" and its length then - * returns a string of only the printable ASCII characters. - * - * Arguments: xdata is the buffer, length is the length of the buffer in - * bytes - * - * Returns: char * -- You must free this char * when you are done with it. - * - ***************************************************************************/ -char *ascii(const u_char *xdata, int length) -{ - char *d_ptr, *ret_val; - int i,count = 0; - int size; - - if(xdata == NULL) - { - return NULL; - } - - for(i=0;i<length;i++) - { - if(xdata[i] == '<') - count+=4; /* < */ - else if(xdata[i] == '&') - count+=5; /* & */ - else if(xdata[i] == '>') /* > */ - count += 4; - } - - size = length + count + 1; - ret_val = (char *) calloc(1,size); - - if(ret_val == NULL) - { - LogMessage("plugbase.c: ascii(): Out of memory, can't log anything!\n"); - return NULL; - } - - d_ptr = ret_val; - - for(i=0;i<length;i++) - { - if((xdata[i] > 0x1F) && (xdata[i] < 0x7F)) - { - if(xdata[i] == '<') - { - SnortStrncpy(d_ptr, "<", size - (d_ptr - ret_val)); - d_ptr+=4; - } - else if(xdata[i] == '&') - { - SnortStrncpy(d_ptr, "&", size - (d_ptr - ret_val)); - d_ptr += 5; - } - else if(xdata[i] == '>') - { - SnortStrncpy(d_ptr, ">", size - (d_ptr - ret_val)); - d_ptr += 4; - } - else - { - *d_ptr++ = xdata[i]; - } - } - else - { - *d_ptr++ = '.'; - } - } - - *d_ptr++ = '\0'; - - return ret_val; -} - -/**************************************************************************** - * - * Function: hex(u_char *xdata, int length) - * - * Purpose: This function takes takes a buffer "xdata" and its length then - * returns a string of hex with no spaces - * - * Arguments: xdata is the buffer, length is the length of the buffer in - * bytes - * - * Returns: char * -- You must free this char * when you are done with it. - * - ***************************************************************************/ -char *hex(const u_char *xdata, int length) -{ - int x; - char *rval = NULL; - char *buf = NULL; - - if (xdata == NULL) - return NULL; - - buf = (char *)calloc((length * 2) + 1, sizeof(char)); - - if (buf != NULL) - { - rval = buf; - - for (x = 0; x < length; x++) - { - SnortSnprintf(buf, 3, "%02X", xdata[x]); - buf += 2; - } - - rval[length * 2] = '\0'; - } - - return rval; -} - - - -char *fasthex(const u_char *xdata, int length) -{ - char conv[] = "0123456789ABCDEF"; - char *retbuf = NULL; - const u_char *index; - const u_char *end; - char *ridx; - - index = xdata; - end = xdata + length; - retbuf = (char *)SnortAlloc(((length * 2) + 1) * sizeof(char)); - ridx = retbuf; - - while(index < end) - { - *ridx++ = conv[((*index & 0xFF)>>4)]; - *ridx++ = conv[((*index & 0xFF)&0x0F)]; - index++; - } - - return retbuf; -} - -/* - * Fatal Integer Parser - * Ascii to Integer conversion with fatal error support - */ -long int xatol(const char *s , const char *etext) -{ - long int val; - char *endptr; - char *default_error = "xatol() error\n"; - - if (etext == NULL) - etext = default_error; - - if (s == NULL) - FatalError("%s: String is NULL\n", etext); - - while (isspace((int)*s)) - s++; - - if (strlen(s) == 0) - FatalError("%s: String is empty\n", etext); - - - /* - * strtoul - errors on win32 : ERANGE (VS 6.0) - * errors on linux : ERANGE, EINVAL - * (for EINVAL, unsupported base which won't happen here) - */ - val = SnortStrtol(s, &endptr, 0); - - if ((errno == ERANGE) || (*endptr != '\0')) - FatalError("%s: Invalid integer input: %s\n", etext, s); - - return val; -} - -/* - * Fatal Integer Parser - * Ascii to Integer conversion with fatal error support - */ -unsigned long int xatou(const char *s , const char *etext) -{ - unsigned long int val; - char *endptr; - char *default_error = "xatou() error\n"; - - if (etext == NULL) - etext = default_error; - - if (s == NULL) - FatalError("%s: String is NULL\n", etext); - - while (isspace((int)*s)) - s++; - - if (strlen(s) == 0) - FatalError("%s: String is empty\n", etext); - - if (*s == '-') - { - FatalError("%s: Invalid unsigned integer - negative sign found, " - "input: %s\n", etext, s); - } - - - /* - * strtoul - errors on win32 : ERANGE (VS 6.0) - * errors on linux : ERANGE, EINVAL - */ - val = SnortStrtoul(s, &endptr, 0); - - if ((errno == ERANGE) || (*endptr != '\0')) - FatalError("%s: Invalid integer input: %s\n", etext, s); - - return val; -} - -unsigned long int xatoup(const char *s , const char *etext) -{ - unsigned long int val = xatou(s, etext); - if ( !val ) - FatalError("%s: must be > 0\n", etext); - return val; -} - -#ifndef SUP_IP6 -char * ObfuscateIpToText(const struct in_addr ip_addr) -#else -char * ObfuscateIpToText(sfip_t *ip) -#endif -{ - static char ip_buf1[INET6_ADDRSTRLEN]; - static char ip_buf2[INET6_ADDRSTRLEN]; - static int buf_num = 0; - int buf_size = INET6_ADDRSTRLEN; - char *ip_buf; -#ifndef SUP_IP6 - uint32_t ip = ip_addr.s_addr; -#endif - - if (buf_num) - ip_buf = ip_buf2; - else - ip_buf = ip_buf1; - - buf_num ^= 1; - ip_buf[0] = 0; - -#ifndef SUP_IP6 - if (ip == 0) - return ip_buf; - - if (snort_conf->obfuscation_net == 0) - { - /* Fully obfuscate - just use 'x' */ - SnortSnprintf(ip_buf, buf_size, "xxx.xxx.xxx.xxx"); - } - else - { - if (snort_conf->homenet != 0) - { - if ((ip & snort_conf->netmask) == snort_conf->homenet) - ip = snort_conf->obfuscation_net | (ip & snort_conf->obfuscation_mask); - } - else - { - ip = snort_conf->obfuscation_net | (ip & snort_conf->obfuscation_mask); - } - - SnortSnprintf(ip_buf, buf_size, "%s", inet_ntoa(*((struct in_addr *)&ip))); - } - -#else - if (ip == NULL) - return ip_buf; - - if (!IS_SET(snort_conf->obfuscation_net)) - { - if (IS_IP6(ip)) - SnortSnprintf(ip_buf, buf_size, "x:x:x:x::x:x:x:x"); - else - SnortSnprintf(ip_buf, buf_size, "xxx.xxx.xxx.xxx"); - } - else - { - sfip_t tmp; - char *tmp_buf; - - IP_COPY_VALUE(tmp, ip); - - if (IS_SET(snort_conf->homenet)) - { - if (sfip_contains(&snort_conf->homenet, &tmp) == SFIP_CONTAINS) - sfip_obfuscate(&snort_conf->obfuscation_net, &tmp); - } - else - { - sfip_obfuscate(&snort_conf->obfuscation_net, &tmp); - } - - tmp_buf = sfip_to_str(&tmp); - SnortSnprintf(ip_buf, buf_size, "%s", tmp_buf); - } -#endif - - return ip_buf; -} - -void PrintPacketData(const uint8_t *data, const uint32_t len) -{ - uint32_t i, j; - uint32_t total_len = 0; - uint8_t hex_buf[16]; - uint8_t char_buf[16]; - char *length_chars = " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n" - "------------------------------------------------------\n"; - - LogMessage("%s", length_chars); - - for (i = 0; i <= len; i++) - { - if ((i%16 == 0) && (i != 0)) - { - LogMessage("%04x ", total_len); - total_len += 16; - - for (j = 0; j < 16; j++) - { - LogMessage("%02x ", hex_buf[j]); - if (j == 7) - LogMessage(" "); - } - - LogMessage(" "); - - for (j = 0; j < 16; j++) - { - LogMessage("%c", char_buf[j]); - if (j == 7) - LogMessage(" "); - } - - LogMessage("\n"); - } - - if (i == len) - break; - - hex_buf[i%16] = data[i]; - - if (isprint((int)data[i])) - char_buf[i%16] = data[i]; - else - char_buf[i%16] = '.'; - } - - if ((i-total_len) > 0) - { - LogMessage("%04x ", total_len); - - for (j = 0; j < i-total_len; j++) - { - LogMessage("%02x ", hex_buf[j]); - if (j == 7) - LogMessage(" "); - } - - if (j < 8) - LogMessage(" "); - LogMessage("%*s", (16-j)*3, ""); - LogMessage(" "); - - for (j = 0; j < i-total_len; j++) - { - LogMessage("%c", char_buf[j]); - if (j == 7) - LogMessage(" "); - } - } - - LogMessage("\n"); -} - |