#!/usr/bin/perl -w
###########################################################################
### ###
### NetworkLens SYSLOG Client ###
### ###
### NetworkLens ###
### Copyright (C) 2002, I-Link Incorporated ###
### ###
### This perl script will open a listening socket on the syslog port ###
### (port 514) and attempt to create new NetworkLens events from any ###
### message that arrive. ###
### ###
### To Do: (*) Check for new event vs. mod to existing event ###
### (rudimentary event correlation) ###
### ###
### (*) Provide some sort of filtering to remove events or ###
### messages that we don't care about ###
### ###
### (*) Make the signal handler abort immediately instead of ###
### just setting the "time_to_die" flag ###
### ###
### Change Log: ###
### ###
### 12/17/2001 Greg Bailey ###
### Initial Version ###
### ###
### 01/10/2002 Greg Bailey ###
### Change data for IP address to character string X.X.X.X ###
### ###
###########################################################################
###########################################################################
# Configuration settings #
###########################################################################
$debug = 0;
$dbi_datasource = "DBI:mysql:lens:localhost:3306";
$dbi_username = "root";
$dbi_password = "";
$MAXLINE = 1024;
###########################################################################
# Package definitions #
###########################################################################
use DBI;
use IO::Socket;
use POSIX;
###########################################################################
# Definitions from /usr/include/sys/syslog.h #
###########################################################################
$priority_map[0] = "LOG_EMERG";
$priority_map[1] = "LOG_ALERT";
$priority_map[2] = "LOG_CRIT";
$priority_map[3] = "LOG_ERR";
$priority_map[4] = "LOG_WARNING";
$priority_map[5] = "LOG_NOTICE";
$priority_map[6] = "LOG_INFO";
$priority_map[7] = "LOG_DEBUG";
$facility_map[0] = "LOG_KERN";
$facility_map[1] = "LOG_USER";
$facility_map[2] = "LOG_MAIL";
$facility_map[3] = "LOG_DAEMON";
$facility_map[4] = "LOG_AUTH";
$facility_map[5] = "LOG_SYSLOG";
$facility_map[6] = "LOG_LPR";
$facility_map[7] = "LOG_NEWS";
$facility_map[8] = "LOG_UUCP";
$facility_map[9] = "LOG_CRON";
$facility_map[10] = "LOG_AUTHPRIV";
$facility_map[11] = "LOG_FTP";
$facility_map[12] = "LOG_RESERVED";
$facility_map[13] = "LOG_RESERVED";
$facility_map[14] = "LOG_RESERVED";
$facility_map[15] = "LOG_RESERVED";
$facility_map[16] = "LOG_LOCAL0";
$facility_map[17] = "LOG_LOCAL1";
$facility_map[18] = "LOG_LOCAL2";
$facility_map[19] = "LOG_LOCAL3";
$facility_map[20] = "LOG_LOCAL4";
$facility_map[21] = "LOG_LOCAL5";
$facility_map[22] = "LOG_LOCAL6";
$facility_map[23] = "LOG_LOCAL7";
###########################################################################
# Make a background process #
###########################################################################
$pid = fork();
exit if $pid;
die "Couldn't fork: $1" unless defined( $pid );
POSIX::setsid()
or die "Can't start a new session: $!";
$time_to_die = 0;
sub signal_handler
{
$time_to_die = 1;
}
$SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signal_handler;
###########################################################################
# Connect to the NetworkLens database #
###########################################################################
$dbh = DBI->connect( $dbi_datasource, $dbi_username, $dbi_password,
{ RaiseError => 1 } )
or die "connecting: $DBI::errstr\n";
###########################################################################
# Open the syslog socket #
###########################################################################
$syslog_socket = IO::Socket::INET->new( LocalPort => 'syslog', Proto => 'udp' )
or die "socket: $@";
###########################################################################
# Main Loop #
###########################################################################
until ( $time_to_die )
{
$syslog_socket->recv( $syslog_message, $MAXLINE );
$client_ip = $syslog_socket->peeraddr();
$client_hostname = gethostbyaddr( $client_ip, AF_INET );
$client_ip_address = $syslog_socket->peerhost();
if ( $syslog_message =~ /^\<([0-9]*)\>(.*)$/ )
{
$code = $1;
$message = $2;
$priority = $code & 0x7;
$facility = $code >> 3;
}
$message =~ s/(['"])/\\$1/g;
##---------------------------------------------------------------------##
##- At this point, remove/filter events we don't care about... -##
##---------------------------------------------------------------------##
if ( $message =~ /^snmptrapd/ )
{
next;
}
##---------------------------------------------------------------------##
##- At this point, we want to create a new event -##
##---------------------------------------------------------------------##
$summary = sprintf( "%s from %s<br>%s",
$facility_map[$facility], $client_hostname, $message );
$sql = sprintf( "insert into lens_event "
. " ( status, severity, created, ip_addr, category, summary ) "
. "values "
. " ( 0, %d, now(), '%s', 'SYSLOG', '%s' )",
$priority, $client_ip_address, $summary );
if ( $debug )
{
printf( "id = UNKNOWN\n" );
printf( "status = NEW\n" );
printf( "code = %s\n", $code );
printf( "priority = %s\n", $priority_map[$priority] );
printf( "facility = %s\n", $facility_map[$facility] );
printf( "message = %s\n", $message );
printf( "SQL = %s\n", $sql );
printf( "\n" );
}
$dbh->do( $sql );
}
###########################################################################
# Disconnect from the NetworkLens database #
###########################################################################
$dbh->disconnect()
or die "disconnecting: $DBI::errstr\n";
###########################################################################
### END OF SOURCE FILE ###
########################################################################### |