|
|
|
|
@ -480,6 +480,42 @@ static void PcapLogUnlock(PcapLogData *pl)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int PcapWrite(
|
|
|
|
|
PcapLogData *pl, PcapLogCompressionData *comp, uint8_t *data, size_t len)
|
|
|
|
|
{
|
|
|
|
|
pcap_dump((u_char *)pl->pcap_dumper, pl->h, data);
|
|
|
|
|
if (pl->compression.format == PCAP_LOG_COMPRESSION_FORMAT_NONE) {
|
|
|
|
|
pl->size_current += len;
|
|
|
|
|
}
|
|
|
|
|
#ifdef HAVE_LIBLZ4
|
|
|
|
|
else if (pl->compression.format == PCAP_LOG_COMPRESSION_FORMAT_LZ4) {
|
|
|
|
|
pcap_dump_flush(pl->pcap_dumper);
|
|
|
|
|
uint64_t in_size = (uint64_t)ftell(comp->pcap_buf_wrapper);
|
|
|
|
|
uint64_t out_size = LZ4F_compressUpdate(
|
|
|
|
|
comp->lz4f_context, comp->buffer, comp->buffer_size, comp->pcap_buf, in_size, NULL);
|
|
|
|
|
if (LZ4F_isError(len)) {
|
|
|
|
|
SCLogError(SC_ERR_PCAP_LOG_COMPRESS, "LZ4F_compressUpdate: %s", LZ4F_getErrorName(len));
|
|
|
|
|
return TM_ECODE_FAILED;
|
|
|
|
|
}
|
|
|
|
|
if (fseek(pl->compression.pcap_buf_wrapper, 0, SEEK_SET) != 0) {
|
|
|
|
|
SCLogError(SC_ERR_FSEEK, "fseek failed: %s", strerror(errno));
|
|
|
|
|
return TM_ECODE_FAILED;
|
|
|
|
|
}
|
|
|
|
|
if (fwrite(comp->buffer, 1, out_size, comp->file) < out_size) {
|
|
|
|
|
SCLogError(SC_ERR_FWRITE, "fwrite failed: %s", strerror(errno));
|
|
|
|
|
return TM_ECODE_FAILED;
|
|
|
|
|
}
|
|
|
|
|
if (out_size > 0) {
|
|
|
|
|
pl->size_current += out_size;
|
|
|
|
|
comp->bytes_in_block = len;
|
|
|
|
|
} else {
|
|
|
|
|
comp->bytes_in_block += len;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif /* HAVE_LIBLZ4 */
|
|
|
|
|
return TM_ECODE_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Pcap logging main function
|
|
|
|
|
*
|
|
|
|
|
@ -574,37 +610,17 @@ static int PcapLog (ThreadVars *t, void *thread_data, const Packet *p)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PCAPLOG_PROFILE_START;
|
|
|
|
|
pcap_dump((u_char *)pl->pcap_dumper, pl->h, GET_PKT_DATA(p));
|
|
|
|
|
if (pl->compression.format == PCAP_LOG_COMPRESSION_FORMAT_NONE) {
|
|
|
|
|
pl->size_current += len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBLZ4
|
|
|
|
|
else if (pl->compression.format == PCAP_LOG_COMPRESSION_FORMAT_LZ4) {
|
|
|
|
|
pcap_dump_flush(pl->pcap_dumper);
|
|
|
|
|
uint64_t in_size = (uint64_t)ftell(comp->pcap_buf_wrapper);
|
|
|
|
|
uint64_t out_size = LZ4F_compressUpdate(comp->lz4f_context,
|
|
|
|
|
comp->buffer, comp->buffer_size, comp->pcap_buf, in_size, NULL);
|
|
|
|
|
if (LZ4F_isError(len)) {
|
|
|
|
|
SCLogError(SC_ERR_PCAP_LOG_COMPRESS, "LZ4F_compressUpdate: %s",
|
|
|
|
|
LZ4F_getErrorName(len));
|
|
|
|
|
return TM_ECODE_FAILED;
|
|
|
|
|
}
|
|
|
|
|
if (fseek(pl->compression.pcap_buf_wrapper, 0, SEEK_SET) != 0) {
|
|
|
|
|
SCLogError(SC_ERR_FSEEK, "fseek failed: %s", strerror(errno));
|
|
|
|
|
return TM_ECODE_FAILED;
|
|
|
|
|
}
|
|
|
|
|
if (fwrite(comp->buffer, 1, out_size, comp->file) < out_size) {
|
|
|
|
|
SCLogError(SC_ERR_FWRITE, "fwrite failed: %s", strerror(errno));
|
|
|
|
|
return TM_ECODE_FAILED;
|
|
|
|
|
}
|
|
|
|
|
if (out_size > 0) {
|
|
|
|
|
pl->size_current += out_size;
|
|
|
|
|
comp->bytes_in_block = len;
|
|
|
|
|
} else {
|
|
|
|
|
comp->bytes_in_block += len;
|
|
|
|
|
}
|
|
|
|
|
ret = PcapWrite(pl, comp, GET_PKT_DATA(p), len);
|
|
|
|
|
#else
|
|
|
|
|
ret = PcapWrite(pl, NULL, GET_PKT_DATA(p), len);
|
|
|
|
|
#endif
|
|
|
|
|
if (ret != TM_ECODE_OK) {
|
|
|
|
|
PCAPLOG_PROFILE_END(pl->profile_write);
|
|
|
|
|
PcapLogUnlock(pl);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
#endif /* HAVE_LIBLZ4 */
|
|
|
|
|
|
|
|
|
|
PCAPLOG_PROFILE_END(pl->profile_write);
|
|
|
|
|
pl->profile_data_size += len;
|
|
|
|
|
|