static TmEcode LogFileLogWrap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq, int ipver) { SCEnter(); LogFileLogThread *aft = (LogFileLogThread *)data; uint8_t flags = 0; /* 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) { if (ff->flags & FILE_LOGGED) continue; if (FileForceMagic() && ff->magic == NULL) { FilemagicGlobalLookup(ff); } SCLogDebug("ff %p", ff); if (file_trunc && 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 || (file_close == 1 && ff->state < FILE_STATE_CLOSED)) { LogFileWriteJsonRecord(aft, p, ff, ipver); ff->flags |= FILE_LOGGED; aft->file_cnt++; } } FilePrune(ffc); } FLOWLOCK_UNLOCK(p->flow); SCReturnInt(TM_ECODE_OK); }
static TmEcode LogFilestoreLogWrap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq, int ipver) { SCEnter(); LogFilestoreLogThread *aft = (LogFilestoreLogThread *)data; uint8_t flags = 0; /* 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 = AppLayerGetFilesFromFlow(p->flow, 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 (ff->state == FILE_STATE_CLOSED || ff->state == FILE_STATE_TRUNCATED || ff->state == FILE_STATE_ERROR || (file_close == 1 && ff->state < FILE_STATE_CLOSED)) { if (ffd->next == NULL) { LogFilestoreLogCloseMetaFile(ff); ff->flags |= FILE_STORED; } } ffd->stored = 1; } } FilePrune(ffc); } FLOWLOCK_UNLOCK(p->flow); SCReturnInt(TM_ECODE_OK); }
static TmEcode OutputFileLog(ThreadVars *tv, Packet *p, void *thread_data, PacketQueue *pq, PacketQueue *postpq) { BUG_ON(thread_data == NULL); BUG_ON(list == NULL); OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; OutputFileLogger *logger = list; OutputLoggerThreadStore *store = op_thread_data->store; BUG_ON(logger == NULL && store != NULL); BUG_ON(logger != NULL && store == NULL); BUG_ON(logger == NULL && store == NULL); uint8_t flags = 0; Flow * const f = p->flow; /* no flow, no files */ if (f == 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(f); // < need write lock for FilePrune below file_trunc = StreamTcpReassembleDepthReached(p); FileContainer *ffc = AppLayerParserGetFiles(p->proto, f->alproto, f->alstate, flags); SCLogDebug("ffc %p", ffc); if (ffc != NULL) { File *ff; for (ff = ffc->head; ff != NULL; ff = ff->next) { if (ff->flags & FILE_LOGGED) continue; SCLogDebug("ff %p", ff); 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) { int file_logged = 0; if (FileForceMagic() && ff->magic == NULL) { FilemagicGlobalLookup(ff); } logger = list; store = op_thread_data->store; while (logger && store) { BUG_ON(logger->LogFunc == NULL); SCLogDebug("logger %p", logger); PACKET_PROFILING_TMM_START(p, logger->module_id); logger->LogFunc(tv, store->thread_data, (const Packet *)p, (const File *)ff); PACKET_PROFILING_TMM_END(p, logger->module_id); file_logged = 1; logger = logger->next; store = store->next; BUG_ON(logger == NULL && store != NULL); BUG_ON(logger != NULL && store == NULL); } if (file_logged) { ff->flags |= FILE_LOGGED; } } } FilePrune(ffc); } FLOWLOCK_UNLOCK(f); return TM_ECODE_OK; }