diff --git a/src/alert-debuglog.c b/src/alert-debuglog.c index d2153d782f..52b65d7f92 100644 --- a/src/alert-debuglog.c +++ b/src/alert-debuglog.c @@ -14,6 +14,7 @@ #include "flow.h" #include "conf.h" +#include "threads.h" #include "threadvars.h" #include "tm-modules.h" @@ -33,6 +34,7 @@ int AlertDebuglogIPv6(ThreadVars *, Packet *, void *, PacketQueue *); int AlertDebuglogThreadInit(ThreadVars *, void*, void **); int AlertDebuglogThreadDeinit(ThreadVars *, void *); void AlertDebuglogExitPrintStats(ThreadVars *, void *); +int AlertDebuglogOpenFileCtx(LogFileCtx* , char *); void TmModuleAlertDebuglogRegister (void) { tmm_modules[TMM_ALERTDEBUGLOG].name = "AlertDebuglog"; @@ -44,7 +46,8 @@ void TmModuleAlertDebuglogRegister (void) { } typedef struct AlertDebuglogThread_ { - FILE *fp; + LogFileCtx *file_ctx; + /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ uint32_t alerts; } AlertDebuglogThread; @@ -70,54 +73,56 @@ int AlertDebuglogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - fprintf(aft->fp, "+================\n"); - fprintf(aft->fp, "TIME: %s\n", timebuf); - fprintf(aft->fp, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); + mutex_lock(&aft->file_ctx->fp_mutex); + + fprintf(aft->file_ctx->fp, "+================\n"); + fprintf(aft->file_ctx->fp, "TIME: %s\n", timebuf); + fprintf(aft->file_ctx->fp, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; - fprintf(aft->fp, "ALERT MSG [%02d]: %s\n", i, pa->msg); - fprintf(aft->fp, "ALERT GID [%02d]: %" PRIu32 "\n", i, pa->gid); - fprintf(aft->fp, "ALERT SID [%02d]: %" PRIu32 "\n", i, pa->sid); - fprintf(aft->fp, "ALERT REV [%02d]: %" PRIu32 "\n", i, pa->rev); - fprintf(aft->fp, "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->prio); + fprintf(aft->file_ctx->fp, "ALERT MSG [%02d]: %s\n", i, pa->msg); + fprintf(aft->file_ctx->fp, "ALERT GID [%02d]: %" PRIu32 "\n", i, pa->gid); + fprintf(aft->file_ctx->fp, "ALERT SID [%02d]: %" PRIu32 "\n", i, pa->sid); + fprintf(aft->file_ctx->fp, "ALERT REV [%02d]: %" PRIu32 "\n", i, pa->rev); + fprintf(aft->file_ctx->fp, "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->prio); } char srcip[16], dstip[16]; inet_ntop(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); inet_ntop(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - fprintf(aft->fp, "SRC IP: %s\n", srcip); - fprintf(aft->fp, "DST IP: %s\n", dstip); - fprintf(aft->fp, "PROTO: %" PRIu32 "\n", IPV4_GET_IPPROTO(p)); + fprintf(aft->file_ctx->fp, "SRC IP: %s\n", srcip); + fprintf(aft->file_ctx->fp, "DST IP: %s\n", dstip); + fprintf(aft->file_ctx->fp, "PROTO: %" PRIu32 "\n", IPV4_GET_IPPROTO(p)); if (IPV4_GET_IPPROTO(p) == IPPROTO_TCP || IPV4_GET_IPPROTO(p) == IPPROTO_UDP) { - fprintf(aft->fp, "SRC PORT: %" PRIu32 "\n", p->sp); - fprintf(aft->fp, "DST PORT: %" PRIu32 "\n", p->dp); + fprintf(aft->file_ctx->fp, "SRC PORT: %" PRIu32 "\n", p->sp); + fprintf(aft->file_ctx->fp, "DST PORT: %" PRIu32 "\n", p->dp); } /* flow stuff */ - fprintf(aft->fp, "FLOW: to_server: %s, to_client %s\n", + fprintf(aft->file_ctx->fp, "FLOW: to_server: %s, to_client %s\n", p->flowflags & FLOW_PKT_TOSERVER ? "TRUE" : "FALSE", p->flowflags & FLOW_PKT_TOCLIENT ? "TRUE" : "FALSE"); PktVar *pv = PktVarGet(p,"http_host"); if (pv) { - fprintf(aft->fp, "PKTVAR: %s\n", pv->name); - PrintRawDataFp(aft->fp, pv->value, pv->value_len); + fprintf(aft->file_ctx->fp, "PKTVAR: %s\n", pv->name); + PrintRawDataFp(aft->file_ctx->fp, pv->value, pv->value_len); } pv = PktVarGet(p,"http_ua"); if (pv) { - fprintf(aft->fp, "PKTVAR: %s\n", pv->name); - PrintRawDataFp(aft->fp, pv->value, pv->value_len); + fprintf(aft->file_ctx->fp, "PKTVAR: %s\n", pv->name); + PrintRawDataFp(aft->file_ctx->fp, pv->value, pv->value_len); } for (i = 0; i < p->http_uri.cnt; i++) { - fprintf(aft->fp, "RAW URI [%2d]: ", i); - PrintRawUriFp(aft->fp, p->http_uri.raw[i], p->http_uri.raw_size[i]); - fprintf(aft->fp, "\n"); - PrintRawDataFp(aft->fp, p->http_uri.raw[i], p->http_uri.raw_size[i]); + fprintf(aft->file_ctx->fp, "RAW URI [%2d]: ", i); + PrintRawUriFp(aft->file_ctx->fp, p->http_uri.raw[i], p->http_uri.raw_size[i]); + fprintf(aft->file_ctx->fp, "\n"); + PrintRawDataFp(aft->file_ctx->fp, p->http_uri.raw[i], p->http_uri.raw_size[i]); } /* any stuff */ @@ -127,11 +132,13 @@ int AlertDebuglogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) aft->alerts += p->alerts.cnt; - fprintf(aft->fp, "PACKET LEN: %" PRIu32 "\n", p->pktlen); - fprintf(aft->fp, "PACKET:\n"); - PrintRawDataFp(aft->fp, p->pkt, p->pktlen); + fprintf(aft->file_ctx->fp, "PACKET LEN: %" PRIu32 "\n", p->pktlen); + fprintf(aft->file_ctx->fp, "PACKET:\n"); + PrintRawDataFp(aft->file_ctx->fp, p->pkt, p->pktlen); + + fflush(aft->file_ctx->fp); + mutex_unlock(&aft->file_ctx->fp_mutex); - fflush(aft->fp); return 0; } @@ -148,6 +155,7 @@ int AlertDebuglogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); + mutex_lock(&aft->file_ctx->fp_mutex); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; char srcip[46], dstip[46]; @@ -155,10 +163,11 @@ int AlertDebuglogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) inet_ntop(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); inet_ntop(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - fprintf(aft->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: fixme] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", + fprintf(aft->file_ctx->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: fixme] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", timebuf, pa->gid, pa->sid, pa->rev, pa->msg, pa->prio, IPV6_GET_L4PROTO(p), srcip, p->sp, dstip, p->dp); - fflush(aft->fp); } + fflush(aft->file_ctx->fp); + mutex_unlock(&aft->file_ctx->fp_mutex); return 0; } @@ -182,15 +191,13 @@ int AlertDebuglogThreadInit(ThreadVars *t, void *initdata, void **data) } memset(aft, 0, sizeof(AlertDebuglogThread)); - char log_path[PATH_MAX], *log_dir; - if (ConfGet("default-log-dir", &log_dir) != 1) - log_dir = DEFAULT_LOG_DIR; - snprintf(log_path, PATH_MAX, "%s/%s", log_dir, DEFAULT_LOG_FILENAME); - aft->fp = fopen(log_path, "w"); - if (aft->fp == NULL) { - printf("ERROR: failed to open %s: %s\n", log_path, strerror(errno)); + if(initdata == NULL) + { + printf("Error getting context for the file\n"); return -1; } + /** Use the Ouptut Context (file pointer and mutex) */ + aft->file_ctx=(LogFileCtx *) initdata; *data = (void *)aft; return 0; @@ -203,9 +210,6 @@ int AlertDebuglogThreadDeinit(ThreadVars *t, void *data) return 0; } - if (aft->fp != NULL) - fclose(aft->fp); - /* clear memory */ memset(aft, 0, sizeof(AlertDebuglogThread)); @@ -222,3 +226,66 @@ void AlertDebuglogExitPrintStats(ThreadVars *tv, void *data) { SCLogInfo("(%s) Alerts %" PRIu32 "", tv->name, aft->alerts); } + +/** \brief Create a new file_ctx from config_file (if specified) + * \param config_file for loading separate configs + * \return NULL if failure, LogFileCtx* to the file_ctx if succesful + * */ +LogFileCtx *AlertDebuglogInitCtx(char *config_file) +{ + int ret=0; + LogFileCtx* file_ctx=LogFileNewCtx(); + + if(file_ctx == NULL) + { + printf("AlertDebuglogInitCtx: Couldn't create new file_ctx\n"); + return NULL; + } + + /** fill the new LogFileCtx with the specific AlertDebuglog configuration */ + ret=AlertDebuglogOpenFileCtx(file_ctx, config_file); + + if(ret < 0) + return NULL; + + /** In AlertDebuglogOpenFileCtx the second parameter should be the configuration file to use + * but it's not implemented yet, so passing NULL to load the default + * configuration + */ + + return file_ctx; +} + +/** \brief Read the config set the file pointer, open the file + * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() + * \param config_file for loading separate configs + * \return -1 if failure, 0 if succesful + * */ +int AlertDebuglogOpenFileCtx(LogFileCtx *file_ctx, char *config_file) +{ + int ret=0; + if(config_file == NULL) + { + /** Separate config files not implemented at the moment, + * but it must be able to load from separate config file. + * Load the default configuration. + */ + + char log_path[PATH_MAX], *log_dir; + if (ConfGet("default-log-dir", &log_dir) != 1) + log_dir = DEFAULT_LOG_DIR; + snprintf(log_path, PATH_MAX, "%s/%s", log_dir, DEFAULT_LOG_FILENAME); + file_ctx->fp = fopen(log_path, "w"); + if (file_ctx->fp == NULL) { + printf("ERROR: failed to open %s: %s\n", log_path, strerror(errno)); + return -1; + } + if(file_ctx->config_file == NULL) + file_ctx->config_file = strdup("configfile.ad"); + /** Remember the config file (or NULL if not indicated) */ + } + + return ret; +} + + diff --git a/src/alert-debuglog.h b/src/alert-debuglog.h index 08e50934b2..1bea0075e6 100644 --- a/src/alert-debuglog.h +++ b/src/alert-debuglog.h @@ -6,6 +6,7 @@ void TmModuleAlertDebuglogRegister (void); void TmModuleAlertDebuglogIPv4Register (void); void TmModuleAlertDebuglogIPv6Register (void); +LogFileCtx *AlertDebuglogInitCtx(char *); #endif /* __ALERT_DEBUGLOG_H__ */ diff --git a/src/alert-fastlog.c b/src/alert-fastlog.c index f7a08f76b3..a85783c562 100644 --- a/src/alert-fastlog.c +++ b/src/alert-fastlog.c @@ -18,6 +18,7 @@ #include "flow.h" #include "conf.h" +#include "threads.h" #include "threadvars.h" #include "tm-modules.h" #include "util-debug.h" @@ -31,6 +32,7 @@ int AlertFastlogIPv6(ThreadVars *, Packet *, void *, PacketQueue *); int AlertFastlogThreadInit(ThreadVars *, void *, void **); int AlertFastlogThreadDeinit(ThreadVars *, void *); void AlertFastlogExitPrintStats(ThreadVars *, void *); +int AlertFastlogOpenFileCtx(LogFileCtx *, char *); void TmModuleAlertFastlogRegister (void) { tmm_modules[TMM_ALERTFASTLOG].name = "AlertFastlog"; @@ -60,7 +62,8 @@ void TmModuleAlertFastlogIPv6Register (void) { } typedef struct AlertFastlogThread_ { - FILE *fp; + /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ + LogFileCtx* file_ctx; uint32_t alerts; } AlertFastlogThread; @@ -88,6 +91,8 @@ int AlertFastlogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); + mutex_lock(&aft->file_ctx->fp_mutex); + for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; char srcip[16], dstip[16]; @@ -95,10 +100,12 @@ int AlertFastlogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) inet_ntop(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); inet_ntop(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - fprintf(aft->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: fixme] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", + fprintf(aft->file_ctx->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: fixme] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", timebuf, pa->gid, pa->sid, pa->rev, pa->msg, pa->prio, IPV4_GET_IPPROTO(p), srcip, p->sp, dstip, p->dp); - fflush(aft->fp); } + fflush(aft->file_ctx->fp); + mutex_unlock(&aft->file_ctx->fp_mutex); + return 0; } @@ -115,6 +122,8 @@ int AlertFastlogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); + mutex_lock(&aft->file_ctx->fp_mutex); + for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; char srcip[46], dstip[46]; @@ -122,11 +131,13 @@ int AlertFastlogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) inet_ntop(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); inet_ntop(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - fprintf(aft->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: fixme] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", + fprintf(aft->file_ctx->fp, "%s [**] [%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [**] [Classification: fixme] [Priority: %" PRIu32 "] {%" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", timebuf, pa->gid, pa->sid, pa->rev, pa->msg, pa->prio, IPV6_GET_L4PROTO(p), srcip, p->sp, dstip, p->dp); - fflush(aft->fp); + fflush(aft->file_ctx->fp); } + mutex_unlock(&aft->file_ctx->fp_mutex); + return 0; } @@ -148,17 +159,13 @@ int AlertFastlogThreadInit(ThreadVars *t, void *initdata, void **data) return -1; } memset(aft, 0, sizeof(AlertFastlogThread)); - - char log_path[PATH_MAX], *log_dir; - if (ConfGet("default-log-dir", &log_dir) != 1) - log_dir = DEFAULT_LOG_DIR; - snprintf(log_path, PATH_MAX, "%s/%s", log_dir, DEFAULT_LOG_FILENAME); - aft->fp = fopen(log_path, "w"); - if (aft->fp == NULL) { - printf("ERROR: failed to open %s: %s\n", log_path, strerror(errno)); + if(initdata == NULL) + { + printf("Error getting context for the file\n"); return -1; } - + /** Use the Ouptut Context (file pointer and mutex) */ + aft->file_ctx = (LogFileCtx*) initdata; *data = (void *)aft; return 0; } @@ -170,9 +177,6 @@ int AlertFastlogThreadDeinit(ThreadVars *t, void *data) return 0; } - if (aft->fp != NULL) - fclose(aft->fp); - /* clear memory */ memset(aft, 0, sizeof(AlertFastlogThread)); @@ -189,3 +193,66 @@ void AlertFastlogExitPrintStats(ThreadVars *tv, void *data) { SCLogInfo("(%s) Alerts %" PRIu32 "", tv->name, aft->alerts); } +/** \brief Create a new file_ctx from config_file (if specified) + * \param config_file for loading separate configs + * \return NULL if failure, LogFileCtx* to the file_ctx if succesful + * */ +LogFileCtx *AlertFastlogInitCtx(char *config_file) +{ + int ret=0; + LogFileCtx* file_ctx=LogFileNewCtx(); + + if(file_ctx == NULL) + { + printf("AlertFastlogInitCtx: Couldn't create new file_ctx\n"); + return NULL; + } + + /** fill the new LogFileCtx with the specific AlertFastlog configuration */ + ret=AlertFastlogOpenFileCtx(file_ctx, config_file); + + if(ret < 0) + return NULL; + + /** In AlertFastlogOpenFileCtx the second parameter should be the configuration file to use + * but it's not implemented yet, so passing NULL to load the default + * configuration + */ + + return file_ctx; +} + +/** \brief Read the config set the file pointer, open the file + * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() + * \param config_file for loading separate configs + * \return -1 if failure, 0 if succesful + * */ +int AlertFastlogOpenFileCtx(LogFileCtx *file_ctx, char *config_file) +{ + if(config_file == NULL) + { + /** Separate config files not implemented at the moment, + * but it must be able to load from separate config file. + * Load the default configuration. + */ + + char log_path[PATH_MAX], *log_dir; + if (ConfGet("default-log-dir", &log_dir) != 1) + log_dir = DEFAULT_LOG_DIR; + snprintf(log_path, PATH_MAX, "%s/%s", log_dir, DEFAULT_LOG_FILENAME); + + file_ctx->fp = fopen(log_path, "w"); + + if (file_ctx->fp == NULL) { + printf("ERROR: failed to open %s: %s\n", log_path, strerror(errno)); + return -1; + } + if(file_ctx->config_file == NULL) + file_ctx->config_file = strdup("config.af"); + /** Remember the config file (or NULL if not indicated) */ + } + + return 0; +} + + diff --git a/src/alert-fastlog.h b/src/alert-fastlog.h index 0372172920..9223188232 100644 --- a/src/alert-fastlog.h +++ b/src/alert-fastlog.h @@ -1,11 +1,13 @@ /* Copyright (c) 2008 Victor Julien */ +#include "tm-modules.h" #ifndef __ALERT_FASTLOG_H__ #define __ALERT_FASTLOG_H__ void TmModuleAlertFastlogRegister (void); void TmModuleAlertFastlogIPv4Register (void); void TmModuleAlertFastlogIPv6Register (void); +LogFileCtx *AlertFastlogInitCtx(char *); #endif /* __ALERT_FASTLOG_H__ */ diff --git a/src/alert-unified-alert.c b/src/alert-unified-alert.c index f79b6b74f0..3df12cb466 100644 --- a/src/alert-unified-alert.c +++ b/src/alert-unified-alert.c @@ -18,14 +18,18 @@ #include "flow.h" #include "conf.h" +#include "threads.h" #include "threadvars.h" #include "tm-modules.h" #include "util-unittest.h" +#define DEFAULT_LOG_FILENAME "unified.alert" + int AlertUnifiedAlert (ThreadVars *, Packet *, void *, PacketQueue *); int AlertUnifiedAlertThreadInit(ThreadVars *, void *, void **); int AlertUnifiedAlertThreadDeinit(ThreadVars *, void *); +int AlertUnifiedAlertOpenFileCtx(LogFileCtx *, char *); void TmModuleAlertUnifiedAlertRegister (void) { tmm_modules[TMM_ALERTUNIFIEDALERT].name = "AlertUnifiedAlert"; @@ -36,7 +40,8 @@ void TmModuleAlertUnifiedAlertRegister (void) { } typedef struct AlertUnifiedAlertThread_ { - FILE *fp; + /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ + LogFileCtx* file_ctx; uint32_t size_limit; uint32_t size_current; } AlertUnifiedAlertThread; @@ -75,52 +80,30 @@ typedef struct AlertUnifiedAlertPacketHeader_ { uint32_t flags; } AlertUnifiedAlertPacketHeader; -int AlertUnifiedAlertCreateFile(ThreadVars *t, AlertUnifiedAlertThread *aun) { - char filename[PATH_MAX]; +int AlertUnifiedAlertWriteFileHeader(ThreadVars *t, AlertUnifiedAlertThread *aun) { int ret; - /* get the time so we can have a filename with seconds since epoch - * in it. XXX review if we can take this info from somewhere else. - * This is used both during init and runtime, so it must be thread - * safe. */ - struct timeval ts; - memset (&ts, 0, sizeof(struct timeval)); - gettimeofday(&ts, NULL); - - /* create the filename to use */ - char *log_dir; - if (ConfGet("default-log-dir", &log_dir) != 1) - log_dir = DEFAULT_LOG_DIR; - snprintf(filename, sizeof(filename), "%s/%s.%" PRIu32, log_dir, "unified.alert", (uint32_t)ts.tv_sec); - - /* XXX filename & location */ - aun->fp = fopen(filename, "wb"); - if (aun->fp == NULL) { - printf("Error: fopen %s failed: %s\n", filename, strerror(errno)); /* XXX errno threadsafety? */ - return -1; - } - - /* write the fileheader to the file so the reader can recognize it */ + /** write the fileheader to the file so the reader can recognize it */ AlertUnifiedAlertFileHeader hdr; hdr.magic = ALERTUNIFIEDALERT_ALERTMAGIC; hdr.ver_major = ALERTUNIFIEDALERT_VERMAJOR; hdr.ver_minor = ALERTUNIFIEDALERT_VERMINOR; hdr.timezone = 0; /* XXX */ - ret = fwrite(&hdr, sizeof(hdr), 1, aun->fp); + ret = fwrite(&hdr, sizeof(hdr), 1, aun->file_ctx->fp); if (ret != 1) { printf("Error: fwrite failed: ret = %" PRId32 ", %s\n", ret, strerror(errno)); return -1; } - fflush(aun->fp); + fflush(aun->file_ctx->fp); aun->size_current = sizeof(hdr); return 0; } int AlertUnifiedAlertCloseFile(ThreadVars *t, AlertUnifiedAlertThread *aun) { - if (aun->fp != NULL) - fclose(aun->fp); + if (aun->file_ctx->fp != NULL) + fclose(aun->file_ctx->fp); return 0; } @@ -130,8 +113,12 @@ int AlertUnifiedAlertRotateFile(ThreadVars *t, AlertUnifiedAlertThread *aun) { printf("Error: AlertUnifiedAlertCloseFile failed\n"); return -1; } - if (AlertUnifiedAlertCreateFile(t, aun) < 0) { - printf("Error: AlertUnifiedCreateFile failed\n"); + if (AlertUnifiedAlertOpenFileCtx(aun->file_ctx,aun->file_ctx->config_file) < 0) { + printf("Error: AlertUnifiedLogOpenFileCtx, open new log file failed\n"); + return -1; + } + if (AlertUnifiedAlertWriteFileHeader(t, aun) < 0) { + printf("Error: AlertUnifiedLogAppendFile, write unified header failed\n"); return -1; } @@ -155,11 +142,16 @@ int AlertUnifiedAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) ethh_offset = sizeof(EthernetHdr); } - /* check and enforce the filesize limit */ + /** check and enforce the filesize limit, thread safe */ + mutex_lock(&aun->file_ctx->fp_mutex); if ((aun->size_current + sizeof(hdr)) > aun->size_limit) { if (AlertUnifiedAlertRotateFile(tv,aun) < 0) + { + mutex_unlock(&aun->file_ctx->fp_mutex); return -1; + } } + mutex_unlock(&aun->file_ctx->fp_mutex); /* XXX which one to add to this alert? Lets see how Snort solves this. * For now just take last alert. */ @@ -183,14 +175,14 @@ int AlertUnifiedAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) hdr.flags = 0; /* write and flush so it's written immediately */ - ret = fwrite(&hdr, sizeof(hdr), 1, aun->fp); + ret = fwrite(&hdr, sizeof(hdr), 1, aun->file_ctx->fp); if (ret != 1) { printf("Error: fwrite failed: %s\n", strerror(errno)); return -1; } /* force writing to disk so barnyard will not read half * written records and choke. */ - fflush(aun->fp); + fflush(aun->file_ctx->fp); aun->size_current += sizeof(hdr); return 0; @@ -204,11 +196,18 @@ int AlertUnifiedAlertThreadInit(ThreadVars *t, void *initdata, void **data) } memset(aun, 0, sizeof(AlertUnifiedAlertThread)); - aun->fp = NULL; + if(initdata == NULL) + { + printf("Error getting context for the file\n"); + return -1; + } + /** Use the Ouptut Context (file pointer and mutex) */ + aun->file_ctx = (LogFileCtx*) initdata; - int ret = AlertUnifiedAlertCreateFile(t, aun); + /** Write Unified header */ + int ret = AlertUnifiedAlertWriteFileHeader(t, aun); if (ret != 0) { - printf("Error: AlertUnifiedCreateFile failed.\n"); + printf("Error: AlertUnifiedLogWriteFileHeader failed.\n"); return -1; } @@ -226,9 +225,6 @@ int AlertUnifiedAlertThreadDeinit(ThreadVars *t, void *data) goto error; } - if (AlertUnifiedAlertCloseFile(t, aun) < 0) - goto error; - /* clear memory */ memset(aun, 0, sizeof(AlertUnifiedAlertThread)); free(aun); @@ -243,3 +239,80 @@ error: return -1; } + +/** \brief Create a new file_ctx from config_file (if specified) + * \param config_file for loading separate configs + * \return NULL if failure, LogFileCtx* to the file_ctx if succesful + * */ +LogFileCtx *AlertUnifiedAlertInitCtx(char *config_file) +{ + int ret=0; + LogFileCtx* file_ctx=LogFileNewCtx(); + + if(file_ctx == NULL) + { + printf("AlertUnifiedAlertInitCtx: Couldn't create new file_ctx\n"); + return NULL; + } + + /** fill the new LogFileCtx with the specific AlertUnifiedAlert configuration */ + ret=AlertUnifiedAlertOpenFileCtx(file_ctx, config_file); + + if(ret < 0) + return NULL; + + /** In AlertUnifiedAlertOpenFileCtx the second parameter should be the configuration file to use + * but it's not implemented yet, so passing NULL to load the default + * configuration + */ + + return file_ctx; +} + +/** \brief Read the config set the file pointer, open the file + * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() + * \param config_file for loading separate configs + * \return -1 if failure, 0 if succesful + * */ +int AlertUnifiedAlertOpenFileCtx(LogFileCtx *file_ctx, char *config_file) +{ + char filename[PATH_MAX]; /* XXX some sane default? */ + + if(config_file == NULL) + { + /** Separate config files not implemented at the moment, + * but it must be able to load from separate config file. + * Load the default configuration. + */ + + /* get the time so we can have a filename with seconds since epoch + * in it. XXX review if we can take this info from somewhere else. + * This is used both during init and runtime, so it must be thread + * safe. */ + struct timeval ts; + memset (&ts, 0, sizeof(struct timeval)); + gettimeofday(&ts, NULL); + + /* create the filename to use */ + char *log_dir; + if (ConfGet("default-log-dir", &log_dir) != 1) + log_dir = DEFAULT_LOG_DIR; + snprintf(filename, sizeof(filename), "%s/%s.%" PRIu32, log_dir, "unified.alert", (uint32_t)ts.tv_sec); + + /* XXX filename & location */ + file_ctx->fp = fopen(filename, "wb"); + if (file_ctx->fp == NULL) { + printf("Error: fopen %s failed: %s\n", filename, strerror(errno)); /* XXX errno threadsafety? */ + return -1; + } + + if(file_ctx->config_file == NULL) + file_ctx->config_file = strdup("configfile.aua"); + /** Remember the config file (or NULL if not indicated) */ + + } + + return 0; +} + + diff --git a/src/alert-unified-alert.h b/src/alert-unified-alert.h index e554383e11..29946b9e27 100644 --- a/src/alert-unified-alert.h +++ b/src/alert-unified-alert.h @@ -4,6 +4,7 @@ #define __ALERT_UNIFIED_ALERT_H__ void TmModuleAlertUnifiedAlertRegister (void); +LogFileCtx *AlertUnifiedAlertInitCtx(char *); #endif /* __ALERT_UNIFIED_ALERT_H__ */ diff --git a/src/alert-unified-log.c b/src/alert-unified-log.c index cd14effa03..055a063fe9 100644 --- a/src/alert-unified-log.c +++ b/src/alert-unified-log.c @@ -18,14 +18,18 @@ #include "flow.h" #include "conf.h" +#include "threads.h" #include "threadvars.h" #include "tm-modules.h" #include "util-unittest.h" +#define DEFAULT_LOG_FILENAME "unified.log" + int AlertUnifiedLog (ThreadVars *, Packet *, void *, PacketQueue *); int AlertUnifiedLogThreadInit(ThreadVars *, void *, void **); int AlertUnifiedLogThreadDeinit(ThreadVars *, void *); +int AlertUnifiedLogOpenFileCtx(LogFileCtx *, char *); void TmModuleAlertUnifiedLogRegister (void) { tmm_modules[TMM_ALERTUNIFIEDLOG].name = "AlertUnifiedLog"; @@ -36,7 +40,8 @@ void TmModuleAlertUnifiedLogRegister (void) { } typedef struct AlertUnifiedLogThread_ { - FILE *fp; + /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ + LogFileCtx* file_ctx; uint32_t size_limit; uint32_t size_current; } AlertUnifiedLogThread; @@ -77,32 +82,10 @@ typedef struct AlertUnifiedLogPacketHeader_ { uint32_t pktlen; } AlertUnifiedLogPacketHeader; -int AlertUnifiedLogCreateFile(ThreadVars *t, AlertUnifiedLogThread *aun) { - char filename[PATH_MAX]; /* XXX some sane default? */ +int AlertUnifiedLogWriteFileHeader(ThreadVars *t, AlertUnifiedLogThread *aun) { int ret; - - /* get the time so we can have a filename with seconds since epoch - * in it. XXX review if we can take this info from somewhere else. - * This is used both during init and runtime, so it must be thread - * safe. */ - struct timeval ts; - memset (&ts, 0, sizeof(struct timeval)); - gettimeofday(&ts, NULL); - - /* create the filename to use */ - char *log_dir; - if (ConfGet("default-log-dir", &log_dir) != 1) - log_dir = DEFAULT_LOG_DIR; - snprintf(filename, sizeof(filename), "%s/%s.%" PRIu32, log_dir, "unified.log", (uint32_t)ts.tv_sec); - - /* XXX filename & location */ - aun->fp = fopen(filename, "wb"); - if (aun->fp == NULL) { - printf("Error: fopen %s failed: %s\n", filename, strerror(errno)); /* XXX errno threadsafety? */ - return -1; - } - /* write the fileheader to the file so the reader can recognize it */ + AlertUnifiedLogFileHeader hdr; hdr.magic = ALERTUNIFIEDLOG_LOGMAGIC; hdr.ver_major = ALERTUNIFIEDLOG_VERMAJOR; @@ -112,7 +95,7 @@ int AlertUnifiedLogCreateFile(ThreadVars *t, AlertUnifiedLogThread *aun) { hdr.snaplen = 65536; /* XXX */ hdr.linktype = DLT_EN10MB; /* XXX */ - ret = fwrite(&hdr, sizeof(hdr), 1, aun->fp); + ret = fwrite(&hdr, sizeof(hdr), 1, aun->file_ctx->fp); if (ret != 1) { printf("Error: fwrite failed: ret = %" PRId32 ", %s\n", ret, strerror(errno)); return -1; @@ -123,8 +106,8 @@ int AlertUnifiedLogCreateFile(ThreadVars *t, AlertUnifiedLogThread *aun) { } int AlertUnifiedLogCloseFile(ThreadVars *t, AlertUnifiedLogThread *aun) { - if (aun->fp != NULL) - fclose(aun->fp); + if (aun->file_ctx->fp != NULL) + fclose(aun->file_ctx->fp); return 0; } @@ -133,8 +116,12 @@ int AlertUnifiedLogRotateFile(ThreadVars *t, AlertUnifiedLogThread *aun) { printf("Error: AlertUnifiedLogCloseFile failed\n"); return -1; } - if (AlertUnifiedLogCreateFile(t, aun) < 0) { - printf("Error: AlertUnifiedCreateFile failed\n"); + if (AlertUnifiedLogOpenFileCtx(aun->file_ctx,aun->file_ctx->config_file) < 0) { + printf("Error: AlertUnifiedLogOpenFileCtx, open new log file failed\n"); + return -1; + } + if (AlertUnifiedLogWriteFileHeader(t, aun) < 0) { + printf("Error: AlertUnifiedLogAppendFile, write unified header failed\n"); return -1; } return 0; @@ -160,10 +147,17 @@ int AlertUnifiedLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) } /* check and enforce the filesize limit */ + /** Wait for the mutex. We dont want all the threads rotating the file + * at the same time :) */ + mutex_lock(&aun->file_ctx->fp_mutex); if ((aun->size_current + sizeof(hdr) + p->pktlen + ethh_offset) > aun->size_limit) { if (AlertUnifiedLogRotateFile(tv,aun) < 0) + { + mutex_unlock(&aun->file_ctx->fp_mutex); return -1; + } } + mutex_unlock(&aun->file_ctx->fp_mutex); /* XXX which one to add to this alert? Lets see how Snort solves this. * For now just take last alert. */ @@ -197,15 +191,15 @@ int AlertUnifiedLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) memcpy(buf+buflen,&p->pkt,p->pktlen); buflen += p->pktlen; - /* write and flush so it's written immediately */ - ret = fwrite(buf, buflen, 1, aun->fp); + /** write and flush so it's written immediately, no need to lock her, no need to lock heree */ + ret = fwrite(buf, buflen, 1, aun->file_ctx->fp); if (ret != 1) { printf("Error: fwrite failed: %s\n", strerror(errno)); return -1; } /* force writing to disk so barnyard will not read half * written records and choke. */ - fflush(aun->fp); + fflush(aun->file_ctx->fp); aun->size_current += buflen; return 0; @@ -218,12 +212,18 @@ int AlertUnifiedLogThreadInit(ThreadVars *t, void *initdata, void **data) return -1; } memset(aun, 0, sizeof(AlertUnifiedLogThread)); + if(initdata == NULL) + { + printf("Error getting context for the file\n"); + return -1; + } + /** Use the Ouptut Context (file pointer and mutex) */ + aun->file_ctx = (LogFileCtx*) initdata; - aun->fp = NULL; - - int ret = AlertUnifiedLogCreateFile(t, aun); + /** Write Unified header */ + int ret = AlertUnifiedLogWriteFileHeader(t, aun); if (ret != 0) { - printf("Error: AlertUnifiedCreateFile failed.\n"); + printf("Error: AlertUnifiedLogWriteFileHeader failed.\n"); return -1; } @@ -241,9 +241,6 @@ int AlertUnifiedLogThreadDeinit(ThreadVars *t, void *data) goto error; } - if (AlertUnifiedLogCloseFile(t, aun) < 0) - goto error; - /* clear memory */ memset(aun, 0, sizeof(AlertUnifiedLogThread)); free(aun); @@ -259,3 +256,80 @@ error: return -1; } + +/** \brief Create a new file_ctx from config_file (if specified) + * \param config_file for loading separate configs + * \return NULL if failure, LogFileCtx* to the file_ctx if succesful + * */ +LogFileCtx *AlertUnifiedLogInitCtx(char *config_file) +{ + int ret=0; + LogFileCtx* file_ctx=LogFileNewCtx(); + + if(file_ctx == NULL) + { + printf("AlertUnifiedLogInitCtx: Couldn't create new file_ctx\n"); + return NULL; + } + + /** fill the new LogFileCtx with the specific AlertUnifiedLog configuration */ + ret=AlertUnifiedLogOpenFileCtx(file_ctx, config_file); + + if(ret < 0) + return NULL; + + /** In AlertUnifiedLogOpenFileCtx the second parameter should be the configuration file to use + * but it's not implemented yet, so passing NULL to load the default + * configuration + */ + + return file_ctx; +} + +/** \brief Read the config set the file pointer, open the file + * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() + * \param config_file for loading separate configs + * \return -1 if failure, 0 if succesful + * */ +int AlertUnifiedLogOpenFileCtx(LogFileCtx *file_ctx, char *config_file) +{ + char filename[PATH_MAX]; /* XXX some sane default? */ + + if(config_file == NULL) + { + /** Separate config files not implemented at the moment, + * but it must be able to load from separate config file. + * Load the default configuration. + */ + + /* get the time so we can have a filename with seconds since epoch + * in it. XXX review if we can take this info from somewhere else. + * This is used both during init and runtime, so it must be thread + * safe. */ + struct timeval ts; + memset (&ts, 0, sizeof(struct timeval)); + gettimeofday(&ts, NULL); + + /* create the filename to use */ + char *log_dir; + if (ConfGet("default-log-dir", &log_dir) != 1) + log_dir = DEFAULT_LOG_DIR; + snprintf(filename, sizeof(filename), "%s/%s.%" PRIu32, log_dir, "unified.log", (uint32_t)ts.tv_sec); + + /* XXX filename & location */ + file_ctx->fp = fopen(filename, "wb"); + if (file_ctx->fp == NULL) { + printf("Error: fopen %s failed: %s\n", filename, strerror(errno)); /* XXX errno threadsafety? */ + return -1; + } + + if(file_ctx->config_file == NULL) + file_ctx->config_file = strdup("configfile.aul"); + /** Remember the config file (or NULL if not indicated) */ + + } + + return 0; +} + + diff --git a/src/alert-unified-log.h b/src/alert-unified-log.h index 6ff7f4e11a..df8720b5fa 100644 --- a/src/alert-unified-log.h +++ b/src/alert-unified-log.h @@ -4,6 +4,7 @@ #define __ALERT_UNIFIED_LOG_H__ void TmModuleAlertUnifiedLogRegister (void); +LogFileCtx *AlertUnifiedLogInitCtx(char *); #endif /* __ALERT_UNIFIED_LOG_H__ */ diff --git a/src/alert-unified2-alert.c b/src/alert-unified2-alert.c index 32334c82dc..571ea200af 100644 --- a/src/alert-unified2-alert.c +++ b/src/alert-unified2-alert.c @@ -10,6 +10,7 @@ #include "flow.h" #include "conf.h" +#include "threads.h" #include "threadvars.h" #include "tm-modules.h" @@ -27,6 +28,7 @@ int Unified2IPv4TypeAlert(ThreadVars *, Packet *, void *, PacketQueue *); int Unified2IPv6TypeAlert(ThreadVars *, Packet *, void *, PacketQueue *); int Unified2PacketTypeAlert(ThreadVars *, Packet *, void *); void Unified2RegisterTests(); +int Unified2AlertOpenFileCtx(LogFileCtx *, char *); /** * Unified2 thread vars @@ -34,7 +36,7 @@ void Unified2RegisterTests(); * Used for storing file options. */ typedef struct Unified2AlertThread_ { - FILE *fp; /**< file pointer */ + LogFileCtx *file_ctx; /** LogFileCtx pointer */ uint32_t size_limit; /**< file size limit */ uint32_t size_current; /**< file current size */ } Unified2AlertThread; @@ -162,8 +164,8 @@ int Unified2AlertCreateFile(ThreadVars *t, Unified2AlertThread *aun) { */ int Unified2AlertCloseFile(ThreadVars *t, Unified2AlertThread *aun) { - if (aun->fp != NULL) - fclose(aun->fp); + if (aun->file_ctx->fp != NULL) + fclose(aun->file_ctx->fp); return 0; } @@ -182,25 +184,13 @@ int Unified2AlertRotateFile(ThreadVars *t, Unified2AlertThread *aun) { printf("Error: Unified2AlertCloseFile failed\n"); return -1; } - if (Unified2AlertCreateFile(t, aun) < 0) { - printf("Error: AlertUnified2CreateFile failed\n"); + if (Unified2AlertOpenFileCtx(aun->file_ctx,aun->file_ctx->config_file) < 0) { + printf("Error: Unified2AlertOpenFileCtx, open new log file failed\n"); return -1; } - return 0; } -/** - * \brief Function to create unified2 file - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param p Packet struct used to decide for ipv4 or ipv6 - * \param data Unified2 thread data. - * \param pq Packet queue - * \retval 0 on succces - * \retval -1 on failure - */ - int Unified2Alert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq) { if(PKT_IS_IPV4(p)) { @@ -249,10 +239,15 @@ int Unified2PacketTypeAlert (ThreadVars *t, Packet *p, void *data) memcpy(write_buffer,&hdr,sizeof(Unified2AlertFileHeader)); + mutex_lock(&aun->file_ctx->fp_mutex); if ((aun->size_current + (sizeof(hdr) + sizeof(phdr))) > aun->size_limit) { if (Unified2AlertRotateFile(t,aun) < 0) + { + mutex_unlock(&aun->file_ctx->fp_mutex); return -1; + } } + mutex_unlock(&aun->file_ctx->fp_mutex); phdr.sensor_id = 0; phdr.linktype = htonl(p->datalink); @@ -264,13 +259,13 @@ int Unified2PacketTypeAlert (ThreadVars *t, Packet *p, void *data) memcpy(write_buffer+sizeof(Unified2AlertFileHeader),&phdr,sizeof(Unified2Packet) - 4); memcpy(write_buffer + sizeof(Unified2AlertFileHeader) + sizeof(Unified2Packet) - 4 , p->pkt, p->pktlen); - ret = fwrite(write_buffer,len, 1, aun->fp); + ret = fwrite(write_buffer,len, 1, aun->file_ctx->fp); if (ret != 1) { printf("Error: fwrite failed: %s\n", strerror(errno)); return -1; } - fflush(aun->fp); + fflush(aun->file_ctx->fp); aun->size_current += len; return 0; @@ -319,10 +314,15 @@ int Unified2IPv6TypeAlert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq } /* check and enforce the filesize limit */ + mutex_lock(&aun->file_ctx->fp_mutex); if ((aun->size_current +(sizeof(hdr) + sizeof(phdr))) > aun->size_limit) { if (Unified2AlertRotateFile(t,aun) < 0) + { + mutex_unlock(&aun->file_ctx->fp_mutex); return -1; + } } + mutex_unlock(&aun->file_ctx->fp_mutex); /* XXX which one to add to this alert? Lets see how Snort solves this. * For now just take last alert. */ @@ -369,13 +369,13 @@ int Unified2IPv6TypeAlert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq memcpy(write_buffer+sizeof(Unified2AlertFileHeader),&phdr,sizeof(AlertIPv6Unified2)); - ret = fwrite(write_buffer,len, 1, aun->fp); + ret = fwrite(write_buffer,len, 1, aun->file_ctx->fp); if (ret != 1) { printf("Error: fwrite failed: %s\n", strerror(errno)); return -1; } - fflush(aun->fp); + fflush(aun->file_ctx->fp); aun->size_current += len; Unified2PacketTypeAlert(t, p, data); @@ -425,10 +425,15 @@ int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *p } /* check and enforce the filesize limit */ + mutex_lock(&aun->file_ctx->fp_mutex); if ((aun->size_current +(sizeof(hdr) + sizeof(phdr))) > aun->size_limit) { if (Unified2AlertRotateFile(tv,aun) < 0) + { + mutex_unlock(&aun->file_ctx->fp_mutex); return -1; + } } + mutex_unlock(&aun->file_ctx->fp_mutex); /* XXX which one to add to this alert? Lets see how Snort solves this. * For now just take last alert. */ @@ -475,13 +480,13 @@ int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *p memcpy(write_buffer+sizeof(Unified2AlertFileHeader),&phdr,sizeof(AlertIPv4Unified2)); - ret = fwrite(write_buffer,len, 1, aun->fp); + ret = fwrite(write_buffer,len, 1, aun->file_ctx->fp); if (ret != 1) { printf("Error: fwrite failed: %s\n", strerror(errno)); return -1; } - fflush(aun->fp); + fflush(aun->file_ctx->fp); aun->size_current += len; Unified2PacketTypeAlert(tv, p, data); @@ -501,21 +506,18 @@ int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *p int Unified2AlertThreadInit(ThreadVars *t, void *initdata, void **data) { - int ret; - Unified2AlertThread *aun = malloc(sizeof(Unified2AlertThread)); if (aun == NULL) { return -1; } memset(aun, 0, sizeof(Unified2AlertThread)); - - aun->fp = NULL; - - ret = Unified2AlertCreateFile(t, aun); - if (ret != 0) { - printf("Error: AlertUnified2CreateFile failed.\n"); + if(initdata == NULL) + { + printf("Error getting context for the file\n"); return -1; } + /** Use the Ouptut Context (file pointer and mutex) */ + aun->file_ctx = (LogFileCtx*) initdata; /* XXX make configurable */ aun->size_limit = 10 * 1024 * 1024; @@ -540,9 +542,6 @@ int Unified2AlertThreadDeinit(ThreadVars *t, void *data) goto error; } - if (Unified2AlertCloseFile(t, aun) < 0) - goto error; - /* clear memory */ memset(aun, 0, sizeof(Unified2AlertThread)); free(aun); @@ -557,6 +556,82 @@ error: return -1; } +/** \brief Create a new file_ctx from config_file (if specified) + * \param config_file for loading separate configs + * \return NULL if failure, LogFileCtx* to the file_ctx if succesful + * */ +LogFileCtx *Unified2AlertInitCtx(char *config_file) +{ + int ret=0; + LogFileCtx* file_ctx=LogFileNewCtx(); + + if(file_ctx == NULL) + { + printf("Unified2AlertInitCtx: Couldn't create new file_ctx\n"); + return NULL; + } + + /** fill the new LogFileCtx with the specific Unified2Alert configuration */ + ret=Unified2AlertOpenFileCtx(file_ctx, config_file); + + if(ret < 0) + return NULL; + + /** In Unified2AlertOpenFileCtx the second parameter should be the configuration file to use + * but it's not implemented yet, so passing NULL to load the default + * configuration + */ + + return file_ctx; +} + +/** \brief Read the config set the file pointer, open the file + * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() + * \param config_file for loading separate configs + * \return -1 if failure, 0 if succesful + * */ +int Unified2AlertOpenFileCtx(LogFileCtx *file_ctx, char *config_file) +{ + char filename[PATH_MAX]; /* XXX some sane default? */ + + if(config_file == NULL) + { + /** Separate config files not implemented at the moment, + * but it must be able to load from separate config file. + * Load the default configuration. + */ + + /** get the time so we can have a filename with seconds since epoch + * in it. XXX review if we can take this info from somewhere else. + * This is used both during init and runtime, so it must be thread + * safe. */ + struct timeval ts; + memset (&ts, 0, sizeof(struct timeval)); + gettimeofday(&ts, NULL); + + /* create the filename to use */ + char *log_dir; + if (ConfGet("default-log-dir", &log_dir) != 1) + log_dir = DEFAULT_LOG_DIR; + snprintf(filename, sizeof(filename), "%s/%s.%" PRIu32, log_dir, "unified2.alert", (uint32_t)ts.tv_sec); + + /* XXX filename & location */ + file_ctx->fp = fopen(filename, "wb"); + if (file_ctx->fp == NULL) { + printf("Error: fopen %s failed: %s\n", filename, strerror(errno)); /* XXX errno threadsafety? */ + return -1; + } + + if(file_ctx->config_file == NULL) + file_ctx->config_file = strdup("configfile.au2a"); + /** Remember the config file (or NULL if not indicated) */ + + } + + return 0; +} + + #ifdef UNITTESTS ThreadVars tv; diff --git a/src/alert-unified2-alert.h b/src/alert-unified2-alert.h index 48a44c28ec..9f79c82e40 100644 --- a/src/alert-unified2-alert.h +++ b/src/alert-unified2-alert.h @@ -22,6 +22,7 @@ #define UNIFIED2_IDS_EVENT_IPV6_MPLS_TYPE 100 void TmModuleUnified2AlertRegister (void); +LogFileCtx *Unified2AlertInitCtx(char *); #endif /* __ALERT_UNIFIED2_ALERT_H__ */ diff --git a/src/eidps.c b/src/eidps.c index dcee4a19dd..33eaaaf8ca 100644 --- a/src/eidps.c +++ b/src/eidps.c @@ -464,6 +464,16 @@ int main(int argc, char **argv) DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + /** Create file contexts for output modules */ + /* ascii */ + LogFileCtx *af_logfile_ctx = AlertFastlogInitCtx(NULL); + LogFileCtx *ad_logfile_ctx = AlertDebuglogInitCtx(NULL); + LogFileCtx *lh_logfile_ctx = LogHttplogInitCtx(NULL); + /* unified */ + LogFileCtx *aul_logfile_ctx = AlertUnifiedLogInitCtx(NULL); + LogFileCtx *aua_logfile_ctx = AlertUnifiedAlertInitCtx(NULL); + LogFileCtx *au2a_logfile_ctx = Unified2AlertInitCtx(NULL); + if (SigLoadSignatures(de_ctx, sig_file) < 0) { printf("ERROR: loading signatures failed.\n"); exit(EXIT_FAILURE); @@ -474,13 +484,13 @@ int main(int argc, char **argv) gettimeofday(&start_time, NULL); if (mode == MODE_PCAP_DEV) { - //RunModeIdsPcap3(de_ctx, pcap_dev); - RunModeIdsPcap2(de_ctx, pcap_dev); - //RunModeIdsPcap(de_ctx, pcap_dev); + //RunModeIdsPcap3(de_ctx, pcap_dev, af_logfile_ctx, ad_logfile_ctx, lh_logfile_ctx, aul_logfile_ctx, aua_logfile_ctx, au2a_logfile_ctx); + RunModeIdsPcap2(de_ctx, pcap_dev, af_logfile_ctx, ad_logfile_ctx, lh_logfile_ctx, aul_logfile_ctx, aua_logfile_ctx, au2a_logfile_ctx); + //RunModeIdsPcap(de_ctx, pcap_dev, af_logfile_ctx, ad_logfile_ctx, lh_logfile_ctx, aul_logfile_ctx, aua_logfile_ctx, au2a_logfile_ctx); } else if (mode == MODE_PCAP_FILE) { - RunModeFilePcap(de_ctx, pcap_file); - //RunModeFilePcap2(de_ctx, pcap_file); + RunModeFilePcap(de_ctx, pcap_file, af_logfile_ctx, ad_logfile_ctx, lh_logfile_ctx, aul_logfile_ctx, aua_logfile_ctx, au2a_logfile_ctx); + //RunModeFilePcap2(de_ctx, pcap_file, af_logfile_ctx, ad_logfile_ctx, lh_logfile_ctx, aul_logfile_ctx, aua_logfile_ctx, au2a_logfile_ctx); } else if (mode == MODE_PFRING) { //RunModeIdsPfring(de_ctx, pfring_dev); @@ -488,7 +498,7 @@ int main(int argc, char **argv) //RunModeIdsPfring3(de_ctx, pfring_dev); } else if (mode == MODE_NFQ) { - RunModeIpsNFQ(de_ctx); + RunModeIpsNFQ(de_ctx, af_logfile_ctx, ad_logfile_ctx, lh_logfile_ctx, aul_logfile_ctx, aua_logfile_ctx, au2a_logfile_ctx); } else { printf("ERROR: Unknown runtime mode.\n"); @@ -574,5 +584,13 @@ int main(int argc, char **argv) SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); + /** Destroy file contexts for output modules */ + LogFileFreeCtx(af_logfile_ctx); + LogFileFreeCtx(lh_logfile_ctx); + LogFileFreeCtx(ad_logfile_ctx); + LogFileFreeCtx(aul_logfile_ctx); + LogFileFreeCtx(aua_logfile_ctx); + LogFileFreeCtx(au2a_logfile_ctx); + exit(EXIT_SUCCESS); } diff --git a/src/log-httplog.c b/src/log-httplog.c index cc50649b09..64bccb187b 100644 --- a/src/log-httplog.c +++ b/src/log-httplog.c @@ -28,6 +28,7 @@ int LogHttplogIPv6(ThreadVars *, Packet *, void *, PacketQueue *); int LogHttplogThreadInit(ThreadVars *, void *, void **); int LogHttplogThreadDeinit(ThreadVars *, void *); void LogHttplogExitPrintStats(ThreadVars *, void *); +int LogHttplogOpenFileCtx(LogFileCtx* , char *); void TmModuleLogHttplogRegister (void) { tmm_modules[TMM_LOGHTTPLOG].name = "LogHttplog"; @@ -57,7 +58,8 @@ void TmModuleLogHttplogIPv6Register (void) { } typedef struct LogHttplogThread_ { - FILE *fp; + LogFileCtx *file_ctx; + /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ uint32_t uri_cnt; } LogHttplogThread; @@ -91,23 +93,25 @@ int LogHttplogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) inet_ntop(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); inet_ntop(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); + mutex_lock(&aft->file_ctx->fp_mutex); for (i = 0; i < p->http_uri.cnt; i++) { /* time */ - fprintf(aft->fp, "%s ", timebuf); + fprintf(aft->file_ctx->fp, "%s ", timebuf); /* hostname */ - if (pv_hn != NULL) PrintRawUriFp(aft->fp, pv_hn->value, pv_hn->value_len); - else fprintf(aft->fp, ""); - fprintf(aft->fp, " [**] "); + if (pv_hn != NULL) PrintRawUriFp(aft->file_ctx->fp, pv_hn->value, pv_hn->value_len); + else fprintf(aft->file_ctx->fp, ""); + fprintf(aft->file_ctx->fp, " [**] "); /* uri */ - PrintRawUriFp(aft->fp, p->http_uri.raw[i], p->http_uri.raw_size[i]); - fprintf(aft->fp, " [**] "); + PrintRawUriFp(aft->file_ctx->fp, p->http_uri.raw[i], p->http_uri.raw_size[i]); + fprintf(aft->file_ctx->fp, " [**] "); /* user agent */ - if (pv_ua != NULL) PrintRawUriFp(aft->fp, pv_ua->value, pv_ua->value_len); - else fprintf(aft->fp, ""); + if (pv_ua != NULL) PrintRawUriFp(aft->file_ctx->fp, pv_ua->value, pv_ua->value_len); + else fprintf(aft->file_ctx->fp, ""); /* ip/tcp header info */ - fprintf(aft->fp, " [**] %s:%" PRIu32 " -> %s:%" PRIu32 "\n", srcip, p->sp, dstip, p->dp); + fprintf(aft->file_ctx->fp, " [**] %s:%" PRIu32 " -> %s:%" PRIu32 "\n", srcip, p->sp, dstip, p->dp); } - fflush(aft->fp); + fflush(aft->file_ctx->fp); + mutex_unlock(&aft->file_ctx->fp_mutex); aft->uri_cnt += p->http_uri.cnt; return 0; @@ -132,23 +136,25 @@ int LogHttplogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) inet_ntop(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); inet_ntop(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); + mutex_lock(&aft->file_ctx->fp_mutex); for (i = 0; i < p->http_uri.cnt; i++) { /* time */ - fprintf(aft->fp, "%s ", timebuf); + fprintf(aft->file_ctx->fp, "%s ", timebuf); /* hostname */ - if (pv_hn != NULL) PrintRawUriFp(aft->fp, pv_hn->value, pv_hn->value_len); - else fprintf(aft->fp, ""); - fprintf(aft->fp, " [**] "); + if (pv_hn != NULL) PrintRawUriFp(aft->file_ctx->fp, pv_hn->value, pv_hn->value_len); + else fprintf(aft->file_ctx->fp, ""); + fprintf(aft->file_ctx->fp, " [**] "); /* uri */ - PrintRawUriFp(aft->fp, p->http_uri.raw[i], p->http_uri.raw_size[i]); - fprintf(aft->fp, " [**] "); + PrintRawUriFp(aft->file_ctx->fp, p->http_uri.raw[i], p->http_uri.raw_size[i]); + fprintf(aft->file_ctx->fp, " [**] "); /* user agent */ - if (pv_ua != NULL) PrintRawUriFp(aft->fp, pv_ua->value, pv_ua->value_len); - else fprintf(aft->fp, ""); + if (pv_ua != NULL) PrintRawUriFp(aft->file_ctx->fp, pv_ua->value, pv_ua->value_len); + else fprintf(aft->file_ctx->fp, ""); /* ip/tcp header info */ - fprintf(aft->fp, " [**] %s:%" PRIu32 " -> %s:%" PRIu32 "\n", srcip, p->sp, dstip, p->dp); + fprintf(aft->file_ctx->fp, " [**] %s:%" PRIu32 " -> %s:%" PRIu32 "\n", srcip, p->sp, dstip, p->dp); } - fflush(aft->fp); + fflush(aft->file_ctx->fp); + mutex_unlock(&aft->file_ctx->fp_mutex); aft->uri_cnt += p->http_uri.cnt; return 0; @@ -176,15 +182,13 @@ int LogHttplogThreadInit(ThreadVars *t, void *initdata, void **data) } memset(aft, 0, sizeof(LogHttplogThread)); - char log_path[PATH_MAX], *log_dir; - if (ConfGet("default-log-dir", &log_dir) != 1) - log_dir = DEFAULT_LOG_DIR; - snprintf(log_path, PATH_MAX, "%s/%s", log_dir, DEFAULT_LOG_FILENAME); - aft->fp = fopen(log_path, "w"); - if (aft->fp == NULL) { - printf("ERROR: failed to open %s: %s\n", log_path, strerror(errno)); + if(initdata == NULL) + { + printf("Error getting context for the file\n"); return -1; } + /** Use the Ouptut Context (file pointer and mutex) */ + aft->file_ctx=(LogFileCtx*) initdata; *data = (void *)aft; return 0; @@ -197,9 +201,6 @@ int LogHttplogThreadDeinit(ThreadVars *t, void *data) return 0; } - if (aft->fp != NULL) - fclose(aft->fp); - /* clear memory */ memset(aft, 0, sizeof(LogHttplogThread)); @@ -216,3 +217,66 @@ void LogHttplogExitPrintStats(ThreadVars *tv, void *data) { SCLogInfo("(%s) HTTP requests %" PRIu32 "", tv->name, aft->uri_cnt); } +/** \brief Create a new file_ctx from config_file (if specified) + * \param config_file for loading separate configs + * \return NULL if failure, LogFileCtx* to the file_ctx if succesful + * */ +LogFileCtx *LogHttplogInitCtx(char *config_file) +{ + int ret=0; + LogFileCtx* file_ctx=LogFileNewCtx(); + + if(file_ctx == NULL) + { + printf("LogHttplogInitCtx: Couldn't create new file_ctx\n"); + return NULL; + } + + /** fill the new LogFileCtx with the specific LogHttplog configuration */ + ret=LogHttplogOpenFileCtx(file_ctx, config_file); + + if(ret < 0) + return NULL; + + /** In LogHttplogOpenFileCtx the second parameter should be the configuration file to use + * but it's not implemented yet, so passing NULL to load the default + * configuration + */ + + return file_ctx; +} + +/** \brief Read the config set the file pointer, open the file + * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() + * \param config_file for loading separate configs + * \return -1 if failure, 0 if succesful + * */ +int LogHttplogOpenFileCtx(LogFileCtx *file_ctx, char *config_file) +{ + if(config_file == NULL) + { + /** Separate config files not implemented at the moment, + * but it must be able to load from separate config file. + * Load the default configuration. + */ + + char log_path[PATH_MAX], *log_dir; + if (ConfGet("default-log-dir", &log_dir) != 1) + log_dir = DEFAULT_LOG_DIR; + snprintf(log_path, PATH_MAX, "%s/%s", log_dir, DEFAULT_LOG_FILENAME); + + file_ctx->fp = fopen(log_path, "w"); + + if (file_ctx->fp == NULL) { + printf("ERROR: failed to open %s: %s\n", log_path, strerror(errno)); + return -1; + } + if(file_ctx->config_file == NULL) + file_ctx->config_file = strdup("configfile.lh"); + /** Remember the config file (or NULL if not indicated) */ + } + + return 0; +} + + diff --git a/src/log-httplog.h b/src/log-httplog.h index a300769864..ef3c865f97 100644 --- a/src/log-httplog.h +++ b/src/log-httplog.h @@ -6,6 +6,7 @@ void TmModuleLogHttplogRegister (void); void TmModuleLogHttplogIPv4Register (void); void TmModuleLogHttplogIPv6Register (void); +LogFileCtx *LogHttplogInitCtx(char *); #endif /* __LOG_HTTPLOG_H__ */ diff --git a/src/runmodes.c b/src/runmodes.c index 028901d6a8..7399883040 100644 --- a/src/runmodes.c +++ b/src/runmodes.c @@ -11,7 +11,7 @@ #include "tm-threads.h" #include "util-time.h" -int RunModeIdsPcap(DetectEngineCtx *de_ctx, char *iface) { +int RunModeIdsPcap(DetectEngineCtx *de_ctx, char *iface, LogFileCtx *af_logfile_ctx, LogFileCtx *ad_logfile_ctx, LogFileCtx *lh_logfile_ctx, LogFileCtx *aul_logfile_ctx, LogFileCtx *aua_logfile_ctx, LogFileCtx *au2a_logfile_ctx) { TimeModeSetLive(); /* create the threads */ @@ -127,14 +127,14 @@ int RunModeIdsPcap(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_alert, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_alert, tm_module, af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_alert, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_alert, tm_module, lh_logfile_ctx); if (TmThreadSpawn(tv_alert) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -152,14 +152,14 @@ int RunModeIdsPcap(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_unified, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_unified, tm_module, aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_unified, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_unified, tm_module, aua_logfile_ctx); if (TmThreadSpawn(tv_unified) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -176,7 +176,7 @@ int RunModeIdsPcap(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - Tm1SlotSetFunc(tv_unified2,tm_module,NULL); + Tm1SlotSetFunc(tv_unified2,tm_module,au2a_logfile_ctx); if (TmThreadSpawn(tv_unified2) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -193,7 +193,7 @@ int RunModeIdsPcap(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - Tm1SlotSetFunc(tv_debugalert,tm_module,NULL); + Tm1SlotSetFunc(tv_debugalert,tm_module, ad_logfile_ctx); if (TmThreadSpawn(tv_debugalert) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -204,7 +204,7 @@ int RunModeIdsPcap(DetectEngineCtx *de_ctx, char *iface) { } /** \brief Live pcap mode with 4 stream tracking and reassembly threads, testing the flow queuehandler */ -int RunModeIdsPcap2(DetectEngineCtx *de_ctx, char *iface) { +int RunModeIdsPcap2(DetectEngineCtx *de_ctx, char *iface, LogFileCtx *af_logfile_ctx, LogFileCtx *ad_logfile_ctx, LogFileCtx *lh_logfile_ctx, LogFileCtx *aul_logfile_ctx, LogFileCtx *aua_logfile_ctx, LogFileCtx *au2a_logfile_ctx) { TimeModeSetLive(); /* create the threads */ @@ -371,14 +371,14 @@ int RunModeIdsPcap2(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_alert, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_alert, tm_module, af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_alert, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_alert, tm_module, lh_logfile_ctx); if (TmThreadSpawn(tv_alert) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -396,14 +396,14 @@ int RunModeIdsPcap2(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_unified,tm_module,NULL); + TmVarSlotSetFuncAppend(tv_unified,tm_module,aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_unified,tm_module,NULL); + TmVarSlotSetFuncAppend(tv_unified,tm_module,aua_logfile_ctx); if (TmThreadSpawn(tv_unified) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -420,7 +420,7 @@ int RunModeIdsPcap2(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - Tm1SlotSetFunc(tv_unified2,tm_module,NULL); + Tm1SlotSetFunc(tv_unified2,tm_module,au2a_logfile_ctx); if (TmThreadSpawn(tv_unified2) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -437,7 +437,7 @@ int RunModeIdsPcap2(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - Tm1SlotSetFunc(tv_debugalert,tm_module,NULL); + Tm1SlotSetFunc(tv_debugalert,tm_module, ad_logfile_ctx); if (TmThreadSpawn(tv_debugalert) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -448,7 +448,7 @@ int RunModeIdsPcap2(DetectEngineCtx *de_ctx, char *iface) { } /** \brief Live pcap mode with 4 stream tracking and reassembly threads, testing the flow queuehandler */ -int RunModeIdsPcap3(DetectEngineCtx *de_ctx, char *iface) { +int RunModeIdsPcap3(DetectEngineCtx *de_ctx, char *iface, LogFileCtx *af_logfile_ctx, LogFileCtx *ad_logfile_ctx, LogFileCtx *lh_logfile_ctx, LogFileCtx *aul_logfile_ctx, LogFileCtx *aua_logfile_ctx, LogFileCtx *au2a_logfile_ctx) { TimeModeSetLive(); /* create the threads */ @@ -518,42 +518,42 @@ int RunModeIdsPcap3(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, lh_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedLog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aua_logfile_ctx); tm_module = TmModuleGetByName("Unified2Alert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for Unified2Alert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,au2a_logfile_ctx); tm_module = TmModuleGetByName("AlertDebuglog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, ad_logfile_ctx); TmThreadSetCPUAffinity(tv, 0); @@ -593,42 +593,42 @@ int RunModeIdsPcap3(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, lh_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedLog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aua_logfile_ctx); tm_module = TmModuleGetByName("Unified2Alert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for Unified2Alert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,au2a_logfile_ctx); tm_module = TmModuleGetByName("AlertDebuglog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, ad_logfile_ctx); TmThreadSetCPUAffinity(tv, 0); @@ -668,42 +668,42 @@ int RunModeIdsPcap3(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, lh_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedLog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aua_logfile_ctx); tm_module = TmModuleGetByName("Unified2Alert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for Unified2Alert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,au2a_logfile_ctx); tm_module = TmModuleGetByName("AlertDebuglog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, ad_logfile_ctx); TmThreadSetCPUAffinity(tv, 1); @@ -743,42 +743,42 @@ int RunModeIdsPcap3(DetectEngineCtx *de_ctx, char *iface) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, lh_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedLog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aua_logfile_ctx); tm_module = TmModuleGetByName("Unified2Alert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for Unified2Alert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,au2a_logfile_ctx); tm_module = TmModuleGetByName("AlertDebuglog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, ad_logfile_ctx); TmThreadSetCPUAffinity(tv, 1); @@ -789,7 +789,7 @@ int RunModeIdsPcap3(DetectEngineCtx *de_ctx, char *iface) { return 0; } -int RunModeIpsNFQ(DetectEngineCtx *de_ctx) { +int RunModeIpsNFQ(DetectEngineCtx *de_ctx, LogFileCtx *af_logfile_ctx, LogFileCtx *ad_logfile_ctx, LogFileCtx *lh_logfile_ctx, LogFileCtx *aul_logfile_ctx, LogFileCtx *aua_logfile_ctx, LogFileCtx *au2a_logfile_ctx) { TimeModeSetLive(); /* create the threads */ @@ -922,14 +922,14 @@ int RunModeIpsNFQ(DetectEngineCtx *de_ctx) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_alert, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_alert, tm_module, af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_alert, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_alert, tm_module, lh_logfile_ctx); if (TmThreadSpawn(tv_alert) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -947,14 +947,14 @@ int RunModeIpsNFQ(DetectEngineCtx *de_ctx) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_unified, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_unified, tm_module, aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_unified, tm_module, NULL); + TmVarSlotSetFuncAppend(tv_unified, tm_module, aua_logfile_ctx); if (TmThreadSpawn(tv_unified) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -971,7 +971,7 @@ int RunModeIpsNFQ(DetectEngineCtx *de_ctx) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - Tm1SlotSetFunc(tv_unified2,tm_module,NULL); + Tm1SlotSetFunc(tv_unified2,tm_module,au2a_logfile_ctx); if (TmThreadSpawn(tv_unified2) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -988,7 +988,7 @@ int RunModeIpsNFQ(DetectEngineCtx *de_ctx) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - Tm1SlotSetFunc(tv_debugalert,tm_module,NULL); + Tm1SlotSetFunc(tv_debugalert,tm_module, ad_logfile_ctx); if (TmThreadSpawn(tv_debugalert) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -998,7 +998,7 @@ int RunModeIpsNFQ(DetectEngineCtx *de_ctx) { return 0; } -int RunModeFilePcap(DetectEngineCtx *de_ctx, char *file) { +int RunModeFilePcap(DetectEngineCtx *de_ctx, char *file, LogFileCtx *af_logfile_ctx, LogFileCtx *ad_logfile_ctx, LogFileCtx *lh_logfile_ctx, LogFileCtx *aul_logfile_ctx, LogFileCtx *aua_logfile_ctx, LogFileCtx *au2a_logfile_ctx) { printf("RunModeFilePcap: file %s\n", file); TimeModeSetOffline(); @@ -1100,14 +1100,14 @@ int RunModeFilePcap(DetectEngineCtx *de_ctx, char *file) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_alert,tm_module,NULL); + TmVarSlotSetFuncAppend(tv_alert,tm_module,af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_alert,tm_module,NULL); + TmVarSlotSetFuncAppend(tv_alert,tm_module, lh_logfile_ctx); if (TmThreadSpawn(tv_alert) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -1125,14 +1125,14 @@ int RunModeFilePcap(DetectEngineCtx *de_ctx, char *file) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_unified,tm_module,NULL); + TmVarSlotSetFuncAppend(tv_unified,tm_module,aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv_unified,tm_module,NULL); + TmVarSlotSetFuncAppend(tv_unified,tm_module,aua_logfile_ctx); if (TmThreadSpawn(tv_unified) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -1150,7 +1150,7 @@ int RunModeFilePcap(DetectEngineCtx *de_ctx, char *file) { printf("ERROR: TmModuleGetByName for Unified2Alert failed\n"); exit(EXIT_FAILURE); } - Tm1SlotSetFunc(tv_unified2,tm_module,NULL); + Tm1SlotSetFunc(tv_unified2,tm_module,au2a_logfile_ctx); if (TmThreadSpawn(tv_unified2) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -1167,7 +1167,7 @@ int RunModeFilePcap(DetectEngineCtx *de_ctx, char *file) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - Tm1SlotSetFunc(tv_debugalert,tm_module,NULL); + Tm1SlotSetFunc(tv_debugalert,tm_module, ad_logfile_ctx); if (TmThreadSpawn(tv_debugalert) != 0) { printf("ERROR: TmThreadSpawn failed\n"); @@ -1179,7 +1179,7 @@ int RunModeFilePcap(DetectEngineCtx *de_ctx, char *file) { /** * \brief Single thread version of the Pcap file processing. */ -int RunModeFilePcap2(DetectEngineCtx *de_ctx, char *file) { +int RunModeFilePcap2(DetectEngineCtx *de_ctx, char *file, LogFileCtx *af_logfile_ctx, LogFileCtx *ad_logfile_ctx, LogFileCtx *lh_logfile_ctx, LogFileCtx *aul_logfile_ctx, LogFileCtx *aua_logfile_ctx, LogFileCtx *au2a_logfile_ctx) { printf("RunModeFilePcap2: file %s\n", file); TimeModeSetOffline(); @@ -1223,41 +1223,41 @@ int RunModeFilePcap2(DetectEngineCtx *de_ctx, char *file) { printf("ERROR: TmModuleGetByName for AlertFastlog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,af_logfile_ctx); tm_module = TmModuleGetByName("LogHttplog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, lh_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedLog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedLog failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aul_logfile_ctx); tm_module = TmModuleGetByName("AlertUnifiedAlert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for AlertUnifiedAlert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,aua_logfile_ctx); tm_module = TmModuleGetByName("Unified2Alert"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName for Unified2Alert failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module,au2a_logfile_ctx); tm_module = TmModuleGetByName("AlertDebuglog"); if (tm_module == NULL) { printf("ERROR: TmModuleGetByName failed\n"); exit(EXIT_FAILURE); } - TmVarSlotSetFuncAppend(tv,tm_module,NULL); + TmVarSlotSetFuncAppend(tv,tm_module, ad_logfile_ctx); if (TmThreadSpawn(tv) != 0) { printf("ERROR: TmThreadSpawn failed\n"); diff --git a/src/runmodes.h b/src/runmodes.h index e538c0839c..fb74572a0c 100644 --- a/src/runmodes.h +++ b/src/runmodes.h @@ -1,14 +1,14 @@ #ifndef __RUNMODES_H__ #define __RUNMODES_H__ -int RunModeIdsPcap(DetectEngineCtx *, char *); -int RunModeIdsPcap2(DetectEngineCtx *, char *); -int RunModeIdsPcap3(DetectEngineCtx *, char *); +int RunModeIdsPcap(DetectEngineCtx *, char *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *); +int RunModeIdsPcap2(DetectEngineCtx *, char *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *); +int RunModeIdsPcap3(DetectEngineCtx *, char *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *); -int RunModeIpsNFQ(DetectEngineCtx *); +int RunModeIpsNFQ(DetectEngineCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *); -int RunModeFilePcap(DetectEngineCtx *, char *); -int RunModeFilePcap2(DetectEngineCtx *, char *); +int RunModeFilePcap(DetectEngineCtx *, char *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *); +int RunModeFilePcap2(DetectEngineCtx *, char *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *, LogFileCtx *); int RunModeIdsPfring(DetectEngineCtx *, char *); int RunModeIdsPfring2(DetectEngineCtx *, char *); diff --git a/src/tm-modules.c b/src/tm-modules.c index db09bf7f75..c2cd5055a7 100644 --- a/src/tm-modules.c +++ b/src/tm-modules.c @@ -4,6 +4,7 @@ #include "packet-queue.h" #include "tm-modules.h" #include "util-debug.h" +#include "threads.h" void TmModuleDebugList(void) { TmModule *t; @@ -39,6 +40,52 @@ TmModule *TmModuleGetByName(char *name) { return NULL; } +/** \brief LogFileNewCtx() Get a new LogFileCtx + * \retval LogFileCtx * pointer if succesful, NULL if error + * */ +LogFileCtx *LogFileNewCtx() +{ + LogFileCtx* lf_ctx; + lf_ctx=(LogFileCtx*)malloc(sizeof(LogFileCtx)); + + if(lf_ctx == NULL) + { + printf("LogFileCtxNew: Couldn't malloc \n"); + return NULL; + } + memset(lf_ctx, 0, sizeof(LogFileCtx)); + /** Ensure that it is unlocked */ + pthread_mutex_init(&lf_ctx->fp_mutex,NULL); + mutex_unlock(&lf_ctx->fp_mutex); + + return lf_ctx; +} + +/** \brief LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory) + * \param motcx pointer to the OutputCtx + * \retval int 1 if succesful, 0 if error + * */ +int LogFileFreeCtx(LogFileCtx *lf_ctx) +{ + int ret=0; + + if(lf_ctx != NULL) + { + if (lf_ctx->fp != NULL) + { + mutex_lock(&lf_ctx->fp_mutex); + fclose(lf_ctx->fp); + mutex_unlock(&lf_ctx->fp_mutex); + } + if (lf_ctx->config_file != NULL); + free(lf_ctx->config_file); + free(lf_ctx); + ret=1; + } + + return ret; +} + /** \brief register all unittests for the tm modules */ void TmModuleRegisterTests(void) { #ifdef UNITTESTS diff --git a/src/tm-modules.h b/src/tm-modules.h index 2b78854a52..79ddb1a3bf 100644 --- a/src/tm-modules.h +++ b/src/tm-modules.h @@ -45,6 +45,21 @@ enum { TmModule tmm_modules[TMM_SIZE]; +/** Global structure for Output Context */ +typedef struct LogFileCtx_ { + FILE *fp; + pthread_mutex_t fp_mutex; + /** It will be locked if the log/alert + * record cannot be written to the file in one call */ + + char *config_file; + /** To know where did we read this config */ + +} LogFileCtx; + +LogFileCtx *LogFileNewCtx(); +int LogFileFreeCtx(LogFileCtx *); + TmModule *TmModuleGetByName(char *name); int TmModuleRegister(char *name, int (*module_func)(ThreadVars *, Packet *, void *)); void TmModuleDebugList(void);