#define MODULE_NAME "LogFilestoreLog"
-SC_ATOMIC_DECLARE(unsigned int, file_id);
static char g_logfile_base_dir[PATH_MAX] = "/tmp";
-static char g_waldo[PATH_MAX] = "";
typedef struct LogFilestoreLogThread_ {
LogFileCtx *file_ctx;
uint32_t file_cnt;
} LogFilestoreLogThread;
-static void LogFilestoreMetaGetUri(FILE *fp, Packet *p, File *ff) {
+static void LogFilestoreMetaGetUri(FILE *fp, const Packet *p, const File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid);
fprintf(fp, "<unknown>");
}
-static void LogFilestoreMetaGetHost(FILE *fp, Packet *p, File *ff) {
+static void LogFilestoreMetaGetHost(FILE *fp, const Packet *p, const File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid);
fprintf(fp, "<unknown>");
}
-static void LogFilestoreMetaGetReferer(FILE *fp, Packet *p, File *ff) {
+static void LogFilestoreMetaGetReferer(FILE *fp, const Packet *p, const File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid);
fprintf(fp, "<unknown>");
}
-static void LogFilestoreMetaGetUserAgent(FILE *fp, Packet *p, File *ff) {
+static void LogFilestoreMetaGetUserAgent(FILE *fp, const Packet *p, const File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid);
fprintf(fp, "<unknown>");
}
-static void LogFilestoreLogCreateMetaFile(Packet *p, File *ff, char *filename, int ipver) {
+static void LogFilestoreLogCreateMetaFile(const Packet *p, const File *ff, const char *filename, int ipver) {
char metafilename[PATH_MAX] = "";
snprintf(metafilename, sizeof(metafilename), "%s.meta", filename);
FILE *fp = fopen(metafilename, "w+");
}
}
-static void LogFilestoreLogCloseMetaFile(File *ff) {
+static void LogFilestoreLogCloseMetaFile(const File *ff) {
char filename[PATH_MAX] = "";
snprintf(filename, sizeof(filename), "%s/file.%u",
g_logfile_base_dir, ff->file_id);
}
}
-static TmEcode LogFilestoreLogWrap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq, int ipver)
+static int LogFilestoreLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff, const FileData *ffd, uint8_t flags)
{
SCEnter();
- LogFilestoreLogThread *aft = (LogFilestoreLogThread *)data;
- uint8_t flags = 0;
+ LogFilestoreLogThread *aft = (LogFilestoreLogThread *)thread_data;
+ char filename[PATH_MAX] = "";
+ int file_fd = -1;
+ int ipver = -1;
/* no flow, no htp state */
if (p->flow == NULL) {
SCReturnInt(TM_ECODE_OK);
}
- if (p->flowflags & FLOW_PKT_TOCLIENT)
- flags |= STREAM_TOCLIENT;
- else
- flags |= STREAM_TOSERVER;
-
- int file_close = (p->flags & PKT_PSEUDO_STREAM_END) ? 1 : 0;
- int file_trunc = 0;
-
- FLOWLOCK_WRLOCK(p->flow);
- file_trunc = StreamTcpReassembleDepthReached(p);
-
- FileContainer *ffc = AppLayerParserGetFiles(IPPROTO_TCP, p->flow->alproto, p->flow->alstate, flags);
- SCLogDebug("ffc %p", ffc);
- if (ffc != NULL) {
- File *ff;
- for (ff = ffc->head; ff != NULL; ff = ff->next) {
- int file_fd = -1;
-
- if (FileForceMagic() && ff->magic == NULL) {
- FilemagicGlobalLookup(ff);
- }
-
- SCLogDebug("ff %p", ff);
- if (ff->flags & FILE_STORED) {
- SCLogDebug("stored flag set");
- continue;
- }
-
- if (!(ff->flags & FILE_STORE)) {
- SCLogDebug("ff FILE_STORE not set");
- continue;
- }
-
- FileData *ffd;
- for (ffd = ff->chunks_head; ffd != NULL; ffd = ffd->next) {
- SCLogDebug("ffd %p", ffd);
- if (ffd->stored == 1) {
- if (file_close == 1 && ffd->next == NULL) {
- LogFilestoreLogCloseMetaFile(ff);
- ff->flags |= FILE_STORED;
- }
- continue;
- }
-
- /* store */
- SCLogDebug("trying to open file");
-
- char filename[PATH_MAX] = "";
-
- if (ff->file_id == 0) {
- ff->file_id = SC_ATOMIC_ADD(file_id, 1);
-
- snprintf(filename, sizeof(filename), "%s/file.%u",
- g_logfile_base_dir, ff->file_id);
-
- file_fd = open(filename, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
- if (file_fd == -1) {
- SCLogDebug("failed to open file");
- continue;
- }
-
- /* create a .meta file that contains time, src/dst/sp/dp/proto */
- LogFilestoreLogCreateMetaFile(p, ff, filename, ipver);
- aft->file_cnt++;
- } else {
- snprintf(filename, sizeof(filename), "%s/file.%u",
- g_logfile_base_dir, ff->file_id);
-
- file_fd = open(filename, O_APPEND | O_NOFOLLOW | O_WRONLY);
- if (file_fd == -1) {
- SCLogDebug("failed to open file %s: %s", filename, strerror(errno));
- continue;
- }
- }
-
- ssize_t r = write(file_fd, (const void *)ffd->data, (size_t)ffd->len);
- if (r == -1) {
- SCLogDebug("write failed: %s", strerror(errno));
-
- close(file_fd);
- continue;
- }
-
- close(file_fd);
-
- if (file_trunc && ff->state < FILE_STATE_CLOSED)
- ff->state = FILE_STATE_TRUNCATED;
- if (file_close && ff->state < FILE_STATE_CLOSED)
- ff->state = FILE_STATE_TRUNCATED;
-
- if (ff->state == FILE_STATE_CLOSED ||
- ff->state == FILE_STATE_TRUNCATED ||
- ff->state == FILE_STATE_ERROR)
- {
- if (ffd->next == NULL) {
- LogFilestoreLogCloseMetaFile(ff);
-
- ff->flags |= FILE_STORED;
- }
- }
-
- ffd->stored = 1;
- }
- }
-
- FilePrune(ffc);
+ if (PKT_IS_IPV4(p)) {
+ ipver = AF_INET;
+ } else if (PKT_IS_IPV6(p)) {
+ ipver = AF_INET6;
+ } else {
+ return 0;
}
- FLOWLOCK_UNLOCK(p->flow);
- SCReturnInt(TM_ECODE_OK);
-}
+ SCLogDebug("ff %p, ffd %p", ff, ffd);
-static TmEcode LogFilestoreLogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) {
- return LogFilestoreLogWrap(tv, p, data, NULL, NULL, AF_INET);
-}
+ snprintf(filename, sizeof(filename), "%s/file.%u",
+ g_logfile_base_dir, ff->file_id);
-static TmEcode LogFilestoreLogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) {
- return LogFilestoreLogWrap(tv, p, data, NULL, NULL, AF_INET6);
-}
+ if (flags & OUTPUT_FILEDATA_FLAG_OPEN) {
+ aft->file_cnt++;
-static TmEcode LogFilestoreLog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
-{
- SCEnter();
- int r = TM_ECODE_OK;
+ /* create a .meta file that contains time, src/dst/sp/dp/proto */
+ LogFilestoreLogCreateMetaFile(p, ff, filename, ipver);
- /* no flow, no htp state */
- if (p->flow == NULL) {
- SCReturnInt(TM_ECODE_OK);
+ file_fd = open(filename, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
+ if (file_fd == -1) {
+ SCLogDebug("failed to create file");
+ return -1;
+ }
+ /* we can get called with a NULL ffd when we need to close */
+ } else if (ffd != NULL) {
+ file_fd = open(filename, O_APPEND | O_NOFOLLOW | O_WRONLY);
+ if (file_fd == -1) {
+ SCLogDebug("failed to open file %s: %s", filename, strerror(errno));
+ return -1;
+ }
}
- if (!(PKT_IS_TCP(p))) {
- SCReturnInt(TM_ECODE_OK);
+ if (file_fd != -1) {
+ ssize_t r = write(file_fd, (const void *)ffd->data, (size_t)ffd->len);
+ if (r == -1) {
+ SCLogDebug("write failed: %s", strerror(errno));
+ }
+ close(file_fd);
}
- SCLogDebug("p->pcap_cnt %"PRIu64, p->pcap_cnt);
-
- if (PKT_IS_IPV4(p)) {
- r = LogFilestoreLogIPv4(tv, p, data, pq, postpq);
- } else if (PKT_IS_IPV6(p)) {
- r = LogFilestoreLogIPv6(tv, p, data, pq, postpq);
+ if (flags & OUTPUT_FILEDATA_FLAG_CLOSE) {
+ LogFilestoreLogCloseMetaFile(ff);
}
- SCReturnInt(r);
+ return 0;
}
static TmEcode LogFilestoreLogThreadInit(ThreadVars *t, void *initdata, void **data)
SCLogInfo("(%s) Files extracted %" PRIu32 "", tv->name, aft->file_cnt);
}
-/**
- * \internal
- *
- * \brief Open the waldo file (if available) and load the file_id
- *
- * \param path full path for the waldo file
- */
-static void LogFilestoreLogLoadWaldo(const char *path) {
- char line[16] = "";
- unsigned int id = 0;
-
- FILE *fp = fopen(path, "r");
- if (fp == NULL) {
- SCLogInfo("couldn't open waldo: %s", strerror(errno));
- SCReturn;
- }
-
- if (fgets(line, (int)sizeof(line), fp) != NULL) {
- if (sscanf(line, "%10u", &id) == 1) {
- SCLogInfo("id %u", id);
- (void) SC_ATOMIC_CAS(&file_id, 0, id);
- }
- }
- fclose(fp);
-}
-
-/**
- * \internal
- *
- * \brief Store the waldo file based on the file_id
- *
- * \param path full path for the waldo file
- */
-static void LogFilestoreLogStoreWaldo(const char *path) {
- char line[16] = "";
-
- if (SC_ATOMIC_GET(file_id) == 0) {
- SCReturn;
- }
-
- FILE *fp = fopen(path, "w");
- if (fp == NULL) {
- SCLogInfo("couldn't open waldo: %s", strerror(errno));
- SCReturn;
- }
-
- snprintf(line, sizeof(line), "%u\n", SC_ATOMIC_GET(file_id));
- if (fwrite(line, strlen(line), 1, fp) != 1) {
- SCLogError(SC_ERR_FWRITE, "fwrite failed: %s", strerror(errno));
- }
- fclose(fp);
-}
-
/**
* \internal
*
LogFileFreeCtx(logfile_ctx);
free(output_ctx);
- if (strlen(g_waldo) > 0) {
- LogFilestoreLogStoreWaldo(g_waldo);
- }
}
/** \brief Create a new http log LogFilestoreCtx.
SCLogInfo("md5 calculation requires linking against libnss");
#endif
}
-
- const char *waldo = ConfNodeLookupChildValue(conf, "waldo");
- if (waldo != NULL && strlen(waldo) > 0) {
- if (PathIsAbsolute(waldo)) {
- snprintf(g_waldo, sizeof(g_waldo), "%s", waldo);
- } else {
- snprintf(g_waldo, sizeof(g_waldo), "%s/%s", s_default_log_dir, waldo);
- }
-
- SCLogInfo("loading waldo file %s", g_waldo);
- LogFilestoreLogLoadWaldo(g_waldo);
- }
SCLogInfo("storing files in %s", g_logfile_base_dir);
SCReturnPtr(output_ctx, "OutputCtx");
void TmModuleLogFilestoreRegister (void) {
tmm_modules[TMM_FILESTORE].name = MODULE_NAME;
tmm_modules[TMM_FILESTORE].ThreadInit = LogFilestoreLogThreadInit;
- tmm_modules[TMM_FILESTORE].Func = LogFilestoreLog;
+ tmm_modules[TMM_FILESTORE].Func = NULL;
tmm_modules[TMM_FILESTORE].ThreadExitPrintStats = LogFilestoreLogExitPrintStats;
tmm_modules[TMM_FILESTORE].ThreadDeinit = LogFilestoreLogThreadDeinit;
tmm_modules[TMM_FILESTORE].RegisterTests = NULL;
tmm_modules[TMM_FILESTORE].cap_flags = 0;
- OutputRegisterModule(MODULE_NAME, "file", LogFilestoreLogInitCtx);
- OutputRegisterModule(MODULE_NAME, "file-store", LogFilestoreLogInitCtx);
+ OutputRegisterFiledataModule(MODULE_NAME, "file", LogFilestoreLogInitCtx,
+ LogFilestoreLogger);
+ OutputRegisterFiledataModule(MODULE_NAME, "file-store", LogFilestoreLogInitCtx,
+ LogFilestoreLogger);
SCLogDebug("registered");
-
- SC_ATOMIC_INIT(file_id);
}