forked from Mirrors/sngrep
add SIGHUP signal handler to allow rotation of pcap dump files
This commit is contained in:
parent
600511fd0d
commit
a2b88f9b33
|
@ -34,6 +34,8 @@
|
|||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include "capture.h"
|
||||
#ifdef USE_EEP
|
||||
#include "capture_eep.h"
|
||||
|
@ -49,10 +51,26 @@
|
|||
#include "setting.h"
|
||||
#include "util.h"
|
||||
|
||||
#if __STDC_VERSION__ >= 201112L && __STDC_NO_ATOMICS__ != 1
|
||||
// modern C with atomics
|
||||
#include <stdatomic.h>
|
||||
typedef atomic_int signal_flag_type;
|
||||
#else
|
||||
// no atomics available
|
||||
typedef volatile sig_atomic_t signal_flag_type;
|
||||
#endif
|
||||
|
||||
// Capture information
|
||||
capture_config_t capture_cfg =
|
||||
{ 0 };
|
||||
|
||||
signal_flag_type sighup_received = 0;
|
||||
|
||||
void sighup_handler(int signum)
|
||||
{
|
||||
sighup_received = 1;
|
||||
}
|
||||
|
||||
void
|
||||
capture_init(size_t limit, bool rtp_capture, bool rotate, size_t pcap_buffer_size)
|
||||
{
|
||||
|
@ -63,6 +81,13 @@ capture_init(size_t limit, bool rtp_capture, bool rotate, size_t pcap_buffer_siz
|
|||
capture_cfg.paused = 0;
|
||||
capture_cfg.sources = vector_create(1, 1);
|
||||
|
||||
// set up SIGHUP handler
|
||||
// the handler will be served by any of the running threads
|
||||
// so we just set a flag and check it in dump_packet
|
||||
// so it is only acted upon before then next packed will be dumped
|
||||
if (signal(SIGHUP, sighup_handler) == SIG_ERR)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
// Fixme
|
||||
if (setting_has_value(SETTING_CAPTURE_STORAGE, "none")) {
|
||||
capture_cfg.storage = CAPTURE_STORAGE_NONE;
|
||||
|
@ -383,7 +408,7 @@ parse_packet(u_char *info, const struct pcap_pkthdr *header, const u_char *packe
|
|||
capture_eep_send(pkt);
|
||||
#endif
|
||||
// Store this packets in output file
|
||||
dump_packet(capture_cfg.pd, pkt);
|
||||
capture_dump_packet(pkt);;
|
||||
// If storage is disabled, delete frames payload
|
||||
if (capture_cfg.storage == 0) {
|
||||
packet_free_frames(pkt);
|
||||
|
@ -1204,17 +1229,39 @@ capture_packet_time_sorter(vector_t *vector, void *item)
|
|||
}
|
||||
|
||||
void
|
||||
capture_set_dumper(pcap_dumper_t *dumper)
|
||||
capture_set_dumper(pcap_dumper_t *dumper, ino_t dump_inode)
|
||||
{
|
||||
capture_cfg.pd = dumper;
|
||||
capture_cfg.dump_inode = dump_inode;
|
||||
}
|
||||
|
||||
void
|
||||
capture_dump_packet(packet_t *packet)
|
||||
{
|
||||
dump_packet(capture_cfg.pd, packet);
|
||||
if (sighup_received && capture_cfg.pd) {
|
||||
// we got a SIGHUP: reopen the dump file because it could have been renamed
|
||||
// we don't need to care about locking or other threads accessing in parallel
|
||||
// because dump_open ensures count(capture_cfg.sources) == 1
|
||||
|
||||
// check if the file has actually changed
|
||||
// only reopen if it has, otherwise we would overwrite the existing one
|
||||
struct stat sb;
|
||||
if (stat(capture_cfg.dumpfilename, &sb) == -1 ||
|
||||
sb.st_ino != capture_cfg.dump_inode)
|
||||
{
|
||||
pcap_dump_close(capture_cfg.pd);
|
||||
capture_cfg.pd = dump_open(capture_cfg.dumpfilename, &capture_cfg.dump_inode);
|
||||
}
|
||||
|
||||
sighup_received = 0;
|
||||
|
||||
// error reopening capture file: we can't capture anymore
|
||||
if (!capture_cfg.pd)
|
||||
return;
|
||||
}
|
||||
|
||||
dump_packet(capture_cfg.pd, packet);
|
||||
}
|
||||
|
||||
int8_t
|
||||
datalink_size(int datalink)
|
||||
|
@ -1264,13 +1311,31 @@ datalink_size(int datalink)
|
|||
}
|
||||
|
||||
pcap_dumper_t *
|
||||
dump_open(const char *dumpfile)
|
||||
dump_open(const char *dumpfile, ino_t* dump_inode)
|
||||
{
|
||||
capture_info_t *capinfo;
|
||||
|
||||
if (vector_count(capture_cfg.sources) == 1) {
|
||||
capture_cfg.dumpfilename = dumpfile;
|
||||
capinfo = vector_first(capture_cfg.sources);
|
||||
return pcap_dump_open(capinfo->handle, dumpfile);
|
||||
|
||||
FILE *fp = fopen(dumpfile,"wb+");
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
struct stat sb;
|
||||
if (fstat(fileno(fp), &sb) == -1)
|
||||
return NULL;
|
||||
|
||||
if (dump_inode) {
|
||||
// read out the files inode, allows to later check if it has changed
|
||||
struct stat sb;
|
||||
if (fstat(fileno(fp), &sb) == -1)
|
||||
return NULL;
|
||||
*dump_inode = sb.st_ino;
|
||||
}
|
||||
|
||||
return pcap_dump_fopen(capinfo->handle, fp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -139,6 +139,10 @@ struct capture_config {
|
|||
struct bpf_program fp;
|
||||
//! libpcap dump file handler
|
||||
pcap_dumper_t *pd;
|
||||
//! libpcap dump file name
|
||||
const char *dumpfilename;
|
||||
//! inode of the dump file we have open
|
||||
ino_t dump_inode;
|
||||
//! Capture sources
|
||||
vector_t *sources;
|
||||
//! Capture Lock. Avoid parsing and handling data at the same time
|
||||
|
@ -469,7 +473,7 @@ capture_close();
|
|||
* @brief Set general capture dumper
|
||||
*/
|
||||
void
|
||||
capture_set_dumper(pcap_dumper_t *dumper);
|
||||
capture_set_dumper(pcap_dumper_t *dumper, ino_t dump_inode);
|
||||
|
||||
/**
|
||||
* @brief Store a packet in dumper file
|
||||
|
@ -488,7 +492,7 @@ datalink_size(int datalink);
|
|||
* @brief Open a new dumper file for capture handler
|
||||
*/
|
||||
pcap_dumper_t *
|
||||
dump_open(const char *dumpfile);
|
||||
dump_open(const char *dumpfile, ino_t* dump_inode);
|
||||
|
||||
/**
|
||||
* @brief Store a packet in dump file
|
||||
|
|
|
@ -465,7 +465,7 @@ save_to_file(ui_t *ui)
|
|||
|
||||
if (info->saveformat == SAVE_PCAP || info->saveformat == SAVE_PCAP_RTP) {
|
||||
// Open dump file
|
||||
pd = dump_open(fullfile);
|
||||
pd = dump_open(fullfile, NULL);
|
||||
if (access(fullfile, W_OK) != 0) {
|
||||
dialog_run("%s", capture_last_error());
|
||||
return 1;
|
||||
|
|
|
@ -381,8 +381,11 @@ main(int argc, char* argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (outfile) {
|
||||
capture_set_dumper(dump_open(outfile));
|
||||
if (outfile)
|
||||
{
|
||||
ino_t dump_inode;
|
||||
pcap_dumper_t *dumper = dump_open(outfile, &dump_inode);
|
||||
capture_set_dumper(dumper, dump_inode);
|
||||
}
|
||||
|
||||
// Remove Input files vector
|
||||
|
|
Loading…
Reference in New Issue