Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'RemoteSyslogFix' of https://github.com/binf/barnyard2 i…

…nto pre-stable
  • Loading branch information...
commit 840528b516a8d0f3e70bbeaadd294d7cbf32ea35 2 parents 156cfa9 + d0ae24e
@firnsy authored
View
33 etc/barnyard2.conf
@@ -243,23 +243,40 @@ output alert_fast: stdout
# ----------------------------------------------------------------------------
#
# Purpose:
-# This output module provides the abilty to output alert information to a
-# remote network host as well as the local host.
+# This output module provides the abilty to output alert information to local syslog
#
-# Arguments: host=hostname[:port], severity facility
-# arguments should be comma delimited.
-# host - specify a remote hostname or IP with optional port number
-# this is only specific to WIN32 (and is not yet fully supported)
# severity - as defined in RFC 3164 (eg. LOG_WARN, LOG_INFO)
# facility - as defined in RFC 3164 (eg. LOG_AUTH, LOG_LOCAL0)
#
# Examples:
# output alert_syslog
-# output alert_syslog: host=192.168.10.1
-# output alert_syslog: host=sysserver.com:1001
# output alert_syslog: LOG_AUTH LOG_INFO
#
+# syslog_full
+#-------------------------------
+# Available as both a log and alert output plugin. Used to output data via TCP/UDP or LOCAL ie(syslog())
+# Arguments:
+# sensor_name $sensor_name - unique sensor name
+# server $server - server the device will report to
+# local - if defined, ignore all remote information and use syslog() to send message.
+# protocol $protocol - protocol device will report over (tcp/udp)
+# port $port - destination port device will report to (default: 514)
+# delimiters $delimiters - define a character that will delimit message sections ex: "|", will use | as message section delimiters. (default: |)
+# separators $separators - define field separator included in each message ex: " " , will use space as field separator. (default: [:space:])
+# operation_mode $operaion_mode - default | complete : default mode is compatible with default snort syslog message, complete prints more information such as the raw packet (hexed)
+# log_priority $log_priority - used by local option for syslog priority call. (man syslog(3) for supported options) (default: LOG_INFO)
+# log_facility $log_facility - used by local option for syslog facility call. (man syslog(3) for supported options) (default: LOG_USER)
+
+# Usage Examples:
+# output alert_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode default
+# output alert_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode complete
+# output log_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode default
+# output log_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode complete
+# output alert_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514
+# output log_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514
+# output alert_syslog_full: sensor_name snortIds1-eth2, local
+# output log_syslog_full: sensor_name snortIds1-eth2, local, log_priority LOG_CRIT,log_facility LOG_CRON
# log_ascii
# ----------------------------------------------------------------------------
View
3  src/output-plugins/Makefile.am
@@ -21,6 +21,7 @@ spo_log_null.c spo_log_null.h \
spo_log_tcpdump.c spo_log_tcpdump.h \
spo_platypus.c spo_platypus.h \
spo_sguil.c spo_sguil.h \
-spo_database.c spo_database.h
+spo_database.c spo_database.h \
+spo_syslog_full.c spo_syslog.full.h
INCLUDES = -I.. -I ../sfutil
View
868 src/output-plugins/op_syslog_full.c
@@ -1,868 +0,0 @@
-/*
-** Copyright (C) 2011 Tim Shelton
-** Copyright (C) 2011 HAWK Network Defense, Inc. hawkdefense.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.
-*/
-
-/*
-** # syslog_full
-** #-------------------------------
-** # Available as both a log and alert output plugin. Used to output data via TCP/UDP
-** # HAWK Network Defense, Inc.
-** # Arguments:
-** # sensor_name $sensor_name - unique sensor name
-** # server $server - server the device will report to
-** # protocol $protocol - protocol device will report over (tcp/udp)
-** # port $port - destination port device will report to (default: 514)
-** # detail $detail_threshold - specify full/complete log reporting or only summaries.
-** # output alert_syslog_full: sensor_name snortIds1-eth2, server dev.hawkdefense.com, protocol udp, port 514, detail full
-** # output log_syslog_full: sensor_name snortIds1-eth2, server dev.hawkdefense.com, protocol udp, port 514, detail full
-**
-** #output alert_syslog_full: sensor_name snortIds1-eth2, server dev.hawkdefense.com, protocol udp,
-** port 514, detail full
-** output log_syslog_full: sensor_name snortIds1-eth2, server dev.hawkdefense.com, protocol udp, port 514, detail full
-**
-*/
-
-
-
-/* I N C L U D E S *****************************************************/
-
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <time.h>
-#include <errno.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-
-#include "ConfigFile.h"
-#include "mstring.h"
-#include "sid.h"
-#include "classification.h"
-#include "util.h"
-#include "input-plugins/dp_alert.h"
-#include "input-plugins/dp_log.h"
-#include "op_plugbase.h"
-#include "op_decode.h"
-#include "event.h"
-
-#include <ctype.h>
-
-typedef struct _OpSyslog_Data
-{
- char *server;
- char *sensor_name;
- struct sockaddr_in sockaddr;
- u_int32_t port;
- u_int16_t detail;
- u_int16_t proto;
- int socket;
- u_int32_t payload_length;
- char *payload;
-} OpSyslog_Data;
-
-#define MAX_QUERY_SIZE 4096
-
-char *db_proto[] = {"udp", "tcp", NULL};
-
-/* Output plugin API functions */
-int OpSyslog_Setup(OutputPlugin *, char *args);
-int OpSyslog(OutputPlugin *);
-int OpSyslog_Start(OutputPlugin *, void *);
-int OpSyslog_Stop(OutputPlugin *);
-int OpSyslog_Log(void *, void *);
-int OpSyslog_Alert(void *, void *);
-int OpSyslog_Exit(OutputPlugin *outputPlugin);
-int OpSyslog_LogConfig(OutputPlugin *outputPlugin);
-
-/* Internal functions */
-OpSyslog_Data *OpSyslog_ParseArgs(char *);
-int NetClose(OpSyslog_Data *data);
-int NetSend(OpSyslog_Data *data);
-int NetConnect(OpSyslog_Data *data);
-
-static int Syslog_FormatReference(OpSyslog_Data *data, ReferenceData *refer);
-/* init routine makes this processor available for dataprocessor directives */
-void OpSyslog_Init()
-{
- OutputPlugin *outputPlugin;
-
- outputPlugin = RegisterOutputPlugin("alert_syslog_full", "alert");
- outputPlugin->setupFunc = OpSyslog_Setup;
- outputPlugin->exitFunc = OpSyslog_Exit;
- outputPlugin->startFunc = OpSyslog_Start;
- outputPlugin->stopFunc = OpSyslog_Stop;
- outputPlugin->outputFunc = OpSyslog_Alert;
- outputPlugin->logConfigFunc = OpSyslog_LogConfig;
-
- outputPlugin = RegisterOutputPlugin("log_syslog_full", "log");
- outputPlugin->setupFunc = OpSyslog_Setup;
- outputPlugin->exitFunc = OpSyslog_Exit;
- outputPlugin->startFunc = OpSyslog_Start;
- outputPlugin->stopFunc = OpSyslog_Stop;
- outputPlugin->outputFunc = OpSyslog_Log;
- outputPlugin->logConfigFunc = OpSyslog_LogConfig;
-
-}
-
-
-/* Setup the output plugin, process any arguments, link the functions to
- * the output functional node
- */
-int OpSyslog_Setup(OutputPlugin *outputPlugin, char *args)
-{
- /* setup the run time context for this output plugin */
- outputPlugin->data = OpSyslog_ParseArgs(args);
-
- return 0;
-}
-
-/* Inverse of the setup function, free memory allocated in Setup
- * can't free the outputPlugin since it is also the list node itself
- */
-int OpSyslog_Exit(OutputPlugin *outputPlugin)
-{
- return 0;
-}
-
-int OpSyslog_LogConfig(OutputPlugin *outputPlugin)
-{
- OpSyslog_Data *data = NULL;
-
- if(!outputPlugin || !outputPlugin->data)
- return -1;
-
- data = (OpSyslog_Data *)outputPlugin->data;
-
- LogMessage("OpSyslogFull configured\n");
- LogMessage(" Detail Level: %s\n", data->detail == 1 ? "Full" : "Fast");
- LogMessage(" Syslog Server: %s:%u\n", data->server, data->port);
- LogMessage(" Reporting Protocol: %s\n", db_proto[data->proto]);
- return 0;
-}
-
-/*
- * this function gets called at start time, you should open any output files
- * or establish DB connections, etc, here
- */
-int OpSyslog_Start(OutputPlugin *outputPlugin, void *spool_header)
-{
- OpSyslog_Data *data = (OpSyslog_Data *)outputPlugin->data;
-
- if(data == NULL)
- FatalError("ERROR: Unable to find context for SyslogFull startup!\n");
-
- if(pv.verbose)
- {
- OpSyslog_LogConfig(outputPlugin);
- }
-
-
- if(NetConnect(data)) {
- LogMessage("OpSyslogFull: Failed to connect to host: [%s] %s:%u\n",
- db_proto[data->proto], data->server, data->port);
- return 1;
- }
-
- return 0;
-}
-
-int OpSyslog_Stop(OutputPlugin *outputPlugin)
-{
- OpSyslog_Data *data = (OpSyslog_Data *)outputPlugin->data;
-
- if(data == NULL)
- FatalError("ERROR: Unable to find context for SyslogFull startup!\n");
-
- NetClose(data);
- free(data->server);
- free(data->sensor_name);
-
- return 0;
-}
-
-
-static int Syslog_FormatTriggerAlert(OpSyslog_Data *data, UnifiedAlertRecord *record) {
-
- char timestamp[TIMEBUF_SIZE];
- Sid *sid = NULL;
- ClassType *class_type = NULL;
-
- char pBuf[2050];
- char *sensor_name = "SNORTIDS";
- if(data->sensor_name) sensor_name = data->sensor_name;
- snprintf(pBuf,2048,"SNORTIDS[ALERT]: %s|", sensor_name);
- strncat(data->payload, pBuf,data->payload_length);
-
- ////////////////////////////////////////////////////////
- RenderTimestamp(record->ts.tv_sec, timestamp, TIMEBUF_SIZE);
- sid = GetSid(record->event.sig_generator, record->event.sig_id);
- if(sid == NULL)
- sid = FakeSid(record->event.sig_generator, record->event.sig_id);
-
- sid->rev = record->event.sig_rev;
-
- if(!(class_type = GetClassType(record->event.classification))
- && record->event.classification != 0)
- {
- LogMessage("WARNING: No ClassType found for classification '%i'\n",
- record->event.classification);
- return 1;
- }
-
-
- snprintf(pBuf,2048,"%s %u %s", timestamp, record->event.priority, sid != NULL ? sid->msg : "ALERT");
- strncat(data->payload, pBuf, data->payload_length);
- snprintf(pBuf,2048,"|%s|", class_type != NULL ? class_type->name : "Suspicious Activity");
- strncat(data->payload, pBuf, data->payload_length);
- Syslog_FormatReference(data, sid->ref);
-
- return 0;
-}
-
-
-static int Syslog_FormatTriggerLog(OpSyslog_Data *data, UnifiedLogRecord *record) {
-
- char timestamp[TIMEBUF_SIZE];
- Sid *sid = NULL;
- ClassType *class_type = NULL;
-
- char pBuf[2048];
- char *sensor_name = "SNORTIDS";
- if(data->sensor_name) sensor_name = data->sensor_name;
- snprintf(pBuf,2048,"SNORTIDS[LOG]: %s|", sensor_name);
- strncat(data->payload, pBuf,data->payload_length);
-
- RenderTimestamp(record->log.pkth.ts.tv_sec, timestamp, TIMEBUF_SIZE);
- sid = GetSid(record->log.event.sig_generator, record->log.event.sig_id);
- if(sid == NULL)
- sid = FakeSid(record->log.event.sig_generator, record->log.event.sig_id);
-
- sid->rev = record->log.event.sig_rev;
-
- if(!(class_type = GetClassType(record->log.event.classification))
- && record->log.event.classification != 0)
- {
- LogMessage("WARNING: No ClassType found for classification '%i'\n",
- record->log.event.classification);
- return 1;
- }
-
-
- snprintf(pBuf,2048,"%s %u %s|%s|", timestamp, record->log.event.priority, sid != NULL ? sid->msg : "ALERT", class_type != NULL ? class_type->name : "Suspicious Activity");
-
- strncat(data->payload, pBuf, data->payload_length);
-
- Syslog_FormatReference(data, sid->ref);
-
- return 0;
-}
-
-static int Syslog_FormatReference(OpSyslog_Data *data, ReferenceData *refer) {
-
- ReferenceData *ref;
-
- ref = refer;
-
- /*
- while(ref) {
-
- fprintf(stderr,"System: %s ID:%s URL:%s\n", ref->system, ref->id, ref->url);
- ref = ref->next;
- }
- */
- //data->payload_length = strlen(data->payload) +strlen(hex_payload);
- //data->payload = realloc(data->payload,data->payload_length+10);
- //strncat(data->payload,hex_payload,data->payload_length);
- //
-
- return 0;
-
-}
-
-// this should be different for Alert messages
-// than it is for Info/Log messages
-static int Syslog_FormatIPHeaderAlert(OpSyslog_Data *data, UnifiedAlertRecord *record) {
- char pBuf[513];
-
- snprintf(pBuf,512,"%u,%u,%u|", record->sip, record->dip, record->protocol);
- strncat(data->payload, pBuf,data->payload_length);
-
- return 0;
-}
-
-static int Syslog_FormatIPHeaderLog(OpSyslog_Data *data, Packet *p) {
-
- char pBuf[1025];
- unsigned int s, d, proto, ver, hlen, tos, len, id, off, ttl, csum;
-
- s=d=proto=ver=hlen=tos=len=id=off=ttl=csum=0;
-
- if(p->iph) {
- if(p->iph->ip_src.s_addr)
- s = ntohl( p->iph->ip_src.s_addr);
- if(p->iph->ip_dst.s_addr)
- d = ntohl( p->iph->ip_dst.s_addr);
- if(p->iph->ip_proto)
- proto = p->iph->ip_proto;
- if(IP_VER(p->iph))
- ver = IP_VER(p->iph);
- if(IP_HLEN(p->iph))
- ver = IP_HLEN(p->iph);
- if(p->iph->ip_tos)
- tos = p->iph->ip_tos;
- if(p->iph->ip_len)
- len = ntohs(p->iph->ip_len);
- if(p->iph->ip_id)
- id = ntohs(p->iph->ip_id);
- if(p->iph->ip_off)
- off = (p->iph->ip_off);
- if(p->iph->ip_ttl)
- ttl = (p->iph->ip_ttl);
- if(p->iph->ip_csum)
- ttl = htons(p->iph->ip_csum);
- }
-
- snprintf(pBuf,1024,"%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, "
- "%u, %u|",
- s, d, proto, ver, hlen, tos, len, id,
-#if defined(WORDS_BIGENDIAN)
- ((off & 0xE000) >> 13),
- htons(off & 0x1FFF),
-#else
- ((off & 0x00E0) >> 5),
- htons(off & 0xFF1F),
-#endif
- ttl,
- csum);
-
- strncat(data->payload, pBuf, data->payload_length);
-
- return 0;
-}
-
-// need one for each ? alert : log
-static int Syslog_FormatTCPHeaderAlert(OpSyslog_Data *data, UnifiedAlertRecord *record) {
- char pBuf[256];
- snprintf(pBuf,255,"%u,%u|", record->sp, record->dp);
- strncat(data->payload, pBuf,data->payload_length);
-
- return 0;
-}
-
-static int Syslog_FormatTCPHeaderLog(OpSyslog_Data *data, Packet *p) {
- char pBuf[1025];
-
- unsigned int th_win, th_sum, th_flags, th_ack, th_seq, th_urp, th_off, th_x2;
-
- th_win=th_sum=th_flags=th_ack=th_seq=th_urp=th_off=th_x2=0;
-
- if(p->tcph) {
- if(p->tcph->th_seq)
- th_seq = ntohl(p->tcph->th_seq);
- if(p->tcph->th_ack)
- th_ack = ntohl(p->tcph->th_ack);
- if(TCP_OFFSET(p->tcph))
- th_off = TCP_OFFSET(p->tcph);
- if(TCP_X2(p->tcph))
- th_x2 = TCP_X2(p->tcph);
- if(p->tcph->th_flags)
- th_flags = p->tcph->th_flags;
- if(p->tcph->th_win)
- th_win = ntohs(p->tcph->th_win);
- if(p->tcph->th_sum)
- th_sum = ntohs(p->tcph->th_sum);
- if(p->tcph->th_urp)
- th_urp = ntohs(p->tcph->th_urp);
- }
-
- snprintf(pBuf,1024,"%u, %u, %u, %u, %u, %u, %u, %u, %u, %u|", p->sp,
- p->dp, th_seq, th_ack, th_off, th_x2, th_flags, th_win, th_sum, th_urp);
-
- strncat(data->payload, pBuf,data->payload_length);
-
- return 0;
-}
-
-static int Syslog_FormatUDPHeaderAlert(OpSyslog_Data *data, UnifiedAlertRecord *record) {
- char pBuf[256];
- snprintf(pBuf,255,"%u,%u|", record->sp, record->dp);
- strncat(data->payload, pBuf,data->payload_length);
-
- return 0;
-}
-
-static int Syslog_FormatUDPHeaderLog(OpSyslog_Data *data, Packet *p) {
- char pBuf[1025];
- unsigned int uh_len=0, uh_chk=0;
- if(p->udph) {
- if(p->udph->uh_len)
- uh_len = ntohs(p->udph->uh_len);
- if(p->udph->uh_chk)
- uh_chk = ntohs(p->udph->uh_chk);
- }
- snprintf(pBuf,1024,
- "%u, %u, %u, %u|",
- p->sp, p->dp, uh_len, uh_chk);
-
- strncat(data->payload, pBuf,data->payload_length);
-
- return 0;
-}
-
-static int Syslog_FormatICMPHeaderAlert(OpSyslog_Data *data, UnifiedAlertRecord *record) {
- char pBuf[1025];
- snprintf(pBuf,1024,"%u,%u|", record->sp, record->dp);
- strncat(data->payload, pBuf,data->payload_length);
-
- return 0;
-}
-
-static int Syslog_FormatICMPHeaderLog(OpSyslog_Data *data, Packet *p) {
- char pBuf[1025];
-
- unsigned int type, code, csum, id, seq;
- type=code=csum=id=seq=0;
-
- if(p->icmph) {
- if(p->icmph->icmp_type)
- type = p->icmph->icmp_type;
- if(type == 0 || type == 8 ||
- type == 13 || type == 14 ||
- type == 15 || type == 16)
- {
- if(p->icmph->icmp_code)
- code = p->icmph->icmp_code;
- if(p->icmph->icmp_csum)
- csum = ntohs(p->icmph->icmp_csum);
-
- id = htons(p->icmph->icmp_hun.ih_idseq.icd_id);
- seq = htons(p->icmph->icmp_hun.ih_idseq.icd_seq);
-
- snprintf(pBuf, 1024,"%u, %u, %u, %u, %u|", type,
- code, csum,
- id, seq);
- } else {
- if(p->icmph->icmp_code)
- code = p->icmph->icmp_code;
- if(p->icmph->icmp_csum)
- csum = ntohs(p->icmph->icmp_csum);
-
- snprintf(pBuf, 1024,"%u, %u, %u|", type, code, csum);
- }
-
- strncat(data->payload, pBuf,data->payload_length);
-
- }
-
- return 0;
-}
-
-static int Syslog_FormatPayload(OpSyslog_Data *data, Packet *p) {
- char *hex_payload;
- if(p->dsize > 0) {
- hex_payload = fasthex(p->data, p->dsize);
- // lets re-negotiate the size of our payload
- data->payload_length = strlen(data->payload) +strlen(hex_payload);
- data->payload = realloc(data->payload,data->payload_length+10);
- strncat(data->payload,hex_payload,data->payload_length);
- }
-
-
- return 0;
-}
-
-// We only report the data associated with an "Alert"
-//
-// we plan to do the following:
-// connect to our remote host, exit on failure
-// create our Syslog Alert message (format):
-// SNORTIDS:#sensor_name# #timestamp# #signature# #Class_Type# #!!ip header!!# #!!/tcp/udp/icmp header!!# #payload#
-// send our string over our socket using NetSocket
-// close our socket and continue
-
-
-int OpSyslog_Alert(void *context, void *data)
-{
- UnifiedAlertRecord *record = (UnifiedAlertRecord *)data;
- OpSyslog_Data *op_data = (OpSyslog_Data *)context;
-
- if(op_data->socket == -1) {
- if(NetConnect(op_data)) {
- LogMessage("WARNING: Unable to connect to our syslog host: '%s:%u'\n", op_data->server, op_data->port);
- return 1;
- }
- }
-
- // lets put together our payload query
- //
- op_data->payload = malloc(MAX_QUERY_SIZE+10);
- if(!op_data->payload)
- return 1;
-
- op_data->payload_length = MAX_QUERY_SIZE;
-
- // lets start to build our string
- if(Syslog_FormatTriggerAlert(op_data, record) ) {
- LogMessage("WARNING: Unable to append Trigger header.\n");
- free(op_data->payload);
- return 1;
- }
-
- //
- if(Syslog_FormatIPHeaderAlert(op_data, record) ) {
- LogMessage("WARNING: Unable to append Trigger header.\n");
- free(op_data->payload);
- return 1;
- }
-
-
- /* build the protocol specific header information */
- switch(record->protocol)
- {
- case IPPROTO_TCP:
- Syslog_FormatTCPHeaderAlert(data, record);
- break;
- case IPPROTO_UDP:
- Syslog_FormatUDPHeaderAlert(data, record);
- break;
- case IPPROTO_ICMP:
- Syslog_FormatICMPHeaderAlert(data, record);
- break;
- }
-
-
- // by here our msg is completed so lets debug/test its formatting
- // and lets send it to via our socket
- //
-
- strncat(op_data->payload, "\n",op_data->payload_length);
-
- if(NetSend(op_data)) {
- LogMessage("WARNING: Unable to connect to our syslog host: '%s:%u'\n", op_data->server, op_data->port);
- free(op_data->payload);
- NetClose(op_data);
- return 1;
- }
-
- free(op_data->payload);
-
- NetClose(data);
-
- return 0;
-}
-
-int OpSyslog_Log(void *context, void *data)
-{
- UnifiedLogRecord *record = (UnifiedLogRecord *)data;
- OpSyslog_Data *op_data = (OpSyslog_Data *)context;
- Packet p;
-
-
- if(op_data->socket == -1) {
- if(NetConnect(op_data)) {
- LogMessage("WARNING: Unable to connect to our syslog host: '%s:%u'\n", op_data->server, op_data->port);
- return 1;
- }
- }
-
- // lets put together our payload query
- //
- op_data->payload = malloc(MAX_QUERY_SIZE+10);
- if(!op_data->payload)
- return 1;
-
- memset(op_data->payload,0x00, MAX_QUERY_SIZE+10); // null out our buffer
-
- op_data->payload_length = MAX_QUERY_SIZE;
-
- // lets start to build our string
- if(Syslog_FormatTriggerLog(op_data, record) ) {
- LogMessage("WARNING: Unable to append Trigger header.\n");
- free(op_data->payload);
- return 1;
- }
-
- /* decode the packet */
- if(DecodePacket(&p, &record->log.pkth, record->pkt + 2) == 0)
- {
- if(p.iph)
- {
-
- Syslog_FormatIPHeaderLog(op_data, &p);
- // append ip data to our payload string
-
- //if(!(p.pkt_flags & PKT_FRAG_FLAG))
- {
-
- switch(p.iph->ip_proto)
- {
- case IPPROTO_ICMP:
- Syslog_FormatICMPHeaderLog(op_data, &p);
- break;
- case IPPROTO_TCP:
- Syslog_FormatTCPHeaderLog(op_data, &p);
- break;
- case IPPROTO_UDP:
- Syslog_FormatUDPHeaderLog(op_data, &p);
- break;
- }
-
- }
-
- Syslog_FormatPayload(op_data, &p);
- }
- }
-
- strncat(op_data->payload,"\n",op_data->payload_length);
-
- if(NetSend(op_data)) {
- LogMessage("WARNING: Unable to connect to our syslog host: '%s:%u'\n", op_data->server, op_data->port);
- NetClose(op_data);
- free(op_data->payload);
- return 1;
- }
-
- free(op_data->payload);
-
- NetClose(op_data);
-
- return 0;
-}
-
-
-OpSyslog_Data *OpSyslog_ParseArgs(char *args)
-{
- OpSyslog_Data *op_data;
-
- op_data = (OpSyslog_Data *)SafeAlloc(sizeof(OpSyslog_Data));
-
- // default syslog port
- op_data->port = 514;
-
- if(args != NULL)
- {
- char **toks;
- int num_toks;
- int i;
- /* parse out your args */
- toks = mSplit(args, ",", 31, &num_toks, '\\');
- for(i = 0; i < num_toks; ++i)
- {
- char **stoks;
- int num_stoks;
- char *index = toks[i];
- while(isspace((int)*index))
- ++index;
- stoks = mSplit(index, " ", 2, &num_stoks, 0);
- if(strcasecmp("port", stoks[0]) == 0)
- {
- if(num_stoks > 1 )
- op_data->port = strtoul(stoks[1], NULL, 0);
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
- else if(strcasecmp("server", stoks[0]) == 0)
- {
- if(num_stoks > 1 && !op_data->server )
- op_data->server = strdup(stoks[1]);
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
- else if(strcasecmp("sensor_name", stoks[0]) == 0)
- {
- if(num_stoks > 1 && !op_data->sensor_name )
- op_data->sensor_name = strdup(stoks[1]);
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
-
- else if(strcasecmp("protocol", stoks[0]) == 0)
- {
- if(num_stoks > 1)
- {
- if(strcasecmp("udp", stoks[1]) == 0)
- op_data->proto = 0;
- else
- op_data->proto = 1;
- }
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
- else if(strcasecmp("detail", stoks[0]) == 0)
- {
- if(num_stoks > 1)
- {
- if(strcasecmp("full", stoks[1]) == 0)
- op_data->detail = 1;
- }
- else
- LogMessage("Argument Error in %s(%i): %s\n", file_name,
- file_line, index);
- }
- else
- {
- fprintf(stderr, "WARNING %s (%d) => Unrecognized argument for "
- "SyslogFull plugin: %s\n", file_name, file_line, index);
- }
- FreeToks(stoks, num_stoks);
- }
- /* free your mSplit tokens */
- FreeToks(toks, num_toks);
- }
-
- /*
- if(!op_data->sensor_name)
- FatalError("You must specify a sensor name\n");
- */
-
- return op_data;
-}
-
-
-int UDPConnect(OpSyslog_Data *op_data) {
- // IPPROTO_UDP , SOCK_DGRAM
- struct hostent *hostPtr;
- op_data->socket = socket(AF_INET, SOCK_DGRAM, 0);
- if(op_data->socket == -1) {
- LogMessage("Failed to create our socket");
- return 1;
- }
-
-
- if(!op_data->server)
- op_data->server = strdup("127.0.0.1");
-
- if (inet_aton(op_data->server,&op_data->sockaddr.sin_addr) != 1) {
- if ((hostPtr = gethostbyname(op_data->server)) == NULL) {
- LogMessage("could not resolve address[%s]",op_data->server);
- return 1;
- }
-
- memcpy(&op_data->sockaddr.sin_addr,hostPtr->h_addr,sizeof(op_data->sockaddr.sin_addr));
- }
-
- op_data->sockaddr.sin_port = htons(op_data->port);
- op_data->sockaddr.sin_family = AF_INET;
-
- if(connect(op_data->socket, (struct sockaddr*)&op_data->sockaddr, sizeof(struct sockaddr)) == -1) {
- // failed to connect to host
- close(op_data->socket);
- return 1;
- }
-
-
- return 0;
-
-}
-
-int TCPConnect(OpSyslog_Data *op_data) {
- // IPPROTO_TCP , SOCK_STREAM
- //
- struct hostent *hostPtr;
- int option=1;
- op_data->socket = socket(AF_INET, SOCK_STREAM, 0);
- if(op_data->socket == -1) {
- LogMessage("Failed to create our socket");
- return 1;
- }
-
- if(!op_data->server)
- op_data->server = strdup("127.0.0.1");
-
- if (inet_aton(op_data->server,&op_data->sockaddr.sin_addr) != 1) {
- if ((hostPtr = gethostbyname(op_data->server)) == NULL) {
- LogMessage("could not resolve address[%s]",op_data->server);
- return 1;
- }
-
- memcpy(&op_data->sockaddr.sin_addr,hostPtr->h_addr,sizeof(op_data->sockaddr.sin_addr));
- }
-
- op_data->sockaddr.sin_port = htons(op_data->port);
- op_data->sockaddr.sin_family = AF_INET;
-
- if(op_data->proto == 1) { // tcp!!
- setsockopt(op_data->socket,IPPROTO_TCP,TCP_NODELAY, (char *)&option, sizeof(option)); // error checking
- }
-
- if(connect(op_data->socket, (struct sockaddr*)&op_data->sockaddr, sizeof(struct sockaddr)) != 0) {
- // failed to connect to host
- close(op_data->socket);
- return 1;
- }
-
-
- return 0;
-
-}
-
-int NetConnect(OpSyslog_Data *op_data)
-{
- switch(op_data->proto)
- {
- case 0:
- return UDPConnect(op_data);
- case 1:
- return TCPConnect(op_data);
- default:
- FatalError("Protocol not supported\n");
- return 1;
- }
-// return 1;
-}
-
-int NetClose(OpSyslog_Data *op_data)
-{
-
- int rval = close(op_data->socket);
- op_data->socket = -1;
- return rval;
-}
-
-
-int NetSend(OpSyslog_Data *data) {
-// if failure lets try and auto-renegotiate teh connection
- switch(data->proto) {
- case 0: // UDP!!
- if(sendto(data->socket,data->payload, strlen(data->payload), 0 , (struct sockaddr *)&data->sockaddr, sizeof(struct sockaddr)) <= 0) {
- //perror("sendto");
- return 1;
- }
- break;
-
- case 1: // TCP!!
- if( send(data->socket, data->payload, strlen(data->payload), 0) <= 0) {
- //perror("send");
- return 1;
- }
- break;
- }
- return 0;
-}
-
View
27 src/output-plugins/op_syslog_full.h
@@ -1,27 +0,0 @@
-/*
-** Copyright (C) 2011 Tim Shelton
-** Copyright (C) 2011 HAWK Network Defense, Inc. hawkdefense.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.
-*/
-
-#ifndef __OP_SYSLOG_FULL_H_
-#define __OP_SYSLOG_FULL_H_
-
-void OpSyslog_Init();
-
-#endif /* __OP_SYSLOG_FULL_H_ */
-
View
1,905 src/output-plugins/spo_syslog_full.c
@@ -0,0 +1,1905 @@
+/*
+**
+** Copyright (C) 2011-2012 Modified and enchanced for barnyard2 by the Barnyard2 Team.
+** Copyright (C) 2011 Tim Shelton
+** Copyright (C) 2011 HAWK Network Defense, Inc. hawkdefense.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.
+*/
+
+/*
+# syslog_full
+#-------------------------------
+# Available as both a log and alert output plugin. Used to output data via TCP/UDP or LOCAL ie(syslog())
+# Arguments:
+# sensor_name $sensor_name - unique sensor name
+# server $server - server the device will report to
+# local - if defined, ignore all remote information and use syslog() to send message.
+# protocol $protocol - protocol device will report over (tcp/udp)
+# port $port - destination port device will report to (default: 514)
+# delimiters $delimiters - define a character that will delimit message sections ex: "|", will use | as message section delimiters. (default: |)
+# separators $separators - define field separator included in each message ex: " " , will use space as field separator. (default: [:space:])
+# operation_mode $operaion_mode - default | complete : default mode is compatible with default snort syslog message, complete prints more information such as the raw packet (hexed)
+# log_priority $log_priority - used by local option for syslog priority call. (man syslog(3) for supported options) (default: LOG_INFO)
+# log_facility $log_facility - used by local option for syslog facility call. (man syslog(3) for supported options) (default: LOG_USER)
+
+# Usage Examples:
+# output alert_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode default
+# output alert_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode complete
+# output log_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode default
+# output log_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514, operation_mode complete
+# output alert_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514
+# output log_syslog_full: sensor_name snortIds1-eth2, server xxx.xxx.xxx.xxx, protocol udp, port 514
+# output alert_syslog_full: sensor_name snortIds1-eth2, local
+# output log_syslog_full: sensor_name snortIds1-eth2, local, log_priority LOG_CRIT,log_facility LOG_CRON
+
+*/
+
+#include "output-plugins/spo_syslog_full.h"
+
+/* Output plugin API functions */
+static void OpSyslog_Exit(int signal,void *outputPlugin);
+static void OpSyslog_Alert(Packet *, void *, uint32_t, void *);
+static void OpSyslog_Log(Packet *, void *, uint32_t, void *);
+static int OpSyslog_LogConfig(void *outputPlugin);
+static void OpSyslog_InitLog(char *args);
+static void OpSyslog_InitAlert(char *args);
+static OpSyslog_Data *OpSyslog_ParseArgs(char *);
+
+static int NetClose(OpSyslog_Data *data);
+static int NetSend(OpSyslog_Data *data);
+static int NetConnect(OpSyslog_Data *data);
+static int NetTestSocket(OpSyslog_Data *op_data);
+
+//CHECKME: -elz Need to investigate
+//static int Syslog_FormatReference(OpSyslog_Data *data, ReferenceNode *refer);
+
+extern Barnyard2Config *barnyard2_conf;
+
+int SyslogLogContext;
+char *db_proto[] = {"udp", "tcp", NULL};
+
+
+/* Setup routine makes this processor available for dataprocessor directives */
+void OpSyslog_Setup(void)
+{
+ RegisterOutputPlugin("alert_syslog_full", OUTPUT_TYPE_FLAG__ALERT, OpSyslog_InitAlert);
+ RegisterOutputPlugin("log_syslog_full", OUTPUT_TYPE_FLAG__LOG, OpSyslog_InitLog);
+ return;
+}
+
+/* Log Init Context wrapping function */
+void OpSyslog_InitLog(char *args)
+{
+ SyslogLogContext = OUTPUT_TYPE_FLAG__LOG;
+ OpSyslog_Init(args);
+ return;
+}
+
+/* Alert Init Context wrapping function */
+void OpSyslog_InitAlert(char *args)
+{
+ SyslogLogContext = OUTPUT_TYPE_FLAG__ALERT;
+ OpSyslog_Init(args);
+ return;
+}
+
+/*
+ * init the output plugin, process any arguments, link the functions to
+ * the output functional node
+ */
+void OpSyslog_Init(char *args)
+{
+ OpSyslog_Data *syslogContext;
+
+ if( args == NULL)
+ {
+ /* For later use...
+ ErrorMessage("OpSyslog_Init(): Invoked with NULL arguments....\n");
+ return 1;
+ */
+
+ FatalError("OpSyslog_Init(): Invoked with NULL arguments....\n");
+ }
+
+ if( (syslogContext = OpSyslog_ParseArgs(args)) == NULL)
+ {
+ FatalError("OpSyslog_Init(): Error parsing output plugin arguments, bailing.\n");
+ }
+
+ AddFuncToCleanExitList(OpSyslog_Exit,(void *)syslogContext);
+ AddFuncToShutdownList(OpSyslog_Exit,(void *)syslogContext);
+
+ switch(SyslogLogContext)
+ {
+
+ case OUTPUT_TYPE_FLAG__LOG:
+ switch(syslogContext->operation_mode)
+ {
+ case 1:
+ AddFuncToOutputList(OpSyslog_Log, OUTPUT_TYPE__LOG, (void *)syslogContext);
+ break;
+
+ case 0:
+ default:
+ LogMessage("[%s()]: OUTPUT_TYPE__LOG was selected but operation_mode is set to \"default\", using defaut logging hook \n",
+ __FUNCTION__);
+ AddFuncToOutputList(OpSyslog_Alert, OUTPUT_TYPE__ALERT, (void *)syslogContext);
+ break;
+ }
+
+ case OUTPUT_TYPE_FLAG__ALERT:
+ AddFuncToOutputList(OpSyslog_Alert, OUTPUT_TYPE__ALERT, (void *)syslogContext);
+ break;
+
+ default:
+ FatalError("OpSyslog_Init(): Unknown operation mode...\n");
+ break;
+ }
+
+ /* Since we are in init phase */
+ syslogContext->socket = -1;
+
+ if(NetConnect(syslogContext))
+ {
+ FatalError("OpSyslog_Init(): Failed to connect to host: [%s] %s:%u\n",
+ db_proto[syslogContext->proto],
+ syslogContext->server,
+ syslogContext->port);
+ return;
+ }
+
+ if( (syslogContext->payload = malloc(SYSLOG_MAX_QUERY_SIZE)) == NULL)
+ {
+ FatalError("OpSyslog_Init(): Can't allocate payload memory, bailling \n");
+ }
+
+ memset(syslogContext->payload,'\0',(SYSLOG_MAX_QUERY_SIZE));
+
+
+ if( (syslogContext->formatBuffer = malloc(SYSLOG_MAX_QUERY_SIZE)) == NULL)
+ {
+ FatalError("OpSyslog_Init(): Can't allocate payload memory, bailling \n");
+ }
+
+ memset(syslogContext->formatBuffer,'\0',(SYSLOG_MAX_QUERY_SIZE));
+
+ OpSyslog_LogConfig(syslogContext);
+
+ return;
+}
+
+
+/* Inverse of the setup function, free memory allocated in Setup
+ * can't free the outputPlugin since it is also the list node itself
+ */
+void OpSyslog_Exit(int signal,void *pSyslogContext)
+{
+ OpSyslog_Data *iSyslogContext = NULL;
+
+ if( pSyslogContext == NULL)
+ {
+ FatalError("OpSyslog_Exit(): Called with a NULL argument .... bailing \n");
+ }
+
+ iSyslogContext =(OpSyslog_Data *)pSyslogContext;
+
+ if(iSyslogContext->payload)
+ {
+ free(iSyslogContext->payload);
+ iSyslogContext->payload = NULL;
+ }
+
+ if(iSyslogContext->formatBuffer)
+ {
+ free(iSyslogContext->formatBuffer);
+ iSyslogContext->formatBuffer = NULL;
+ }
+
+ if(iSyslogContext->server)
+ {
+ free(iSyslogContext->server);
+ iSyslogContext->server = NULL;
+ }
+
+ if(iSyslogContext->sensor_name)
+ {
+ free(iSyslogContext->sensor_name);
+ iSyslogContext->sensor_name = NULL;
+ }
+
+ NetClose(iSyslogContext);
+
+ return;
+}
+
+
+/* Used to concat current format to current the syslog payload message */
+int OpSyslog_Concat(OpSyslog_Data *syslogContext)
+{
+
+ if( (syslogContext == NULL) ||
+ (syslogContext->payload == NULL) ||
+ (syslogContext->formatBuffer == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if( (syslogContext->payload_current_pos + syslogContext->format_current_pos) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ switch(syslogContext->operation_mode)
+ {
+
+ case 0:
+ if( (syslogContext->payload_current_pos += snprintf((syslogContext->payload+syslogContext->payload_current_pos),
+ (SYSLOG_MAX_QUERY_SIZE - syslogContext->payload_current_pos),
+ "%s",
+ syslogContext->formatBuffer)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+ break;
+
+ case 1:
+ if( (syslogContext->payload_current_pos += snprintf((syslogContext->payload+syslogContext->payload_current_pos),
+ (SYSLOG_MAX_QUERY_SIZE - syslogContext->payload_current_pos),
+ "%c %s %c",
+ syslogContext->delim,
+ syslogContext->formatBuffer,
+ syslogContext->delim)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+
+ memset(syslogContext->formatBuffer,'\0',SYSLOG_MAX_QUERY_SIZE);
+ syslogContext->format_current_pos = 0;
+
+ return 0;
+}
+
+int OpSyslog_LogConfig(void *pSyslogContext)
+{
+ OpSyslog_Data *iSyslogContext = NULL;
+
+ if( pSyslogContext == NULL)
+ {
+ return -1;
+ }
+
+ iSyslogContext =(OpSyslog_Data *)pSyslogContext;
+
+ LogMessage("spo_syslog_full config:\n");
+ LogMessage("\tDetail Level: %s\n",
+ iSyslogContext->detail == 1 ? "Full" : "Fast");
+
+ if(iSyslogContext->local_logging == 0)
+ {
+ LogMessage("\tSyslog Server: %s:%u\n",
+ iSyslogContext->server,
+ iSyslogContext->port);
+ LogMessage("\tReporting Protocol: %s\n",
+ db_proto[iSyslogContext->proto]);
+ }
+ else if(iSyslogContext->local_logging == 1)
+ {
+ LogMessage("\tConfigured to log to local syslog \n");
+ LogMessage("\tConfigure syslog Facility : [%s] \n",iSyslogContext->syslog_tx_facility);
+ LogMessage("\tConfigure syslog Priority : [%s] \n",iSyslogContext->syslog_tx_priority);
+ }
+
+ return 0;
+}
+
+
+
+/* CHECKME: -elz seem to have been incomplete @ creation time ...investigate after port */
+/*int Syslog_FormatReference(OpSyslog_Data *data, ReferenceNode *refer)
+{
+ReferenceNode *cRef = NULL;
+
+if( (data == NULL) ||
+(refer == NULL))
+{
+
+return 1;
+}
+
+cRef = refer;
+
+while(cRef)
+{
+LogMessage("System: %s ID:[%s] URL:%s\n", cRef->system->name,cRef->id, cRef->system->url);
+cRef = cRef->next;
+}
+return 0;
+
+}*/
+
+
+static int Syslog_FormatTrigger(OpSyslog_Data *syslogData, Unified2EventCommon *pEvent,int opType)
+{
+
+ char tSigBuf[256] = {0};
+ char *timestamp_string = NULL;
+
+ SigNode *sn = NULL;
+ ClassType *cn = NULL;
+ //ReferenceNode *rn = NULL;
+
+ if( (syslogData == NULL) ||
+ (pEvent == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ switch(opType)
+ {
+
+ case 0:
+ /* Alert */
+ if( (syslogData->format_current_pos += snprintf(syslogData->formatBuffer,SYSLOG_MAX_QUERY_SIZE,"[SNORTIDS[ALERT]: [%s] }", syslogData->sensor_name)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+ break;
+ case 1:
+ /* Log */
+ if( (syslogData->format_current_pos += snprintf(syslogData->formatBuffer,SYSLOG_MAX_QUERY_SIZE,"[SNORTIDS[LOG]: [%s] ]", syslogData->sensor_name)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+ break;
+
+ default:
+ /* XXX */
+ LogMessage("Syslog_FormatTrigger(): Unknown [%d] operation mode \n",opType);
+ return 1;
+ break;
+ }
+
+
+ if( OpSyslog_Concat(syslogData))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+
+ if( (timestamp_string = GetTimestampByComponent(
+ ntohl(pEvent->event_second),
+ ntohl(pEvent->event_microsecond),
+ GetLocalTimezone())) == NULL)
+ {
+ /* XXX */
+ /* Something went wrong ...we create a little string? */
+ if( (timestamp_string = malloc(256)) == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ memset(timestamp_string,'\0',256);
+ snprintf(timestamp_string,256,"sec:[%u] msec:[%u] Second away from UTC:[%u] ",
+ ntohl(pEvent->event_second),
+ ntohl(pEvent->event_microsecond),
+ GetLocalTimezone());
+ }
+
+
+ snprintf(tSigBuf,256,"Snort Alert [%u:%u:%u]",
+ ntohl(pEvent->generator_id),
+ ntohl(pEvent->signature_id),
+ ntohl(pEvent->signature_revision));
+
+ sn = GetSigByGidSid(ntohl(pEvent->generator_id),
+ ntohl(pEvent->signature_id));
+
+ cn = ClassTypeLookupById(barnyard2_conf,
+ ntohl(pEvent->classification_id));
+
+ if( (syslogData->format_current_pos += snprintf(syslogData->formatBuffer,SYSLOG_MAX_QUERY_SIZE,"%s%c%u%c%s",
+ timestamp_string,syslogData->field_separators,
+ ntohl(pEvent->priority_id),syslogData->field_separators,
+ sn != NULL ? sn->msg : tSigBuf)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ free(timestamp_string);
+ return 1;
+ }
+
+
+ if( OpSyslog_Concat(syslogData))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+ if(cn)
+ {
+ if( (syslogData->format_current_pos += snprintf(syslogData->formatBuffer,SYSLOG_MAX_QUERY_SIZE,"%s",
+ cn->type)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ free(timestamp_string);
+ return 1;
+ }
+ }
+ else
+ {
+ if( ( syslogData->format_current_pos += snprintf(syslogData->formatBuffer,SYSLOG_MAX_QUERY_SIZE,"%s",
+ "[Unknown Classification]") >= SYSLOG_MAX_QUERY_SIZE))
+ {
+ /* XXX */
+ free(timestamp_string);
+ return 1;
+ }
+ }
+
+ if( OpSyslog_Concat(syslogData))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+ /*CHECKME: -elz Need to investigate */
+ //Syslog_FormatReference(syslogData, sn->refs);
+
+ free(timestamp_string);
+
+ return 0;
+}
+
+
+
+static int Syslog_FormatIPHeaderAlert(OpSyslog_Data *data, Packet *p)
+{
+ int inner_ip = 0;
+
+ char *p_ip = NULL;
+ char s_ip[16] ={0};
+ char d_ip[16] ={0};
+
+
+ if(data == NULL ||
+ p == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+
+
+ /* This might not be fixed but meanwhile its a fix */
+ if( (p->iph == NULL) &&
+ (p->inner_iph))
+ {
+ p->iph = p->inner_iph;
+ inner_ip =1;
+ }
+
+ if(p->iph)
+ {
+ p_ip = inet_ntoa(p->iph->ip_src);
+ memcpy(s_ip,p_ip,strlen(p_ip));
+
+ p_ip = inet_ntoa(p->iph->ip_dst);
+ memcpy(d_ip,p_ip,strlen(p_ip));
+
+ if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE,"%lu%c%s%c%s",
+ (u_long)p->iph->ip_proto,data->field_separators,
+ s_ip,data->field_separators,
+ d_ip)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ if(inner_ip)
+ {
+ p->iph = NULL;
+ }
+ return 1;
+ }
+ }
+
+ if(inner_ip)
+ {
+ p->iph = NULL;
+ }
+
+ return OpSyslog_Concat(data);
+}
+
+static int Syslog_FormatIPHeaderLog(OpSyslog_Data *data, Packet *p) {
+
+ int inner_ip = 0;
+
+ unsigned int s, d, proto, ver, hlen, tos, len, id, off, ttl, csum;
+ s=d=proto=ver=hlen=tos=len=id=off=ttl=csum=0;
+
+ if( (p->iph == NULL) &&
+ (p->inner_iph))
+ {
+ p->iph = p->inner_iph;
+ inner_ip =1;
+ }
+
+ if(p->iph)
+ {
+ if(p->iph->ip_src.s_addr)
+ s = ntohl( p->iph->ip_src.s_addr);
+ if(p->iph->ip_dst.s_addr)
+ d = ntohl( p->iph->ip_dst.s_addr);
+ if(p->iph->ip_proto)
+ proto = p->iph->ip_proto;
+ if(IP_VER(p->iph))
+ ver = IP_VER(p->iph);
+ if(IP_HLEN(p->iph))
+ ver = IP_HLEN(p->iph);
+ if(p->iph->ip_tos)
+ tos = p->iph->ip_tos;
+ if(p->iph->ip_len)
+ len = ntohs(p->iph->ip_len);
+ if(p->iph->ip_id)
+ id = ntohs(p->iph->ip_id);
+ if(p->iph->ip_off)
+ off = (p->iph->ip_off);
+ if(p->iph->ip_ttl)
+ ttl = (p->iph->ip_ttl);
+ if(p->iph->ip_csum)
+ ttl = htons(p->iph->ip_csum);
+ }
+
+ if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u",
+ proto,data->field_separators,
+ s, data->field_separators,
+ d, data->field_separators,
+ ver, data->field_separators,
+ hlen, data->field_separators,
+ tos, data->field_separators,
+ len, data->field_separators,
+ id, data->field_separators,
+#if defined(WORDS_BIGENDIAN)
+ ((off & 0xE000) >> 13),data->field_separators,
+ htons(off & 0x1FFF),data->field_separators,
+#else
+ ((off & 0x00E0) >> 5),data->field_separators,
+ htons(off & 0xFF1F), data->field_separators,
+#endif
+ ttl,data->field_separators,
+ csum)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ if(inner_ip)
+ {
+ p->iph = NULL;
+ }
+
+ return 1;
+ }
+
+ if(inner_ip)
+ {
+ p->iph = NULL;
+ }
+
+
+ return OpSyslog_Concat(data);
+}
+
+
+static int Syslog_FormatTCPHeaderAlert(OpSyslog_Data *data, Packet *p)
+{
+ if( (data == NULL) ||
+ (p == NULL) ||
+ (p->tcph == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE,"%u%c%u",
+ ntohs(p->tcph->th_sport),data->field_separators,
+ ntohs(p->tcph->th_dport))) > SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ return OpSyslog_Concat(data);
+}
+
+static int Syslog_FormatTCPHeaderLog(OpSyslog_Data *data, Packet *p)
+{
+
+ unsigned int th_win, th_sum, th_flags, th_ack, th_seq, th_urp, th_off, th_x2;
+
+ th_win=th_sum=th_flags=th_ack=th_seq=th_urp=th_off=th_x2=0;
+
+ if( (data == NULL) ||
+ (p == NULL) ||
+ (p->tcph == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if(p->tcph)
+ {
+ if(p->tcph->th_seq)
+ th_seq = ntohl(p->tcph->th_seq);
+ if(p->tcph->th_ack)
+ th_ack = ntohl(p->tcph->th_ack);
+ if(TCP_OFFSET(p->tcph))
+ th_off = TCP_OFFSET(p->tcph);
+ if(TCP_X2(p->tcph))
+ th_x2 = TCP_X2(p->tcph);
+ if(p->tcph->th_flags)
+ th_flags = p->tcph->th_flags;
+ if(p->tcph->th_win)
+ th_win = ntohs(p->tcph->th_win);
+ if(p->tcph->th_sum)
+ th_sum = ntohs(p->tcph->th_sum);
+ if(p->tcph->th_urp)
+ th_urp = ntohs(p->tcph->th_urp);
+ }
+
+ if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u",
+ p->sp,data->field_separators,
+ p->dp, data->field_separators,
+ th_seq, data->field_separators,
+ th_ack, data->field_separators,
+ th_off, data->field_separators,
+ th_x2, data->field_separators,
+ th_flags, data->field_separators,
+ th_win, data->field_separators,
+ th_sum, data->field_separators,
+ th_urp)) > SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ return OpSyslog_Concat(data);
+}
+
+
+static int Syslog_FormatUDPHeaderAlert(OpSyslog_Data *data, Packet *p)
+{
+
+ if( (data == NULL) ||
+ (p == NULL) ||
+ (p->udph == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+
+ if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "%u%c%u",
+ ntohs(p->udph->uh_sport),data->field_separators,
+ ntohs(p->udph->uh_dport)) >= SYSLOG_MAX_QUERY_SIZE))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ return OpSyslog_Concat(data);;
+}
+
+static int Syslog_FormatUDPHeaderLog(OpSyslog_Data *data, Packet *p)
+{
+ unsigned int uh_len=0, uh_chk=0;
+
+ if( (data == NULL) ||
+ (p == NULL) ||
+ (p->udph == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if(p->udph)
+ {
+ if(p->udph->uh_len)
+ uh_len = ntohs(p->udph->uh_len);
+ if(p->udph->uh_chk)
+ uh_chk = ntohs(p->udph->uh_chk);
+ }
+
+ if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "%u%c%u%c%u%c%u",
+ ntohs(p->udph->uh_sport),data->field_separators,
+ ntohs(p->udph->uh_dport),data->field_separators,
+ uh_len, data->field_separators,
+ uh_chk)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ return OpSyslog_Concat(data);
+}
+
+/* Not Complete */
+static int Syslog_FormatICMPHeaderAlert(OpSyslog_Data *data, Packet *p)
+{
+ if( (data == NULL) ||
+ (p == NULL) ||
+ (p->icmph == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "%u%c%u",
+ p->icmph->type,data->field_separators,
+ p->icmph->code)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ return OpSyslog_Concat(data);
+}
+
+static int Syslog_FormatICMPHeaderLog(OpSyslog_Data *data, Packet *p)
+{
+
+ unsigned int type, code, csum, id, seq;
+ type=code=csum=id=seq=0;
+
+ if( (data == NULL) ||
+ (p == NULL) ||
+ (p->icmph == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ type = p->icmph->type;
+ code = p->icmph->code;
+ csum = ntohs(p->icmph->csum);
+
+ if(type == 0 || type == 8 ||
+ type == 13 || type == 14 ||
+ type == 15 || type == 16)
+ {
+
+ id = htons(p->icmph->icmp_hun.idseq.id);
+ seq = htons(p->icmph->icmp_hun.idseq.seq);
+
+
+ }
+
+ if( (data->format_current_pos += snprintf(data->formatBuffer, SYSLOG_MAX_QUERY_SIZE,
+ "%u%c%u%c%u%c%u%c%u",
+ type,data->field_separators,
+ code,data->field_separators,
+ csum,data->field_separators,
+ id,data->field_separators,
+ seq)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ return OpSyslog_Concat(data);
+}
+
+int Syslog_FormatPayload(OpSyslog_Data *data, Packet *p) {
+
+ char *hex_payload = NULL;
+
+ if( (data == NULL) ||
+ (p == NULL) ||
+ (p->pkt == NULL))
+
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if(p->pkth->len > 0)
+ {
+ if( (hex_payload = fasthex(p->pkt, p->pkth->len)) == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+ if( (data->format_current_pos += snprintf(data->formatBuffer, SYSLOG_MAX_QUERY_SIZE,
+ "%u%c%s",
+ p->pkth->len,data->field_separators,
+ hex_payload)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ free(hex_payload);
+ return 1;
+ }
+
+ free(hex_payload);
+ }
+
+ return OpSyslog_Concat(data);
+}
+
+
+void OpSyslog_Alert(Packet *p, void *event, uint32_t event_type, void *arg)
+{
+ OpSyslog_Data *syslogContext = NULL;
+ Unified2EventCommon *iEvent = NULL;
+
+ SigNode *sn = NULL;
+ ClassType *cn = NULL;
+
+
+ char sip[16] = {0};
+ char dip[16] = {0};
+
+ if( (p == NULL) ||
+ (event == NULL) ||
+ (arg == NULL))
+ {
+ LogMessage("OpSyslog_Alert(): Invoked with Packet[0x%x] Event[0x%x] Event Type [%u] Context pointer[0x%x]\n",
+ p,
+ event,
+ event_type,
+ arg);
+ return;
+ }
+
+ if(event_type != UNIFIED2_IDS_EVENT)
+ {
+ LogMessage("OpSyslog_Alert(): Is currently unable to handle Event Type [%u] \n",
+ event_type);
+ return;
+ }
+
+
+ syslogContext = (OpSyslog_Data *)arg;
+ iEvent = event;
+
+ memset(syslogContext->payload,'\0',(SYSLOG_MAX_QUERY_SIZE));
+ memset(syslogContext->formatBuffer,'\0',(SYSLOG_MAX_QUERY_SIZE));
+ syslogContext->payload_current_pos = 0;
+ syslogContext->format_current_pos = 0;
+
+ switch(syslogContext->operation_mode)
+ {
+
+ case 0: /* Ze Classic (Requested) */
+
+ if(IPH_IS_VALID(p))
+ {
+ if (strlcpy(sip, inet_ntoa(GET_SRC_ADDR(p)), sizeof(sip)) >= sizeof(sip))
+ {
+ FatalError("[%s()], strlcpy() error , bailing \n",
+ __FUNCTION__);
+ return;
+ }
+
+
+ if (strlcpy(dip, inet_ntoa(GET_DST_ADDR(p)), sizeof(dip)) >= sizeof(dip))
+ {
+ FatalError("[%s()], strlcpy() error , bailing \n",
+ __FUNCTION__);
+ return;
+ }
+ }
+
+ sn = GetSigByGidSid(ntohl(iEvent->generator_id),
+ ntohl(iEvent->signature_id));
+
+ cn = ClassTypeLookupById(barnyard2_conf,
+ ntohl(iEvent->classification_id));
+
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "[%u:%u:%u] ",
+ ntohl(iEvent->generator_id),
+ ntohl(iEvent->signature_id),
+ ntohl(iEvent->signature_revision))) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("[%s()], failed call to snprintf \n",
+ __FUNCTION__);
+ return;
+ }
+
+ if( OpSyslog_Concat(syslogContext))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+ if(sn != NULL)
+ {
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "%s ",
+ sn->msg)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("[%s()], failed call to snprintf \n",
+ __FUNCTION__);
+ }
+ }
+ else
+ {
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "ALERT ")) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("[%s()], failed call to snprintf \n",
+ __FUNCTION__);
+ }
+
+ }
+
+ if( OpSyslog_Concat(syslogContext))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+
+
+ if(cn != NULL)
+ {
+ if( cn->name )
+ {
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "[Classification: %s] [Priority: %d]:",
+ cn->name,
+ ntohl(((Unified2EventCommon *)event)->priority_id))) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("[%s()], failed call to snprintf \n",
+ __FUNCTION__);
+ return ;
+ }
+
+ }
+ }
+ else if( ntohl(((Unified2EventCommon *)event)->priority_id) != 0 )
+ {
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "[Priority: %d]:",
+ ntohl(((Unified2EventCommon *)event)->priority_id))) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("[%s()], failed call to snprintf \n",
+ __FUNCTION__);
+ return ;
+ }
+ }
+
+ if( OpSyslog_Concat(syslogContext))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+
+ if( (IPH_IS_VALID(p)) &&
+ (((GET_IPH_PROTO(p) != IPPROTO_TCP &&
+ GET_IPH_PROTO(p) != IPPROTO_UDP &&
+ GET_IPH_PROTO(p) != IPPROTO_ICMP) ||
+ p->frag_flag)))
+ {
+ if(!BcAlertInterface())
+ {
+ if( protocol_names[GET_IPH_PROTO(p)] )
+ {
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ " {%s} %s -> %s",
+ protocol_names[GET_IPH_PROTO(p)],
+ sip, dip)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ return ;
+ }
+ }
+ }
+ else
+ {
+ if( protocol_names[GET_IPH_PROTO(p)] )
+ {
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ " <%s> {%s} %s -> %s",
+ barnyard2_conf->interface,
+ protocol_names[GET_IPH_PROTO(p)],
+ sip, dip)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("[%s()], failed call to snprintf \n",
+ __FUNCTION__);
+ return ;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(BcAlertInterface())
+ {
+ if( protocol_names[GET_IPH_PROTO(p)] )
+ {
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ " <%s> {%s} %s:%i -> %s:%i",
+ barnyard2_conf->interface,
+ protocol_names[GET_IPH_PROTO(p)], sip,
+ p->sp, dip, p->dp)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("[%s()], failed call to snprintf \n",
+ __FUNCTION__);
+ return;
+ }
+ }
+ }
+ else
+ {
+ if( protocol_names[GET_IPH_PROTO(p)] )
+ {
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ " {%s} %s:%i -> %s:%i",
+ protocol_names[GET_IPH_PROTO(p)], sip, p->sp,
+ dip, p->dp)) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("[%s()], failed call to snprintf \n",
+ __FUNCTION__);
+ return;
+ }
+ }
+ }
+ }
+
+
+ if( OpSyslog_Concat(syslogContext))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+ break;
+
+ case 1: /* Ze verbose */
+
+ if(Syslog_FormatTrigger(syslogContext, iEvent,0) )
+ {
+ LogMessage("WARNING: Unable to append Trigger header.\n");
+ return;
+ }
+
+ /* Support for portscan ip */
+ if(p->iph ||
+ p->inner_iph)
+ {
+ if(Syslog_FormatIPHeaderAlert(syslogContext, p) )
+ {
+ LogMessage("WARNING: Unable to append Trigger header.\n");
+ return;
+ }
+ }
+
+ if(p->iph)
+ {
+ /* build the protocol specific header information */
+ switch(p->iph->ip_proto)
+ {
+ case IPPROTO_TCP:
+ Syslog_FormatTCPHeaderAlert(syslogContext, p);
+ break;
+ case IPPROTO_UDP:
+ Syslog_FormatUDPHeaderAlert(syslogContext, p);
+ break;
+ case IPPROTO_ICMP:
+ Syslog_FormatICMPHeaderAlert(syslogContext, p);
+ break;
+ }
+ }
+
+ /* CHECKME: -elz will update formating later on .. */
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "\n")) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("Couldn't finalize payload string ....\n");
+ }
+
+ if( OpSyslog_Concat(syslogContext))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+ break;
+
+ default:
+ FatalError("[%s()]: Unknown operation_mode ... bailing \n",
+ __FUNCTION__);
+ break;
+ }
+
+ if(NetSend(syslogContext))
+ {
+ NetClose(syslogContext);
+ if(syslogContext->local_logging != 1)
+ {
+ FatalError("NetSend(): call failed for host:port '%s:%u' bailing...\n", syslogContext->server, syslogContext->port);
+ }
+ return;
+ }
+ return;
+}
+
+void OpSyslog_Log(Packet *p, void *event, uint32_t event_type, void *arg)
+{
+
+ OpSyslog_Data *syslogContext = NULL;
+ Unified2EventCommon *iEvent = NULL;
+
+ if( (p == NULL) ||
+ (event == NULL) ||
+ (arg == NULL))
+ {
+ LogMessage("OpSyslog_Log(): Invoked with Packet[0x%x] Event[0x%x] Event Type [%u] Context pointer[0x%x]\n",
+ p,
+ event,
+ event_type,
+ arg);
+ return;
+ }
+
+ if(event_type != UNIFIED2_IDS_EVENT)
+ {
+ LogMessage("OpSyslog_Log(): Is currently unable to handle Event Type [%u] \n",
+ event_type);
+ }
+
+ syslogContext = (OpSyslog_Data *)arg;
+ iEvent = event;
+
+ memset(syslogContext->payload,'\0',(SYSLOG_MAX_QUERY_SIZE));
+ memset(syslogContext->formatBuffer,'\0',(SYSLOG_MAX_QUERY_SIZE));
+ syslogContext->payload_current_pos = 0;
+ syslogContext->format_current_pos = 0;
+
+ if(Syslog_FormatTrigger(syslogContext, iEvent,1) )
+ {
+ FatalError("WARNING: Unable to append Trigger header.\n");
+ }
+
+ if(p->iph || p->inner_iph)
+ {
+ Syslog_FormatIPHeaderLog(syslogContext, p);
+ }
+
+ if(p->iph)
+ {
+ switch(p->iph->ip_proto)
+ {
+ case IPPROTO_ICMP:
+ Syslog_FormatICMPHeaderLog(syslogContext, p);
+ break;
+ case IPPROTO_TCP:
+ Syslog_FormatTCPHeaderLog(syslogContext, p);
+ break;
+ case IPPROTO_UDP:
+ Syslog_FormatUDPHeaderLog(syslogContext, p);
+ break;
+ }
+ }
+
+ Syslog_FormatPayload(syslogContext, p);
+
+ /* CHECKME: -elz will update formating later on .. */
+ if( (syslogContext->format_current_pos += snprintf(syslogContext->formatBuffer,SYSLOG_MAX_QUERY_SIZE,
+ "\n")) >= SYSLOG_MAX_QUERY_SIZE)
+ {
+ /* XXX */
+ FatalError("Couldn't finalize payload string ....\n");
+ }
+
+ if( OpSyslog_Concat(syslogContext))
+ {
+ /* XXX */
+ FatalError("OpSyslog_Concat(): Failed \n");
+ }
+
+ if(NetSend(syslogContext))
+ {
+ NetClose(syslogContext);
+ //Reliability...
+ FatalError("WARNING: Unable to connect to our syslog host: '%s:%u'\n", syslogContext->server, syslogContext->port);
+
+ return;
+ }
+
+ return;
+}
+
+
+OpSyslog_Data *OpSyslog_ParseArgs(char *args)
+{
+ OpSyslog_Data *op_data = NULL;
+
+ op_data = (OpSyslog_Data *)SnortAlloc(sizeof(OpSyslog_Data));
+
+ if(args != NULL)
+ {
+ char **toks;
+ int num_toks;
+ int i;
+ /* parse out your args */
+ toks = mSplit(args, ",", 31, &num_toks, '\\');
+ for(i = 0; i < num_toks; ++i)
+ {
+ char **stoks;
+ int num_stoks;
+ char *index = toks[i];
+ while(isspace((int)*index))
+ ++index;
+ stoks = mSplit(index, " ", 2, &num_stoks, 0);
+ if(strcasecmp("port", stoks[0]) == 0)
+ {
+ if(num_stoks > 1 )
+ op_data->port = strtoul(stoks[1], NULL, 0);
+ else
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ file_line, index);
+ }
+ else if(strcasecmp("server", stoks[0]) == 0)
+ {
+ if(num_stoks > 1 && !op_data->server )
+ op_data->server = strdup(stoks[1]);
+ else
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ file_line, index);
+ }
+ else if(strcasecmp("sensor_name", stoks[0]) == 0)
+ {
+ if(num_stoks > 1 && !op_data->sensor_name )
+ op_data->sensor_name = strdup(stoks[1]);
+ else
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ file_line, index);
+ }
+ else if(strcasecmp("protocol", stoks[0]) == 0)
+ {
+ if(num_stoks > 1)
+ {
+ if(strcasecmp("udp", stoks[1]) == 0)
+ op_data->proto = 0;
+ else
+ op_data->proto = 1;
+ }
+ else
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ file_line, index);
+ }
+ else if(strcasecmp("detail", stoks[0]) == 0)
+ {
+ if(num_stoks > 1)
+ {
+ if(strcasecmp("full", stoks[1]) == 0)
+ op_data->detail = 1;
+ }
+ else
+ LogMessage("Argument Error in %s(%i): %s\n", file_name,
+ file_line, index);
+ }
+ else if(strcasecmp("delimiters", stoks[0]) == 0)
+ {
+ if(num_stoks >= 1)
+ {
+ if( (strlen(stoks[1]) > 3) ||
+ (strlen(stoks[1]) < 3))
+ {
+ LogMessage("Invalid delimiters configured [%s], default will be used \n",stoks[1]);
+ }
+ else
+ {
+ if(stoks[1][0] == '"' &&
+ stoks[1][2] == '"')
+ {
+ op_data->delim = stoks[1][1];
+ }
+ else
+ {
+ LogMessage("Invalid delimiters configured [%s], default will be used \n",stoks[1]);
+ }
+ }
+ }
+
+ }
+ else if(strcasecmp("separators", stoks[0]) == 0)
+ {
+ if(num_stoks >= 1)
+ {
+ if( (strlen(stoks[1]) > 3) ||
+ (strlen(stoks[1]) < 3))
+ {
+
+ LogMessage("Invalid field separator configured [%s], default will be used \n",stoks[1]);
+ }
+ else
+ {
+ if(stoks[1][0] == '"' &&
+ stoks[1][2] == '"')
+ {
+ op_data->field_separators = stoks[1][1];
+ }
+ else
+ {
+ LogMessage("Invalid field separator configured [%s], default will be used. \n",stoks[1]);
+ }
+ }
+ }
+ }
+ else if(strcasecmp("operation_mode", stoks[0]) == 0)
+ {
+ if(num_stoks >=1)
+ {
+ if(strcasecmp("default",stoks[1]))
+ {
+ op_data->operation_mode = 0;
+ }
+ else if(strcasecmp("complete",stoks[1]))
+ {
+ op_data->operation_mode = 1;
+ }
+ else
+ {
+ LogMessage("Invalid operation_mode defined [%s], will use default mode \n",stoks[1]);
+ }
+ }
+ else
+ {
+ LogMessage("Invalid operation_mode defined, will use default mode \n");
+ }
+
+ }
+ else if(strcasecmp("local", stoks[0]) == 0)
+ {
+ op_data->local_logging = 1;
+ }
+ else if(strcasecmp("log_facility", stoks[0]) == 0)
+ {
+ if(num_stoks >=1)
+ {
+ if(!strcasecmp("LOG_KERN", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_KERN;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_KERN");
+ }
+ else if(!strcasecmp("LOG_MAIL", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_MAIL;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_MAIL");
+ }
+ else if(!strcasecmp("LOG_DAEMON", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_DAEMON;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_DAEMON");
+ }
+ else if(!strcasecmp("LOG_AUTH", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_AUTH;
+ snprintf(op_data->syslog_tx_facility,"%s","");
+ }
+ else if(!strcasecmp("LOG_SYSLOG", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_SYSLOG;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_SYSLOG");
+ }
+ else if(!strcasecmp("LOG_LPR", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_LPR;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_LPR");
+ }
+ else if(!strcasecmp("LOG_NEWS", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_NEWS;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_NEWS");
+ }
+ else if(!strcasecmp("LOG_UUCP", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_UUCP;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_UUCP");
+ }
+ else if(!strcasecmp("LOG_CRON", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_CRON;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_CRON");
+ }
+ else if(!strcasecmp("LOG_AUTHPRIV", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_AUTHPRIV;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_AUTHPRIV");
+ }
+ else if(!strcasecmp("LOG_FTP", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_FTP;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_FTP");
+ }
+ else if(!strcasecmp("LOG_LOCAL1", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_LOCAL1;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_LOCAL1");
+ }
+ else if(!strcasecmp("LOG_LOCAL2", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_LOCAL2;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_LOCAL2");
+ }
+ else if(!strcasecmp("LOG_LOCAL3", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_LOCAL3;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_LOCAL3");
+ }
+ else if(!strcasecmp("LOG_LOCAL4", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_LOCAL4;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_LOCAL4");
+ }
+ else if(!strcasecmp("LOG_LOCAL5", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_LOCAL5;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_LOCAL5");
+ }
+ else if(!strcasecmp("LOG_LOCAL6", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_LOCAL6;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_LOCAL6");
+ }
+
+ else if(!strcasecmp("LOG_LOCAL7", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_LOCAL7;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_LOCAL7");
+
+ }
+ else if(!strcasecmp("LOG_USER", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_USER;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_USER");
+ }
+ else
+ {
+ LogMessage("[%s()]: Unknown log_facility defined [%s], using \"LOG_USER\" as default \n",
+ __FUNCTION__,
+ stoks[1]);
+ op_data->syslog_priority |= LOG_USER;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_USER");
+ }
+
+ }
+ else
+ {
+ LogMessage("No default log_facility defined, using LOG_USER as default \n");
+ op_data->syslog_priority |= LOG_USER;
+ }
+
+ }
+ else if(strcasecmp("log_priority", stoks[0]) == 0)
+ {
+ if(num_stoks >=1)
+ {
+ if(!strcasecmp("LOG_EMERG",stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_EMERG;
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_EMERG");
+ }
+ else if(!strcasecmp("LOG_ALERT", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_ALERT;
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_ALERT");
+ }
+ else if(!strcasecmp("LOG_CRIT", stoks[1]))
+ {
+ op_data->syslog_priority |=LOG_CRIT;
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_CRIT");
+ }
+ else if(!strcasecmp("LOG_ERR", stoks[1]))
+ {
+ op_data->syslog_priority |=LOG_ERR;
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_ERR");
+ }
+ else if(!strcasecmp("LOG_WARNING", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_WARNING;
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_WARNING");
+ }
+ else if(!strcasecmp("LOG_NOTICE", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_NOTICE;
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_NOTICE");
+ }
+ else if(!strcasecmp("LOG_INFO", stoks[1]))
+ {
+ op_data->syslog_priority |=LOG_INFO;
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_INFO");
+ }
+ else if(!strcasecmp("LOG_DEBUG", stoks[1]))
+ {
+ op_data->syslog_priority |= LOG_DEBUG;
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_DEBUG");
+ }
+ else
+ {
+ LogMessage("[%s()]: Unknown log_priority defined [%s], using \"LOG_INFO\" as default \n",
+ __FUNCTION__,
+ stoks[1]);
+ op_data->syslog_priority |= LOG_INFO;
+ }
+ }
+ else
+ {
+ LogMessage("No default log_priority defined, using LOG_INFO as default \n");
+ op_data->syslog_priority |= LOG_INFO;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "WARNING %s (%d) => Unrecognized argument for "
+ "SyslogFull plugin: %s\n", file_name, file_line, index);
+ }
+
+
+ }
+ /* free your mSplit tokens */
+ mSplitFree(&toks, num_toks);
+ }
+
+ /* Default */
+ if(op_data->sensor_name == NULL)
+ {
+ FatalError("You must specify a sensor name\n");
+ }
+
+ if(op_data->syslog_priority == 0)
+ {
+ op_data->syslog_priority = LOG_INFO | LOG_USER;
+ snprintf(op_data->syslog_tx_facility,16,"%s","LOG_USER");
+ snprintf(op_data->syslog_tx_priority,16,"%s","LOG_INFO");
+ }
+
+
+ if(op_data->local_logging == 1)
+ {
+ LogMessage("Local logging enabled, WILL NOT send information to a remote syslog \n");
+ }
+
+ if( op_data->local_logging == 0)
+ {
+ if(op_data->port == 0)
+ {
+ LogMessage("Using default Syslog port [%u] \n",op_data->port);
+ op_data->port = 514;
+ }
+
+ if( op_data->server == NULL)
+ {
+ FatalError("You must specify a valid server \n");
+ }
+
+ }
+
+ if(op_data->operation_mode == 0)
+ {
+ LogMessage("using operation_mode: default \n");
+ }
+ else if(op_data->operation_mode == 1)
+ {
+ LogMessage("using operation_mode: complete \n");
+
+ if(op_data->delim == 0)
+ {
+ LogMessage("Using default delimiters for syslog messages \"|\"\n");
+ op_data->delim = '|';
+ }
+ else
+ {
+ LogMessage("Using \"%c\" as delimiters for syslog messages \n",op_data->delim);
+ }
+
+ if(op_data->field_separators == 0)
+ {
+ LogMessage("Using default field separators for syslog messages \" \"\n");
+ op_data->field_separators= ' ';
+ }
+ else
+ {
+ LogMessage("Using \"%c\" as field separators for syslog messages \n",op_data->field_separators);
+ }
+ }
+ else
+ {
+ LogMessage("Defaulting operation_mode to default. \n");
+ op_data->operation_mode = 0;
+ }
+
+
+ return op_data;
+}
+
+
+int UDPConnect(OpSyslog_Data *op_data)
+{
+
+ if( (op_data == NULL))
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if(op_data->socket != -1 )
+ {
+ return 0;
+ }
+
+ if( (op_data->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ perror("Socket()");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int TCPConnect(OpSyslog_Data *op_data)
+{
+ int option=1;
+
+ if(op_data == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+
+
+ if( (op_data->socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ LogMessage("Failed to create our socket");
+ return 1;
+ }
+
+ /* CHECKME: -elz Really needed....? */
+ if( (setsockopt(op_data->socket,IPPROTO_TCP,TCP_NODELAY, (char *)&option, sizeof(option))) < 0 )
+ {
+ perror("setsockopt():");
+ close(op_data->socket);
+ op_data->socket = -1;
+ return 1;
+ }
+
+ if( connect(op_data->socket,(struct sockaddr *)&op_data->sockaddr, sizeof(op_data->sockaddr)) != 0 )
+ {
+ perror("connect()");
+ close(op_data->socket);
+ op_data->socket = -1;
+ return 1;
+ }
+
+
+ return 0;
+}
+
+int NetConnect(OpSyslog_Data *op_data)
+{
+ if(op_data == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if(op_data->local_logging == 1)
+ {
+ return 0;
+ }
+
+ if(op_data->socket > 0)
+ {
+ if(NetTestSocket(op_data))
+ {
+ op_data->socket = -1;
+ /* Test reconnection */
+ }
+ }
+
+
+ /* Set socket information */
+
+ if (inet_aton(op_data->server,&op_data->sockaddr.sin_addr) != 1)
+ {
+ if ((op_data->hostPtr = gethostbyname(op_data->server)) == NULL)
+ {
+ FatalError("could not resolve address[%s]",op_data->server);
+ }
+
+ memcpy(&op_data->sockaddr.sin_addr,op_data->hostPtr->h_addr,sizeof(op_data->sockaddr.sin_addr));
+ }
+
+
+ op_data->sockaddr.sin_port = htons(op_data->port);
+ op_data->sockaddr.sin_family = AF_INET;
+
+
+
+ switch(op_data->proto)
+ {
+ case 0:
+ return UDPConnect(op_data);
+ break;
+ case 1:
+ return TCPConnect(op_data);
+ break;
+ default:
+ FatalError("Protocol not supported\n");
+ return 1;
+ break;
+ }
+
+ /* XXX */
+ /* Should never be reached */
+ return 1;
+}
+
+
+int NetClose(OpSyslog_Data *op_data)
+{
+ int rval = 0;
+
+ if(op_data ==NULL)
+ {
+ /* XXX */
+ return -1;
+ }
+
+ if(op_data->local_logging == 1)
+ {
+ /* We Skip */
+ return 0;
+ }
+
+ if(op_data->socket)
+ {
+ rval = close(op_data->socket);
+ op_data->socket = -1;
+ }
+
+ return rval;
+}
+
+
+int NetTestSocket(OpSyslog_Data *op_data)
+{
+ struct sockaddr addr = {0};
+ socklen_t socklen = {0};
+
+ if (op_data == NULL)
+ {
+ /* XXX */
+ return 1;
+ }
+
+ if(op_data->local_logging == 1)
+ {
+ /* We skip */
+ return 0;