📄 snort.c
字号:
}
grinder = DecodePppPkt;
break;
case DLT_NULL: /* loopback and stuff.. you wouldn't perform intrusion
* detection on it, but it's ok for testing.
*/
if (!pv.readmode_flag)
printf(" => Decoding LoopBack on interface %s\n", pv.interface);
else
printf("Entering readback mode....\n");
if (pv.show2hdr_flag == 1)
{
printf("Second layer header parsing for this datalink "
"isn't implemented yet\n");
pv.show2hdr_flag = 0;
}
grinder = DecodeNullPkt;
break;
#ifdef DLT_RAW /* Not supported in some arch or older pcap versions */
case DLT_RAW:
if (!pv.readmode_flag)
printf(" => Decoding raw data on interface %s\n", pv.interface);
else
printf("Entering readback mode....\n");
if (pv.show2hdr_flag == 1)
{
printf("There's no second layer header available for this datalink\n");
pv.show2hdr_flag = 0;
}
grinder = DecodeRawPkt;
break;
#endif
/* you need the I4L modified version of libpcap
to get this stuff working */
#ifdef DLT_I4L_RAWIP
case DLT_I4L_RAWIP:
printf(" => Decoding I4L-rawip on interface %s\n", pv.interface);
grinder = DecodeI4LRawIPPkt;
break;
#endif
#ifdef DLT_I4L_IP
case DLT_I4L_IP:
printf(" => Decoding I4L-ip on interface %s\n", pv.interface);
grinder = DecodeEthPkt;
break;
#endif
#ifdef DLT_I4L_CISCOHDLC
case DLT_I4L_CISCOHDLC:
printf(" => Decoding I4L-cisco-h on interface %s\n", pv.interface);
grinder = DecodeI4LCiscoIPPkt;
break;
#endif
default: /* oops, don't know how to handle this one */
PrintFmtError("\n%s cannot handle data link type %d",
progname, datalink);
CleanExit(SIGQUIT);
}
return 0;
}
/****************************************************************************
*
* Function: OpenPcap(char *)
*
* Purpose: Open the libpcap interface
*
* Arguments: intf => name of the interface to open
*
* Returns: 0 => success, exits on problems
*
****************************************************************************/
int OpenPcap(char *intf)
{
bpf_u_int32 localnet, netmask; /* net addr holders */
struct bpf_program fcode; /* Finite state machine holder */
char errorbuf[PCAP_ERRBUF_SIZE]; /* buffer to put error strings in */
bpf_u_int32 defaultnet = 0xFFFFFF00;
printf("\nInitializing Network Interface...\n");
if (pv.interface == NULL)
{
#ifdef DEBUG
printf("pv.interface is NULL, looking up interface.... ");
#endif
/* look up the device and get the handle */
pv.interface = pcap_lookupdev(errorbuf);
#ifdef DEBUG
printf("found interface %s\n", pv.interface);
#endif
/* uh oh, we couldn't find the interface name */
if (pv.interface == NULL)
{
FatalError("ERROR: OpenPcap() interface lookup: \n\t%s\n", errorbuf);
}
}
/* if we're not reading packets from a file */
if (!pv.readmode_flag)
{
if (pv.pkt_snaplen) /* if it's set let's try it... */
{
if (pv.pkt_snaplen < MIN_SNAPLEN) /* if it's < MIN set it to MIN */
{
snaplen = MIN_SNAPLEN;
}
else
{
snaplen = pv.pkt_snaplen;
}
}
else
{
snaplen = SNAPLEN; /* otherwise let's put the compiled value in */
}
#ifdef DEBUG
printf("snaplength info: set=%d/compiled=%d/wanted=%d\n", snaplen,
SNAPLEN, pv.pkt_snaplen);
#endif
/* get the device file descriptor */
pd = pcap_open_live(pv.interface, snaplen,
pv.promisc_flag ? PROMISC : 0, READ_TIMEOUT, errorbuf);
}
else /* reading packets from a file */
{
/* open the file */
pd = pcap_open_offline(intf, errorbuf);
/* the file didn't open correctly */
if (pd == NULL)
{
FatalError("ERROR => unable to open file %s for readback: %s\n",
intf, errorbuf);
}
/* set the snaplen for the file (so we don't get a lot of extra
crap in the end of packets */
snaplen = pcap_snapshot(pd);
printf("snaplen = %d\n", snaplen);
}
/* something is wrong with the opened packet socket */
if (pd == NULL)
{
FatalError("ERROR: OpenPcap() device %s open: \n\t%s\n",
pv.interface, errorbuf);
}
/* get local net and netmask */
if (pcap_lookupnet(pv.interface, &localnet, &netmask, errorbuf) < 0)
{
ErrorMessage("WARNING: OpenPcap() device %s network lookup: \n\t%s\n",
pv.interface, errorbuf);
/* set the default netmask to 255.255.255.0 (for stealthed interfaces) */
netmask = htonl(defaultnet);
}
/* compile BPF filter spec info fcode FSM */
if (pcap_compile(pd, &fcode, pv.pcap_cmd, 1, netmask) < 0)
{
ErrorMessage("ERROR: OpenPcap() FSM compilation failed: \n\t%s\n",
pcap_geterr(pd));
FatalError("PCAP command: %s\n", pv.pcap_cmd);
}
/* set the pcap filter */
if (pcap_setfilter(pd, &fcode) < 0)
{
FatalError("ERROR: OpenPcap() setfilter: \n\t%s\n", pcap_geterr(pd));
}
/* get data link type */
datalink = pcap_datalink(pd);
if (datalink < 0)
{
FatalError("ERROR: OpenPcap() datalink grab: \n\t%s\n", pcap_geterr(pd));
}
return 0;
}
/****************************************************************************
*
* Function: CleanExit()
*
* Purpose: Clean up misc file handles and such and exit
*
* Arguments: Signal
*
* Returns: void function
*
****************************************************************************/
extern PluginSignalFuncNode *PluginCleanExitList;
extern PluginSignalFuncNode *PluginRestartList;
void CleanExit(int sig)
{
struct pcap_stat ps;
float drop;
float recv;
PluginSignalFuncNode *idx;
/* make sure everything that needs to go to the screen gets there */
fflush(stdout);
if (sig != SIGHUP)
printf("\nExiting...\n");
else
printf("\nRestaring...\n");
if (pv.logbin_flag)
{
pcap_dump_close(dumpd);
}
unlink(pv.pid_filename);
pv.pid_filename[0] = 0;
if (pv.alert_mode == ALERT_FAST || pv.alert_mode == ALERT_FULL)
{
if (alert != NULL)
fclose(alert);
}
/* carry signals down to plugins */
if(sig != SIGHUP)
{
idx = PluginCleanExitList;
}
else
{
idx = PluginRestartList;
}
while(idx != NULL)
{
idx->func(sig, idx->arg);
idx = idx->next;
}
if (pv.readmode_flag)
{
puts("\n\n===============================================================================");
recv = pc.tcp+pc.udp+pc.icmp+pc.arp+pc.ipx+pc.ipv6+pc.other;
printf("Snort processed %d packets.\n", (int) recv);
puts("Breakdown by protocol:");
printf(" TCP: %-10ld (%.3f%%)\n", pc.tcp, CalcPct((float)pc.tcp, recv));
printf(" UDP: %-10ld (%.3f%%)\n", pc.udp, CalcPct((float)pc.udp, recv));
printf(" ICMP: %-10ld (%.3f%%)\n", pc.icmp, CalcPct((float)pc.icmp, recv));
printf(" FRAGS: %-10ld (%.3f%%)\n", pc.frags, CalcPct((float)pc.frags, recv));
printf(" ARP: %-10ld (%.3f%%)\n", pc.arp, CalcPct((float)pc.arp, recv));
printf(" IPv6: %-10ld (%.3f%%)\n", pc.ipv6, CalcPct((float)pc.ipv6, recv));
printf(" IPX: %-10ld (%.3f%%)\n", pc.ipx, CalcPct((float)pc.ipx, recv));
printf(" OTHER: %-10ld (%.3f%%)\n", pc.other, CalcPct((float)pc.other, recv));
puts("\n\n===============================================================================");
exit_or_exec(0, sig);
exit(0);
}
if (pd == NULL)
exit(1);
/* collect the packet stats */
if (pcap_stats(pd, &ps))
{
pcap_perror(pd, "pcap_stats");
}
else
{
recv = ps.ps_recv;
drop = ps.ps_drop;
puts("\n\n===============================================================================");
printf("Snort received %d packets", ps.ps_recv);
if (ps.ps_recv)
{
#ifndef LINUX
printf(" and dropped %d(%.3f%%) packets\n\n", ps.ps_drop,
CalcPct(drop, recv));
#else
printf(".\nPacket loss statistics are unavailable under Linux. Sorry!\n\n");
#endif
}
else
{
puts(".\n");
}
puts("Breakdown by protocol:");
printf(" TCP: %-10ld (%.3f%%)\n", pc.tcp, CalcPct((float)pc.tcp, recv));
printf(" UDP: %-10ld (%.3f%%)\n", pc.udp, CalcPct((float)pc.udp, recv));
printf(" ICMP: %-10ld (%.3f%%)\n", pc.icmp, CalcPct((float)pc.icmp, recv));
printf(" FRAGS: %-10ld (%.3f%%)\n", pc.frags, CalcPct((float)pc.frags, recv));
printf(" ARP: %-10ld (%.3f%%)\n", pc.arp, CalcPct((float)pc.arp, recv));
printf(" IPv6: %-10ld (%.3f%%)\n", pc.ipv6, CalcPct((float)pc.ipv6, recv));
printf(" IPX: %-10ld (%.3f%%)\n", pc.ipx, CalcPct((float)pc.ipx, recv));
printf(" OTHER: %-10ld (%.3f%%)\n", pc.other, CalcPct((float)pc.other, recv));
puts("===============================================================================");
}
pcap_close(pd);
exit_or_exec(0, sig);
exit(0);
}
/*
*
* exit_or_exec()
* Arguments: status, signal received.
*
* This function performs exec on SIGHUP signal and exit otherwise
*
*/
void exit_or_exec(int stat, int sig)
{
if ( sig != SIGHUP )
exit(stat);
else
{
syslog(LOG_DAEMON|LOG_NOTICE,"Received SIGHUP. Restarting");
#ifdef PARANOID
execv(progname,progargs);
#else
execvp(progname,progargs);
#endif
syslog(LOG_DAEMON|LOG_NOTICE,"Restarting %s failed",progname);
exit(1);
}
}
/****************************************************************************
*
* Function: CalcPct(float, float)
*
* 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
*
****************************************************************************/
float CalcPct(float cnt, float total)
{
float pct;
if (cnt > 0.0)
pct = cnt/total;
else
return 0.0;
pct *= 100.0;
return pct;
}
/****************************************************************************
*
* Function: DisplayBanner()
*
* Purpose: Show valuable proggie info
*
* Arguments: None.
*
* Returns: 0 all the time
*
****************************************************************************/
int DisplayBanner()
{
printf("\n-*> Snort! <*-\nVersion %s\nBy Martin Roesch (roesch@clark.net, www.snort.org)\n", VERSION);
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;
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;
}
lt = localtime((time_t *)&tvp->tv_sec);
s = (tvp->tv_sec + thiszone) % 86400;
(void)sprintf(timebuf, "%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;
/* If the year or julian day is different, we span 00:00 GMT
and must add or subtract a day. Check the year first to
avoid problems when the julian day wraps. */
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -