📄 snort.c
字号:
/* $Id: snort.c,v 1.52 2001/01/26 16:40:44 roesch Exp $ */
/*
** Copyright (C) 1998,1999,2000,2001 Martin Roesch <roesch@clark.net>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** 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.
*/
/*
*
* Program: Snort
*
* Purpose: Check out the README file for info on what you can do
* with Snort.
*
* Author: Martin Roesch (roesch@clark.net)
*
* Comments: Ideas and code stolen liberally from Mike Borella's IP Grab
* program. Check out his stuff at http://www.borella.net. I
* also have ripped some util functions from TCPdump, plus Mike's
* prog is derived from it as well. All hail TCPdump....
*
* HP-UX 10.x note from Chris Sylvain:
* if you run snort and receive the error message
* "ERROR: OpenPcap() device lan0 open:
* recv_ack: promisc_phys: Invalid argument"
* it's because there's another program running using the DLPI service.
* The HP-UX implementation doesn't allow more than one libpcap program
* at a time to run, unlike Linux.
*
*/
/* I N C L U D E S **********************************************************/
#include "snort.h"
/* G L O B A L S ************************************************************/
extern OutputFuncNode *AlertList;
extern OutputFuncNode *LogList;
/*extern char *malloc_options;*/
/*
*
* Function: main(int, char *)
*
* Purpose: Handle program entry and exit, call main prog sections
*
* Arguments: See command line args in README file
*
* Returns: 0 => normal exit, 1 => exit on error
*
*/
int main(int argc, char *argv[])
{
#ifdef USE_PTHREADS
int i;
#endif
#ifndef WIN32
#if defined(LINUX) || defined(FREEBSD) || defined(OPENBSD) || defined(SOLARIS)
sigset_t set;
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
#else
sigsetmask(0);
#endif
#endif
/* malloc_options = "AX";*/
/* make this prog behave nicely when signals come along */
signal(SIGKILL, CleanExit);
signal(SIGTERM, CleanExit);
signal(SIGINT, CleanExit);
signal(SIGQUIT, CleanExit);
signal(SIGHUP, CleanExit);
signal(SIGUSR1, DropStats);
/* sane permissions */
umask(077);
/*
* set a global ptr to the program name so other functions can tell what
* the program name is
*/
progname = argv[0];
progargs = argv;
#ifdef WIN32
if (!init_winsock())
FatalError("[!] ERROR: Could not Initialize Winsock!\n");
#endif
/*
* setup some lookup data structs
*/
InitNetmasks();
InitProtoNames();
/* initialize the packet counter to loop forever */
pv.pkt_cnt = -1;
/* set the alert filename to NULL */
pv.alert_filename = NULL;
/* set the default alert mode */
pv.alert_mode = ALERT_FULL;
pv.use_utc = 0;
/*
* provide (limited) status messages by default
*/
pv.quiet_flag = 0;
ifr_count = 0;
#ifdef USE_PTHREADS
pt_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
/* chew up the command line */
ParseCmdLine(argc, argv);
if(pv.use_utc == 1)
{
thiszone = 0;
}
else
{
/* set the timezone (ripped from tcpdump) */
thiszone = gmt2local(0);
}
/*
* make sure we've got the privs to continue
*/
if(!pv.readmode_flag && geteuid() != SNIFFUSER)
{
DisplayBanner();
ShowUsage(progname);
printf("\n\nDude, you need root priveleges to run Snort in this mode!\n\n");
exit(1);
}
if(!pv.quiet_flag)
{
printf("\n --== Initializing Snort ==--\n");
}
/* if the logging flag hasn't been set yet... */
if(!pv.log_flag)
{
/* ...set the default logging dir */
strncpy(pv.log_dir, DEFAULT_LOG_DIR, strlen(DEFAULT_LOG_DIR) + 1);
}
if(pv.use_rules || pv.log_flag || pv.daemon_flag)
{
/* perform some sanity checks on the output directory, etc */
/* first perform some sanity checks on the output directory, etc ... */
SanityChecks();
/* ... then create a PID file if not reading from a file */
if (!pv.readmode_flag && pv.daemon_flag)
#ifdef WIN32
CreatePidFile("WIN32");
#else
CreatePidFile(pv.interfaces[0]);
#endif
}
if(pv.use_rules && pv.rules_order_flag)
{
if(!pv.quiet_flag)
{
printf("Rule application order changed to Pass->Alert->Log\n");
}
}
/*
* we're not using rules, sniffing to the screen, or logging packets so
* we don't really need to run...
*/
if(!pv.use_rules && !pv.verbose_flag && !pv.log_flag)
{
/*
* give them a nice little reminder that Snort needs to be told what
* to do
*/
DisplayBanner();
ShowUsage(progname);
PrintError("\n\nUh, you need to tell me to do something....\n\n");
exit(0);
}
/*
* if daemon mode requested, fork daemon first, otherwise on linux
* interface will be reset.
*/
if(pv.daemon_flag)
{
#ifdef DEBUG
printf("Entering daemon mode\n");
#endif
GoDaemon();
}
/*
* if no interfaces were specified we would need one anyway
*/
if(!ifr_count)
ifr_count++;
/*
* if we're not reading packets from a file, open the network interface
* for reading
*/
if(!pv.readmode_flag)
{
#ifdef DEBUG
#ifdef WIN32
printf("Opening interface: %s\n", print_interface(pv.interfaces[0]));
#else
printf("Opening interface: %s\n", pv.interfaces[0]);
#endif
#endif
/* open up our libpcap packet capture interface */
InitializeInterfaces();
}
else
{
#ifdef DEBUG
printf("Opening file: %s\n", pv.readfile);
#endif
/* open the packet file for readback */
OpenPcap(pv.readfile, 0);
}
/*
* creating a PID file before setting its proper
* path (in SanityChecks()) is not a good idea
*/
if((!(pv.use_rules || pv.log_flag) || pv.daemon_flag) && !pv.readmode_flag)
{
#ifdef WIN32
CreatePidFile("WIN32");
#else
CreatePidFile(pv.interfaces[0]);
#endif
}
#ifndef WIN32
/* Don't need root privelege anymore, so lets drop ownership
* and chroot if requested....
*/
if(chrootdir != NULL)
{
if(chdir(chrootdir) < 0)
FatalError("Can not chdir to \"%s\"\n", chrootdir);
if(chroot(chrootdir) < 0)
FatalError("Can not chroot to %s\n", chrootdir);
if(chdir("/") < 0)
FatalError("Can not chdir to \"/\"\n");
chrootdir = NULL; /* we don't need chrootdir anymore so all
* other routines should use fullpath. */
}
/* set safe userID/groupID if needed */
SetUidGid();
#endif
#ifdef DEBUG
printf("Setting Packet Processor\n");
#endif
/* set the packet processor (ethernet, slip, t/r, etc ) */
SetPktProcessors();
/* if we're using the rules system, it gets initialized here */
if(pv.use_rules)
{
/* initialize all the plugin modules */
InitPreprocessors();
InitPlugIns();
InitOutputPlugins();
#ifdef DEBUG
DumpPreprocessors();
DumpPlugIns();
DumpOutputPlugins();
#endif
/* setup the default rule action anchor points */
CreateDefaultRules();
if(pv.rules_order_flag)
{
OrderRuleLists("pass alert log");
}
ParseRulesFile(pv.config_file, 0);
if(!pv.quiet_flag)
{
printRuleOrder();
}
}
if(!pv.quiet_flag)
{
printf("\n --== Initialization Complete ==--\n");
}
/* Tell 'em who wrote it, and what "it" is */
if(!pv.quiet_flag)
DisplayBanner();
if(pv.alert_cmd_override)
{
/*
* if a command line alert override has been specified, setup the
* appropriate function pointer
*/
/*
* if we're using syslog alerting set the alert function pointer to
* the syslog alerting function
*/
if(pv.syslog_flag)
{
AddFuncToOutputList(SyslogAlert, NT_OUTPUT_ALERT, NULL);
openlog("snort", LOG_PID | LOG_NDELAY | LOG_NOWAIT, LOG_AUTH);
}
else if(pv.smbmsg_flag)
{
#ifdef ENABLE_SMB_ALERTS
AddFuncToOutputList(SmbAlert, NT_OUTPUT_ALERT, NULL);
#else
FatalError("[!] ERROR: SMB support not compiled into program, exiting...\n");
#endif
}
else
{
switch(pv.alert_mode)
{
case ALERT_FAST:
alert = OpenAlertFile(pv.alert_filename);
AddFuncToOutputList(FastAlert, NT_OUTPUT_ALERT, NULL);
break;
case ALERT_FULL:
alert = OpenAlertFile(pv.alert_filename);
AddFuncToOutputList(FullAlert, NT_OUTPUT_ALERT, NULL);
break;
case ALERT_NONE:
SetOutputList(NoAlert, NT_OUTPUT_ALERT, NULL);
break;
case ALERT_UNSOCK:
AddFuncToOutputList(SpoAlertUnixSock, NT_OUTPUT_ALERT, NULL);
OpenAlertSock();
break;
}
}
}
/* set the default alert function (alert full) */
if(AlertList == NULL && pv.use_rules == 1)
{
alert = OpenAlertFile(pv.alert_filename);
AddFuncToOutputList(FullAlert, NT_OUTPUT_ALERT, NULL);
}
/* set the alert function pointer list to call all the output plugins */
AlertFunc = CallAlertPlugins;
if(pv.log_cmd_override)
{
/* logging to a tcpdump file, initialize the output file and pointer */
if(pv.logbin_flag)
{
#ifdef DEBUG
printf("Initializing output file\n");
#endif
InitBinLogFile(pv.binLogFile);
AddFuncToOutputList(LogBin, NT_OUTPUT_LOG, NULL);
}
else
{ /* if we're not logging in tcpdump format...
* set the logging function pointer */
if(!pv.nolog_flag)
AddFuncToOutputList(LogPkt, NT_OUTPUT_LOG, NULL);
else
SetOutputList(NoLog, NT_OUTPUT_LOG, NULL);
}
}
if(LogList == NULL)
{
AddFuncToOutputList(LogPkt, NT_OUTPUT_LOG, NULL);
}
LogFunc = CallLogPlugins;
#ifdef DEBUG
printf("Entering pcap loop\n");
#endif
#ifdef USE_PTHREADS
/*
* With pthreads each interface gets a thread of its own.
*
*/
for(i = 0; i < ifr_count; i++)
{
pthread_create(&pt[i], NULL, InterfaceThread, NULL);
}
while(1)
{
sleep(10);
}
#else
/* Without pthreads one interface goes in main thread */
InterfaceThread(NULL);
#endif
return 0;
}
void ProcessPacket(char *user, struct pcap_pkthdr * pkthdr, u_char * pkt)
{
Packet p;
#ifdef USE_PTHREADS
pthread_mutex_lock(&pt_lock);
#endif
/* call the packet decoder */
(*grinder) (&p, pkthdr, pkt);
/* print the packet to the screen */
if(pv.verbose_flag)
{
if(p.iph != NULL)
{
PrintIPPkt(stdout, p.iph->ip_proto, &p);
}
else if(p.ah != NULL)
{
PrintArpHeader(stdout, &p);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -