diff --git a/src/log-pcap.c b/src/log-pcap.c index 9d97c4e1dc..a95a2aa06e 100644 --- a/src/log-pcap.c +++ b/src/log-pcap.c @@ -1,8 +1,28 @@ -/* Copyright (c) 2009 Open Information Security Foundation */ +/* Copyright (C) 2007-2011 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * 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 + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + /** \file + * * \author William Metcalf + * + * Pcap packet logging module. */ + #if LIBPCAP_VERSION_MAJOR == 1 #include #else @@ -50,11 +70,11 @@ static void PcapLogFileDeInitCtx(OutputCtx *); * Used for storing file options. */ typedef struct PcapLogThread_ { - LogFileCtx *file_ctx; /** LogFileCtx pointer */ - uint32_t size_current; /**< file current size */ - pcap_t *pcap_dead_handle; /**< pcap_dumper_t needs a handle */ + LogFileCtx *file_ctx; /**< LogFileCtx pointer */ + uint32_t size_current; /**< file current size */ + pcap_t *pcap_dead_handle; /**< pcap_dumper_t needs a handle */ pcap_dumper_t *pcap_dumper; /**< actually writes the packets */ - struct pcap_pkthdr *h; /**< pcap header struct */ + struct pcap_pkthdr *h; /**< pcap header struct */ } PcapLogThread; void TmModulePcapLogRegister (void) { @@ -63,6 +83,7 @@ void TmModulePcapLogRegister (void) { tmm_modules[TMM_PCAPLOG].Func = PcapLog; tmm_modules[TMM_PCAPLOG].ThreadDeinit = PcapLogThreadDeinit; tmm_modules[TMM_PCAPLOG].RegisterTests = NULL; + OutputRegisterModule(MODULE_NAME, "pcap-log", PcapLogInitCtx); } @@ -72,11 +93,12 @@ void TmModulePcapLogRegister (void) { * \param t Thread Variable containing input/output queue, cpu affinity etc. * \param pl PcapLog thread variable. */ - int PcapLogCloseFile(ThreadVars *t, PcapLogThread *pl) { - pcap_dump_close(pl->pcap_dumper); - pl->size_current = 0; - pl->pcap_dumper = NULL; + if (pl != NULL) { + pcap_dump_close(pl->pcap_dumper); + pl->size_current = 0; + pl->pcap_dumper = NULL; + } return 0; } @@ -85,27 +107,43 @@ int PcapLogCloseFile(ThreadVars *t, PcapLogThread *pl) { * * \param t Thread Variable containing input/output queue, cpu affinity etc. * \param pl PcapLog thread variable. + * * \retval 0 on succces * \retval -1 on failure */ - int PcapLogRotateFile(ThreadVars *t, PcapLogThread *pl) { if (PcapLogCloseFile(t,pl) < 0) { - SCLogInfo("Error: PcapLogCloseFile failed"); + SCLogDebug("PcapLogCloseFile failed"); return -1; } if (PcapLogOpenFileCtx(pl->file_ctx,pl->file_ctx->prefix) < 0) { - SCLogInfo("Error: PcapLogOpenFileCtx, open new log file failed"); + SCLogError(SC_ERR_FOPEN, "opening new pcap log file failed"); return -1; } return 0; } +/** + * \brief Pcap logging main function + * + * \param t threadvar + * \param p packet + * \param data thread module specific data + * \param pq pre-packet-queue + * \param postpq post-packet-queue + * + * \retval TM_ECODE_OK on succes + * \retval TM_ECODE_FAILED on serious error + */ TmEcode PcapLog (ThreadVars *t, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { - int len; + size_t len; PcapLogThread *pl = (PcapLogThread *)data; + if (pl == NULL) { + return TM_ECODE_FAILED; + } + pl->h->ts.tv_sec = p->ts.tv_sec; pl->h->ts.tv_usec = p->ts.tv_usec; pl->h->caplen = p->pktlen; @@ -117,43 +155,51 @@ TmEcode PcapLog (ThreadVars *t, Packet *p, void *data, PacketQueue *pq, PacketQu if (PcapLogRotateFile(t,pl) < 0) { SCMutexUnlock(&pl->file_ctx->fp_mutex); - SCLogInfo("rotation of pcap failed"); + SCLogDebug("rotation of pcap failed"); return TM_ECODE_FAILED; } } SCMutexUnlock(&pl->file_ctx->fp_mutex); - /* XXX pcap handles, nfq, pfring, can only have one link type ipfw? we do this here as we don't know the link type until we get our first packet */ - if(pl->pcap_dead_handle == NULL){ + /* XXX pcap handles, nfq, pfring, can only have one link type ipfw? we do + * this here as we don't know the link type until we get our first packet */ + if (pl->pcap_dead_handle == NULL) { SCLogDebug("Setting pcap-log link type to %u", p->datalink); - if((pl->pcap_dead_handle=pcap_open_dead(p->datalink,LIBPCAP_SNAPLEN)) == NULL){ + + if ((pl->pcap_dead_handle = pcap_open_dead(p->datalink, + LIBPCAP_SNAPLEN)) == NULL) + { SCLogDebug("Error opening dead pcap handle"); return TM_ECODE_FAILED; } } - /*XXX LogfileCtx setup currently doesn't allow thread vars so we open the handle here */ - if(pl->pcap_dumper == NULL){ - if((pl->pcap_dumper=pcap_dump_open(pl->pcap_dead_handle, pl->file_ctx->filename)) == NULL){ + /* XXX LogfileCtx setup currently doesn't allow thread vars so we open the + * handle here */ + if (pl->pcap_dumper == NULL) { + if ((pl->pcap_dumper = pcap_dump_open(pl->pcap_dead_handle, + pl->file_ctx->filename)) == NULL) + { SCLogInfo("Error opening dump file %s",pcap_geterr(pl->pcap_dead_handle)); return TM_ECODE_FAILED; } } - pcap_dump((u_char *)pl->pcap_dumper,pl->h,p->pkt); + pcap_dump((u_char *)pl->pcap_dumper, pl->h, p->pkt); pl->size_current += len; SCLogDebug("%u %u",pl->size_current,pl->file_ctx->size_limit); + return TM_ECODE_OK; } TmEcode PcapLogThreadInit(ThreadVars *t, void *initdata, void **data) { - PcapLogThread *pl = malloc(sizeof(PcapLogThread)); + PcapLogThread *pl = SCMalloc(sizeof(PcapLogThread)); if (pl == NULL) { return TM_ECODE_FAILED; } memset(pl, 0, sizeof(PcapLogThread)); - pl->h = malloc(sizeof(*pl->h)); + pl->h = SCMalloc(sizeof(*pl->h)); if (pl->h == NULL) { return TM_ECODE_FAILED; } @@ -226,6 +272,7 @@ OutputCtx *PcapLogInitCtx(ConfNode *conf) } if (filename == NULL) filename = DEFAULT_LOG_FILENAME; + file_ctx->prefix = SCStrdup(filename); const char *s_limit = NULL; @@ -249,9 +296,9 @@ OutputCtx *PcapLogInitCtx(ConfNode *conf) } file_ctx->size_limit = limit * 1024 * 1024; - ret=PcapLogOpenFileCtx(file_ctx, filename); + ret = PcapLogOpenFileCtx(file_ctx, filename); - if(ret < 0) + if (ret < 0) return NULL; OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); @@ -267,20 +314,29 @@ OutputCtx *PcapLogInitCtx(ConfNode *conf) static void PcapLogFileDeInitCtx(OutputCtx *output_ctx) { - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - LogFileFreeCtx(logfile_ctx); - free(output_ctx); + if (output_ctx != NULL) { + LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; + if (logfile_ctx != NULL) { + LogFileFreeCtx(logfile_ctx); + } + free(output_ctx); + } } -/** \brief Read the config set the file pointer, open the file +/** + * \brief Read the config set the file pointer, open the file + * * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() * \param prefix Prefix of the log file. - * \return -1 if failure, 0 if succesful - * */ + * + * \retval -1 if failure + * \retval 0 if succesful + */ int PcapLogOpenFileCtx(LogFileCtx *file_ctx, const char *prefix) { char *filename = NULL; - if (file_ctx->filename != NULL) + + if (file_ctx->filename != NULL) filename = file_ctx->filename; else filename = file_ctx->filename = malloc(PATH_MAX); /* XXX some sane default? */