#include <stdio.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
#ifdef HAVE_LIBPCAP
#include <string.h>
#include <ui/exit_codes.h>
#include <wsutil/file_util.h>
#include <wsutil/ws_pipe.h>
+#include <wsutil/ws_assert.h>
#include "capture/capture_ifinfo.h"
#include "capture/capture-pcap-util.h"
capture_opts->default_options.extcap = NULL;
capture_opts->default_options.extcap_fifo = NULL;
capture_opts->default_options.extcap_args = NULL;
- capture_opts->default_options.extcap_pipedata = NULL;
capture_opts->default_options.extcap_pid = WS_INVALID_PID;
+ capture_opts->default_options.extcap_pipedata = NULL;
+ capture_opts->default_options.extcap_stderr = NULL;
+ capture_opts->default_options.extcap_stdout_watch = 0;
+ capture_opts->default_options.extcap_stderr_watch = 0;
#ifdef _WIN32
capture_opts->default_options.extcap_pipe_h = INVALID_HANDLE_VALUE;
capture_opts->default_options.extcap_control_in_h = INVALID_HANDLE_VALUE;
capture_opts->has_file_duration = FALSE;
capture_opts->file_duration = 60.0; /* 1 min */
capture_opts->has_file_interval = FALSE;
+ capture_opts->has_nametimenum = FALSE;
capture_opts->file_interval = 60; /* 1 min */
capture_opts->has_file_packets = FALSE;
capture_opts->file_packets = 0;
capture_opts->autostop_files = 1;
capture_opts->has_autostop_packets = FALSE;
capture_opts->autostop_packets = 0;
+ capture_opts->has_autostop_written_packets = FALSE;
+ capture_opts->autostop_written_packets = 0;
capture_opts->has_autostop_filesize = FALSE;
capture_opts->autostop_filesize = 1000; /* 1 MB */
capture_opts->has_autostop_duration = FALSE;
capture_opts->autostop_duration = 60.0; /* 1 min */
- capture_opts->capture_comment = NULL;
capture_opts->output_to_pipe = FALSE;
capture_opts->capture_child = FALSE;
+ capture_opts->stop_after_extcaps = FALSE;
+ capture_opts->wait_for_extcap_cbs = FALSE;
capture_opts->print_file_names = FALSE;
capture_opts->print_name_to = NULL;
+ capture_opts->temp_dir = NULL;
capture_opts->compress_type = NULL;
+ capture_opts->closed_msg = NULL;
+ capture_opts->extcap_terminate_id = 0;
}
void
capture_opts->all_ifaces = NULL;
}
g_free(capture_opts->save_file);
+ g_free(capture_opts->temp_dir);
+
+ if (capture_opts->closed_msg) {
+ g_free(capture_opts->closed_msg);
+ capture_opts->closed_msg = NULL;
+ }
+ if (capture_opts->extcap_terminate_id > 0) {
+ g_source_remove(capture_opts->extcap_terminate_id);
+ capture_opts->extcap_terminate_id = 0;
+ }
}
/* log content of capture_opts */
ws_log(log_domain, log_level, "Promiscuous Mode[%02d]: %s", i, interface_opts->promisc_mode?"TRUE":"FALSE");
ws_log(log_domain, log_level, "Extcap[%02d] : %s", i, interface_opts->extcap ? interface_opts->extcap : "(unspecified)");
ws_log(log_domain, log_level, "Extcap FIFO[%02d] : %s", i, interface_opts->extcap_fifo ? interface_opts->extcap_fifo : "(unspecified)");
- ws_log(log_domain, log_level, "Extcap PID[%02d] : %d", i, interface_opts->extcap_pid);
+ ws_log(log_domain, log_level, "Extcap PID[%02d] : %"PRIdMAX, i, (intmax_t)interface_opts->extcap_pid);
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
ws_log(log_domain, log_level, "Buffer size[%02d] : %d (MB)", i, interface_opts->buffer_size);
#endif
ws_log(log_domain, log_level, "FileDuration (%u) : %.3f", capture_opts->has_file_duration, capture_opts->file_duration);
ws_log(log_domain, log_level, "FileInterval (%u) : %u", capture_opts->has_file_interval, capture_opts->file_interval);
ws_log(log_domain, log_level, "FilePackets (%u) : %u", capture_opts->has_file_packets, capture_opts->file_packets);
+ ws_log(log_domain, log_level, "FileNameType : %s", (capture_opts->has_nametimenum) ? "prefix_time_num.suffix" : "prefix_num_time.suffix");
ws_log(log_domain, log_level, "RingNumFiles (%u) : %u", capture_opts->has_ring_num_files, capture_opts->ring_num_files);
ws_log(log_domain, log_level, "RingPrintFiles (%u) : %s", capture_opts->print_file_names, (capture_opts->print_file_names ? capture_opts->print_name_to : ""));
ws_log(log_domain, log_level, "AutostopFiles (%u) : %u", capture_opts->has_autostop_files, capture_opts->autostop_files);
ws_log(log_domain, log_level, "AutostopPackets (%u) : %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
+ ws_log(log_domain, log_level, "AutostopWrittenPackets (%u) : %u", capture_opts->has_autostop_written_packets, capture_opts->autostop_written_packets);
ws_log(log_domain, log_level, "AutostopFilesize(%u) : %u (KB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
ws_log(log_domain, log_level, "AutostopDuration(%u) : %.3f", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
+ ws_log(log_domain, log_level, "Temporary Directory : %s", capture_opts->temp_dir && capture_opts->temp_dir[0] ? capture_opts->temp_dir : g_get_tmp_dir());
}
/*
capture_opts->has_autostop_files = TRUE;
capture_opts->autostop_files = get_positive_int(p,"autostop files");
} else if (strcmp(autostoparg,"packets") == 0) {
- capture_opts->has_autostop_packets = TRUE;
- capture_opts->autostop_packets = get_positive_int(p,"packet count");
+ capture_opts->has_autostop_written_packets = TRUE;
+ capture_opts->autostop_written_packets = get_positive_int(p,"packet write count");
} else {
return FALSE;
}
} else if (strcmp(arg,"interval") == 0) {
capture_opts->has_file_interval = TRUE;
capture_opts->file_interval = get_positive_int(p, "ring buffer interval");
+ } else if (strcmp(arg,"nametimenum") == 0) {
+ int val = get_positive_int(p, "file name: time before num");
+ capture_opts->has_nametimenum = (val > 1);
} else if (strcmp(arg,"packets") == 0) {
capture_opts->has_file_packets = TRUE;
capture_opts->file_packets = get_positive_int(p, "ring buffer packet count");
* On UN*X, however, users are more used to interface names,
* and may find it helpful to see them.
*/
- return g_strdup_printf("%s: %s", friendly_name, name);
+ return ws_strdup_printf("%s: %s", friendly_name, name);
}
#endif
interface_opts.extcap_args = NULL;
interface_opts.extcap_pid = WS_INVALID_PID;
interface_opts.extcap_pipedata = NULL;
+ interface_opts.extcap_stderr = NULL;
+ interface_opts.extcap_stdout_watch = 0;
+ interface_opts.extcap_stderr_watch = 0;
#ifdef _WIN32
interface_opts.extcap_pipe_h = INVALID_HANDLE_VALUE;
interface_opts.extcap_control_in_h = INVALID_HANDLE_VALUE;
capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p)
{
int status, snaplen;
+ ws_statb64 fstat;
switch(opt) {
- case LONGOPT_NUM_CAP_COMMENT: /* capture comment */
- if (capture_opts->capture_comment) {
- cmdarg_err("--capture-comment can be set only once per file");
- return 1;
- }
- capture_opts->capture_comment = g_strdup(optarg_str_p);
- break;
case 'a': /* autostop criteria */
if (set_autostop_criterion(capture_opts, optarg_str_p) == FALSE) {
cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg_str_p);
if (strcmp(optarg_str_p, "none") == 0) {
;
} else if (strcmp(optarg_str_p, "gzip") == 0) {
+#ifdef HAVE_ZLIB
;
+#else
+ cmdarg_err("'gzip' compression is not supported");
+ return 1;
+#endif
} else {
+#ifdef HAVE_ZLIB
cmdarg_err("parameter of --compress-type can be 'none' or 'gzip'");
+#else
+ cmdarg_err("parameter of --compress-type can only be 'none'");
+#endif
return 1;
}
capture_opts->compress_type = g_strdup(optarg_str_p);
break;
+ case LONGOPT_CAPTURE_TMPDIR: /* capture temporary directory */
+ if (capture_opts->temp_dir) {
+ cmdarg_err("--temp-dir can be set only once");
+ return 1;
+ }
+ if (ws_stat64(optarg_str_p, &fstat) < 0) {
+ cmdarg_err("Can't set temporary directory %s: %s",
+ optarg_str_p, g_strerror(errno));
+ return 1;
+ }
+ if (!S_ISDIR(fstat.st_mode)) {
+ cmdarg_err("Can't set temporary directory %s: not a directory",
+ optarg_str_p);
+ return 1;
+ }
+#ifdef S_IRWXU
+ if ((fstat.st_mode & S_IRWXU) != S_IRWXU) {
+ cmdarg_err("Can't set temporary directory %s: not a writable directory",
+ optarg_str_p);
+ return 1;
+ }
+#endif /* S_IRWXU */
+ capture_opts->temp_dir = g_strdup(optarg_str_p);
+ break;
default:
/* the caller is responsible to send us only the right opt's */
- g_assert_not_reached();
+ ws_assert_not_reached();
}
return 0;
if (interface_opts->extcap_args)
g_hash_table_unref(interface_opts->extcap_args);
if (interface_opts->extcap_pid != WS_INVALID_PID)
- ws_pipe_close((ws_pipe_t *) interface_opts->extcap_pipedata);
+ ws_warning("Extcap still running during interface delete");
g_free(interface_opts->extcap_pipedata);
+ if (interface_opts->extcap_stderr)
+ g_string_free(interface_opts->extcap_stderr, TRUE);
g_free(interface_opts->extcap_control_in);
g_free(interface_opts->extcap_control_out);
#ifdef HAVE_PCAP_REMOTE
/* Now fill the list up again. */
for (i = 0; i < capture_opts->all_ifaces->len; i++) {
device = &g_array_index(capture_opts->all_ifaces, interface_t, i);
- if (!device->hidden && device->selected) {
+ if (device->selected) {
interface_opts.name = g_strdup(device->name);
interface_opts.descr = g_strdup(device->friendly_name);
interface_opts.ifname = NULL;
if (interface_opts.extcap_args)
g_hash_table_ref(interface_opts.extcap_args);
interface_opts.extcap_pipedata = NULL;
+ interface_opts.extcap_stderr = NULL;
#ifdef _WIN32
interface_opts.extcap_pipe_h = INVALID_HANDLE_VALUE;
interface_opts.extcap_control_in_h = INVALID_HANDLE_VALUE;