📄 spo_unified.c
字号:
/*** Copyright (C) 1998-2005 Martin Roesch <roesch@sourcefire.com>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License 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.*//* $Id$ *//* spo_unified * * Purpose: * * This plugin generates the new unified alert and logging formats * * Arguments: * * filename of the alert and log spools * * Effect: * * Packet logs are written (quickly) to a unified output file * * Comments: * * The future... */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h>#include <stdlib.h>#include <string.h>#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <errno.h>#include <time.h>#include "decode.h"#include "rules.h"#include "util.h"#include "plugbase.h"#include "spo_plugbase.h"#include "parser.h"#include "debug.h"#include "mstring.h"#include "stream.h"#include "event.h"#include "generators.h"#include "snort_packet_header.h"#include "snort.h"#ifdef GIDS#include "inline.h"#endif#define SNORT_MAGIC 0xa1b2c3d4#define ALERT_MAGIC 0xDEAD4137 /* alert magic, just accept it */#define LOG_MAGIC 0xDEAD1080 /* log magic, what's 31337-speak for G? */#define SNORT_VERSION_MAJOR 1#define SNORT_VERSION_MINOR 2/* From fpdetect.c, for logging reassembled packets */extern u_int16_t event_id;/* file header for snort unified format log files * * Identical to pcap file header, used for portability where the libpcap * might not be used after the pa_engine code becomes available */ typedef struct _UnifiedLogFileHeader{ u_int32_t magic; u_int16_t version_major; u_int16_t version_minor; u_int32_t timezone; u_int32_t sigfigs; u_int32_t snaplen; u_int32_t linktype;} UnifiedLogFileHeader;typedef struct _UnifiedAlertFileHeader{ u_int32_t magic; u_int32_t version_major; u_int32_t version_minor; u_int32_t timezone;} UnifiedAlertFileHeader;/* unified log packet header format * * One of these per packet in the log file, the packets are appended in the * file after each UnifiedLog header (extended pcap format) */typedef struct _UnifiedLog{ Event event; u_int32_t flags; /* bitmap for interesting flags */ SnortPktHeader pkth; /* SnortPktHeader schtuff */} UnifiedLog;/* Unified alert message format * * One per event notification, all the important data for people to know */typedef struct _UnifiedAlert{ Event event; struct timeval ts; /* event timestamp */ u_int32_t sip; /* src ip */ u_int32_t dip; /* dest ip */ u_int16_t sp; /* src port */ u_int16_t dp; /* dest port */ u_int32_t protocol; /* protocol id */ u_int32_t flags; /* any other flags (fragmented, etc) */} UnifiedAlert;/* ----------------External variables -------------------- */extern OptTreeNode *otn_tmp;extern int thiszone;#ifdef GIDS#ifndef IPFWextern ipq_packet_msg_t *g_m;#endif#endif/* ------------------ Data structures --------------------------*/typedef struct _UnifiedConfig{ char *filename; FILE *stream; unsigned int limit; unsigned int current;} UnifiedConfig;typedef struct _FileHeader{ u_int32_t magic; u_int32_t flags;} FileHeader;typedef struct _DataHeader{ u_int32_t type; u_int32_t length;} DataHeader;#define UNIFIED_MAGIC 0x2dac5ceb#define UNIFIED_TYPE_ALERT 0x1#define UNIFIED_TYPE_PACKET_ALERT 0x2/* -------------------- Global Variables ----------------------*/#ifdef GIDSEtherHdr g_ethernet;#endif/* -------------------- Local Functions -----------------------*/static UnifiedConfig *UnifiedParseArgs(char *, char *);static void UnifiedCleanExit(int, void *);static void UnifiedRestart(int, void *);/* Unified Output functions */static void UnifiedInit(u_char *);static void UnifiedInitFile(UnifiedConfig *);static void UnifiedRotateFile(UnifiedConfig *);static void UnifiedLogAlert(Packet *, char *, void *, Event *);static void UnifiedLogPacketAlert(Packet *, char *, void *, Event *);static void RealUnifiedLogAlert(Packet *, char *, void *, Event *, DataHeader *);static void RealUnifiedLogPacketAlert(Packet *, char *, void *, Event *, DataHeader *);void RealUnifiedLogStreamAlert(Packet *,char *,void *,Event *,DataHeader *);static void UnifiedRotateFile(UnifiedConfig *data);/* Unified Alert functions (deprecated) */static void UnifiedAlertInit(u_char *);static void UnifiedInitAlertFile(UnifiedConfig *);static void UnifiedAlertRotateFile(UnifiedConfig *data);static void OldUnifiedLogAlert(Packet *, char *, void *, Event *);/* Unified Packet Log functions (deprecated) */static void UnifiedLogInit(u_char *);static void UnifiedInitLogFile(UnifiedConfig *);static void OldUnifiedLogPacketAlert(Packet *, char *, void *, Event *);static void UnifiedLogRotateFile(UnifiedConfig *data);static UnifiedConfig *unifiedConfig;/* * Function: SetupUnified() * * Purpose: Registers the output plugin keyword and initialization * function into the output plugin list. This is the function that * gets called from InitOutputPlugins() in plugbase.c. * * Arguments: None. * * Returns: void function * */void UnifiedSetup(){ /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("log_unified", NT_OUTPUT_LOG, UnifiedLogInit); RegisterOutputPlugin("alert_unified", NT_OUTPUT_ALERT, UnifiedAlertInit); RegisterOutputPlugin("unified", NT_OUTPUT_SPECIAL, UnifiedInit); DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output plugin: Unified logging/alerting " "is setup...\n"););}/* * Function: UnifiedInit(u_char *) * * Purpose: Calls the argument parsing function, performs final setup on data * structs, links the preproc function into the function list. * * Arguments: args => ptr to argument string * * Returns: void function * */void UnifiedInit(u_char *args){ if(unifiedConfig) { FatalError("unified can only be instantiated once\n"); } //DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: Unified Initialized\n");); pv.log_plugin_active = 1; pv.alert_plugin_active = 1; /* parse the argument list from the rules file */ unifiedConfig = UnifiedParseArgs(args, "snort-unified"); UnifiedInitFile(unifiedConfig); //LogMessage("UnifiedFilename = %s\n", unifiedConfig->filename); /* Set the preprocessor function into the function list */ AddFuncToOutputList(UnifiedLogAlert, NT_OUTPUT_ALERT, unifiedConfig); AddFuncToOutputList(UnifiedLogPacketAlert, NT_OUTPUT_LOG, unifiedConfig); AddFuncToCleanExitList(UnifiedCleanExit, unifiedConfig); AddFuncToRestartList(UnifiedRestart, unifiedConfig);}/* * Function: InitOutputFile() * * Purpose: Initialize the unified ouput file * * Arguments: data => pointer to the plugin's reference data struct * * Returns: void function */static void UnifiedInitFile(UnifiedConfig *data){ time_t curr_time; /* place to stick the clock data */ char logdir[STD_BUF]; FileHeader hdr; int value; bzero(logdir, STD_BUF); curr_time = time(NULL); if(data == NULL) FatalError("SpoUnified: Unable to get context data\n"); if(*(data->filename) == '/') value = snprintf(logdir, STD_BUF, "%s.%lu", data->filename, (unsigned long)curr_time); else value = snprintf(logdir, STD_BUF, "%s/%s.%lu", pv.log_dir, data->filename, (unsigned long)curr_time); if(value == -1) FatalError("SpoUnified: filepath too long\n"); //printf("Opening %s\n", logdir); if((data->stream = fopen(logdir, "wb")) == NULL) FatalError("UnifiedInitLogFile(%s): %s\n", logdir, strerror(errno)); /* write the log file header */ hdr.magic = UNIFIED_MAGIC; hdr.flags = 0; /* XXX: not used yet */ if(fwrite((char *)&hdr, sizeof(hdr), 1, data->stream) != 1) { FatalError("SpoUnified: InitOutputFile(): %s", strerror(errno)); } fflush(data->stream); return;}void UnifiedRotateFile(UnifiedConfig *data){ fclose(data->stream); data->current = 0; UnifiedInitFile(data);}/* buffer */static char write_pkt_buffer[sizeof(DataHeader)+IP_MAXPACKET];/* buffer */int UnifiedLogData(u_int32_t type, u_int32_t length, void *data){ DataHeader dHdr; if(!unifiedConfig) { FatalError("Unified output not configured\n"); } /* do not write if data is not available */ if(!data) { LogMessage("WARNING: call to LogUnified with NULL data\n"); return -1; } /* length check */ if(length <= 0) { LogMessage("Empty Alert ....LogUnified bailing \n"); return -1; } memset(write_pkt_buffer,'\0',sizeof(DataHeader)+IP_MAXPACKET); dHdr.type = type; dHdr.length = length; memcpy(write_pkt_buffer,&dHdr,sizeof(DataHeader)); memcpy(write_pkt_buffer+sizeof(DataHeader),(char *)data,length);/* if(fwrite((char *)&dHdr, sizeof(DataHeader), 1, unifiedConfig->stream) != 1) { FatalError("SpoUnified: write failed: %s\n", strerror(errno)); } if(fwrite((char *)data, length, 1, unifiedConfig->stream) != 1) {*/ if(fwrite(write_pkt_buffer,length+sizeof(DataHeader),1,unifiedConfig->stream) != 1) { FatalError("SpoUnified: write failed: %s\n", strerror(errno)); } fflush(unifiedConfig->stream); return 0;}void UnifiedLogAlert(Packet *p, char *msg, void *arg, Event *event){ DataHeader dHdr; dHdr.type = UNIFIED_TYPE_ALERT; dHdr.length = sizeof(UnifiedAlert); /* check for a pseudo-packet, we don't want to log those */ RealUnifiedLogAlert(p, msg, arg, event, &dHdr);} void RealUnifiedLogAlert(Packet *p, char *msg, void *arg, Event *event, DataHeader *dHdr){ UnifiedConfig *data = (UnifiedConfig *)arg; UnifiedAlert alertdata; Stream * s; StreamPacketData * spd; bzero(&alertdata, sizeof(alertdata)); if(event != NULL) { alertdata.event.sig_generator = event->sig_generator; alertdata.event.sig_id = event->sig_id; alertdata.event.sig_rev = event->sig_rev; alertdata.event.classification = event->classification; alertdata.event.priority = event->priority; alertdata.event.event_id = event->event_id; alertdata.event.event_reference = event->event_reference; alertdata.event.ref_time.tv_sec = event->ref_time.tv_sec; alertdata.event.ref_time.tv_usec = event->ref_time.tv_usec; } if(p) { alertdata.ts.tv_sec = p->pkth->ts.tv_sec; alertdata.ts.tv_usec = p->pkth->ts.tv_usec; if(p->packet_flags & PKT_REBUILT_STREAM) { DEBUG_WRAP(DebugMessage(DEBUG_LOG, "man:Logging rebuilt stream data.\n");); s = (Stream *) p->streamptr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -