Add support for handling multiple interfaces as command line

parameters. An array of interface specific data is handled
in addition to the current way.
This change should not have any effect right now, it will
be used by dumpcap when supporting multiple interfaces
(and tshark/wireshark... in the future).


svn path=/trunk/; revision=37082
This commit is contained in:
Michael Tüxen 2011-05-12 16:54:16 +00:00
parent 12d8f46860
commit 2d6cd58f91
2 changed files with 235 additions and 63 deletions

View File

@ -55,68 +55,80 @@ static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_
void
capture_opts_init(capture_options *capture_opts, void *cf)
{
capture_opts->cf = cf;
capture_opts->cfilter = g_strdup(""); /* No capture filter string specified */
capture_opts->iface = NULL; /* Default is "pick the first interface" */
capture_opts->iface_descr = NULL;
capture_opts->cf = cf;
capture_opts->cfilter = g_strdup(""); /* No capture filter string specified */
capture_opts->iface = NULL; /* Default is "pick the first interface" */
capture_opts->iface_descr = NULL;
capture_opts->ifaces = g_array_new(FALSE, FALSE, sizeof(interface_options));
capture_opts->number_of_ifaces = 0;
capture_opts->default_options.name = g_strdup("");
capture_opts->default_options.descr = g_strdup("");
capture_opts->default_options.cfilter = g_strdup("");
capture_opts->default_options.snaplen = 0;
capture_opts->default_options.linktype = -1;
capture_opts->default_options.promisc_mode = TRUE;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
capture_opts->default_options.buffer_size = 1; /* 1 MB */
#endif
capture_opts->default_options.monitor_mode = FALSE;
#ifdef HAVE_PCAP_REMOTE
capture_opts->src_type = CAPTURE_IFLOCAL;
capture_opts->remote_host = NULL;
capture_opts->remote_port = NULL;
capture_opts->auth_type = CAPTURE_AUTH_NULL;
capture_opts->auth_username = NULL;
capture_opts->auth_password = NULL;
capture_opts->datatx_udp = FALSE;
capture_opts->nocap_rpcap = TRUE;
capture_opts->nocap_local = FALSE;
capture_opts->src_type = CAPTURE_IFLOCAL;
capture_opts->remote_host = NULL;
capture_opts->remote_port = NULL;
capture_opts->auth_type = CAPTURE_AUTH_NULL;
capture_opts->auth_username = NULL;
capture_opts->auth_password = NULL;
capture_opts->datatx_udp = FALSE;
capture_opts->nocap_rpcap = TRUE;
capture_opts->nocap_local = FALSE;
#endif
#ifdef HAVE_PCAP_SETSAMPLING
capture_opts->sampling_method = CAPTURE_SAMP_NONE;
capture_opts->sampling_param = 0;
capture_opts->sampling_method = CAPTURE_SAMP_NONE;
capture_opts->sampling_param = 0;
#endif
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
capture_opts->buffer_size = 1; /* 1 MB */
capture_opts->buffer_size = 1; /* 1 MB */
#endif
capture_opts->has_snaplen = FALSE;
capture_opts->snaplen = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
infinite, in effect */
capture_opts->promisc_mode = TRUE; /* promiscuous mode is the default */
capture_opts->monitor_mode = FALSE;
capture_opts->linktype = -1; /* the default linktype */
capture_opts->saving_to_file = FALSE;
capture_opts->save_file = NULL;
capture_opts->group_read_access = FALSE;
capture_opts->use_pcapng = FALSE; /* the default is pcap */
capture_opts->real_time_mode = TRUE;
capture_opts->show_info = TRUE;
capture_opts->quit_after_cap = FALSE;
capture_opts->restart = FALSE;
capture_opts->has_snaplen = FALSE;
capture_opts->snaplen = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
infinite, in effect */
capture_opts->promisc_mode = TRUE; /* promiscuous mode is the default */
capture_opts->monitor_mode = FALSE;
capture_opts->linktype = -1; /* the default linktype */
capture_opts->saving_to_file = FALSE;
capture_opts->save_file = NULL;
capture_opts->group_read_access = FALSE;
capture_opts->use_pcapng = FALSE; /* the default is pcap */
capture_opts->real_time_mode = TRUE;
capture_opts->show_info = TRUE;
capture_opts->quit_after_cap = FALSE;
capture_opts->restart = FALSE;
capture_opts->multi_files_on = FALSE;
capture_opts->has_file_duration = FALSE;
capture_opts->file_duration = 60; /* 1 min */
capture_opts->has_ring_num_files = FALSE;
capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
capture_opts->multi_files_on = FALSE;
capture_opts->has_file_duration = FALSE;
capture_opts->file_duration = 60; /* 1 min */
capture_opts->has_ring_num_files = FALSE;
capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
capture_opts->has_autostop_files = FALSE;
capture_opts->autostop_files = 1;
capture_opts->has_autostop_packets = FALSE;
capture_opts->autostop_packets = 0;
capture_opts->has_autostop_filesize = FALSE;
capture_opts->autostop_filesize = 1024; /* 1 MB */
capture_opts->has_autostop_duration = FALSE;
capture_opts->autostop_duration = 60; /* 1 min */
capture_opts->has_autostop_files = FALSE;
capture_opts->autostop_files = 1;
capture_opts->has_autostop_packets = FALSE;
capture_opts->autostop_packets = 0;
capture_opts->has_autostop_filesize = FALSE;
capture_opts->autostop_filesize = 1024; /* 1 MB */
capture_opts->has_autostop_duration = FALSE;
capture_opts->autostop_duration = 60; /* 1 min */
capture_opts->fork_child = -1; /* invalid process handle */
capture_opts->fork_child = -1; /* invalid process handle */
#ifdef _WIN32
capture_opts->signal_pipe_write_fd = -1;
capture_opts->signal_pipe_write_fd = -1;
#endif
capture_opts->state = CAPTURE_STOPPED;
capture_opts->output_to_pipe = FALSE;
capture_opts->state = CAPTURE_STOPPED;
capture_opts->output_to_pipe = FALSE;
#ifndef _WIN32
capture_opts->owner = getuid();
capture_opts->group = getgid();
capture_opts->owner = getuid();
capture_opts->group = getgid();
#endif
}
@ -124,13 +136,33 @@ capture_opts_init(capture_options *capture_opts, void *cf)
/* log content of capture_opts */
void
capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_options *capture_opts) {
gint i;
g_log(log_domain, log_level, "CAPTURE OPTIONS :");
g_log(log_domain, log_level, "CFile : 0x%p", capture_opts->cf);
g_log(log_domain, log_level, "Filter : %s", capture_opts->cfilter);
g_log(log_domain, log_level, "Interface : %s", capture_opts->iface);
/* iface_descr may not been filled in and some C Libraries hate a null ptr for %s */
g_log(log_domain, log_level, "Interface Descr : %s",
capture_opts->iface_descr ? capture_opts->iface_descr : "<null>");
for (i = 0; i < capture_opts->number_of_ifaces; i++) {
interface_options options;
options = g_array_index(capture_opts->ifaces, interface_options, i);
g_log(log_domain, log_level, "Interface name[%02d] : %s", i, options.name);
g_log(log_domain, log_level, "Interface Descr[%02d]: %s", i, options.descr);
g_log(log_domain, log_level, "Capture filter[%02d] : %s", i, options.cfilter);
g_log(log_domain, log_level, "Snap length[%02d] : %d", i, options.snaplen);
g_log(log_domain, log_level, "Link Type[%02d] : %d", i, options.linktype);
g_log(log_domain, log_level, "Promiscous Mode[%02d]: %s", i, options.promisc_mode?"TRUE":"FALSE");
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
g_log(log_domain, log_level, "Buffer size[%02d] : %d (MB)", i, options.buffer_size);
#endif
g_log(log_domain, log_level, "Monitor Mode[%02d] : %s", i, options.monitor_mode?"TRUE":"FALSE");
}
g_log(log_domain, log_level, "Interface name[df] : %s", capture_opts->default_options.name);
g_log(log_domain, log_level, "Capture filter[df] : %s", capture_opts->default_options.cfilter);
g_log(log_domain, log_level, "Snap length[df] : %d", capture_opts->default_options.snaplen);
g_log(log_domain, log_level, "Link Type[df] : %d", capture_opts->default_options.linktype);
g_log(log_domain, log_level, "Promiscous Mode[df]: %s", capture_opts->default_options.promisc_mode?"TRUE":"FALSE");
#ifdef HAVE_PCAP_REMOTE
g_log(log_domain, log_level, "Capture source : %s",
capture_opts->src_type == CAPTURE_IFLOCAL ? "Local interface" :
@ -359,6 +391,7 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
if_info_t *if_info;
int err;
gchar *err_str;
interface_options options;
/*
@ -405,6 +438,7 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
return 1;
}
capture_opts->iface = g_strdup(if_info->name);
options.name = g_strdup(if_info->name);
/* We don't set iface_descr here because doing so requires
* capture_ui_utils.c which requires epan/prefs.c which is
* probably a bit too much dependency for here...
@ -412,7 +446,20 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
free_interface_list(if_list);
} else {
capture_opts->iface = g_strdup(optarg_str_p);
options.name = g_strdup(optarg_str_p);
}
options.descr = g_strdup(capture_opts->default_options.descr);
options.cfilter = g_strdup(capture_opts->default_options.cfilter);
options.snaplen = capture_opts->default_options.snaplen;
options.linktype = capture_opts->default_options.linktype;
options.promisc_mode = capture_opts->default_options.promisc_mode;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
options.buffer_size = capture_opts->default_options.buffer_size;
#endif
options.monitor_mode = capture_opts->default_options.monitor_mode;
g_array_append_val(capture_opts->ifaces, options);
capture_opts->number_of_ifaces++;
return 0;
}
@ -447,6 +494,16 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
case 'B': /* Buffer size */
capture_opts->buffer_size = get_positive_int(optarg_str_p, "buffer size");
if (capture_opts->number_of_ifaces > 0) {
interface_options options;
options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->number_of_ifaces - 1);
capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->number_of_ifaces - 1);
options.buffer_size = get_positive_int(optarg_str_p, "buffer size");
g_array_append_val(capture_opts->ifaces, options);
} else {
capture_opts->default_options.buffer_size = get_positive_int(optarg_str_p, "buffer size");
}
break;
#endif
case 'c': /* Capture n packets */
@ -454,13 +511,25 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
capture_opts->autostop_packets = get_positive_int(optarg_str_p, "packet count");
break;
case 'f': /* capture filter */
if (capture_opts->has_cfilter) {
if ((!capture_opts->use_pcapng) && (capture_opts->has_cfilter)) {
cmdarg_err("More than one -f argument specified");
return 1;
}
capture_opts->has_cfilter = TRUE;
g_free(capture_opts->cfilter);
capture_opts->cfilter = g_strdup(optarg_str_p);
if (capture_opts->number_of_ifaces > 0) {
interface_options options;
options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->number_of_ifaces - 1);
capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->number_of_ifaces - 1);
g_free(options.cfilter);
options.cfilter = g_strdup(capture_opts->cfilter);
g_array_append_val(capture_opts->ifaces, options);
} else {
g_free(capture_opts->default_options.cfilter);
capture_opts->default_options.cfilter = g_strdup(capture_opts->cfilter);
}
break;
case 'H': /* Hide capture info dialog box */
capture_opts->show_info = FALSE;
@ -474,6 +543,16 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
#ifdef HAVE_PCAP_CREATE
case 'I': /* Capture in monitor mode */
capture_opts->monitor_mode = TRUE;
if (capture_opts->number_of_ifaces > 0) {
interface_options options;
options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->number_of_ifaces - 1);
capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->number_of_ifaces - 1);
options.monitor_mode = TRUE;
g_array_append_val(capture_opts->ifaces, options);
} else {
capture_opts->default_options.monitor_mode = TRUE;
}
break;
#endif
case 'k': /* Start capture immediately */
@ -493,6 +572,16 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
break;
case 'p': /* Don't capture in promiscuous mode */
capture_opts->promisc_mode = FALSE;
if (capture_opts->number_of_ifaces > 0) {
interface_options options;
options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->number_of_ifaces - 1);
capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->number_of_ifaces - 1);
options.promisc_mode = FALSE;
g_array_append_val(capture_opts->ifaces, options);
} else {
capture_opts->default_options.promisc_mode = FALSE;
}
break;
case 'Q': /* Quit after capture (just capture to file) */
capture_opts->quit_after_cap = TRUE;
@ -512,6 +601,16 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
*/
if (capture_opts->snaplen == 0)
capture_opts->snaplen = WTAP_MAX_PACKET_SIZE;
if (capture_opts->number_of_ifaces > 0) {
interface_options options;
options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->number_of_ifaces - 1);
capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->number_of_ifaces - 1);
options.snaplen = capture_opts->snaplen;
g_array_append_val(capture_opts->ifaces, options);
} else {
capture_opts->default_options.snaplen = capture_opts->snaplen;
}
break;
case 'S': /* "Real-Time" mode: used for following file ala tail -f */
capture_opts->real_time_mode = TRUE;
@ -542,6 +641,16 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
optarg_str_p);
return 1;
}
if (capture_opts->number_of_ifaces > 0) {
interface_options options;
options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->number_of_ifaces - 1);
capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->number_of_ifaces - 1);
options.linktype = linktype_name_to_val(optarg_str_p);
g_array_append_val(capture_opts->ifaces, options);
} else {
capture_opts->default_options.linktype = linktype_name_to_val(optarg_str_p);
}
break;
default:
/* the caller is responsible to send us only the right opt's */
@ -599,10 +708,23 @@ capture_opts_print_interfaces(GList *if_list)
void capture_opts_trim_snaplen(capture_options *capture_opts, int snaplen_min)
{
gint i;
interface_options options;
if (capture_opts->snaplen < 1)
capture_opts->snaplen = WTAP_MAX_PACKET_SIZE;
else if (capture_opts->snaplen < snaplen_min)
capture_opts->snaplen = snaplen_min;
for (i = 0; i < capture_opts->number_of_ifaces; i++) {
options = g_array_index(capture_opts->ifaces, interface_options, 0);
capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, 0);
if (options.snaplen < 1)
options.snaplen = WTAP_MAX_PACKET_SIZE;
else if (options.snaplen < snaplen_min)
options.snaplen = snaplen_min;
g_array_append_val(capture_opts->ifaces, options);
}
}
@ -629,14 +751,16 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt
if_info_t *if_info;
int err;
gchar *err_str;
interface_options options;
/* Did the user specify an interface to use? */
if (capture_opts->iface == NULL) {
if (capture_opts->number_of_ifaces == 0) {
/* No - is a default specified in the preferences file? */
if (capture_device != NULL) {
/* Yes - use it. */
capture_opts->iface = g_strdup(capture_device);
options.name = g_strdup(capture_device);
/* We don't set iface_descr here because doing so requires
* capture_ui_utils.c which requires epan/prefs.c which is
* probably a bit too much dependency for here...
@ -660,12 +784,23 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt
}
if_info = (if_info_t *)if_list->data; /* first interface */
capture_opts->iface = g_strdup(if_info->name);
options.name = g_strdup(if_info->name);
/* We don't set iface_descr here because doing so requires
* capture_ui_utils.c which requires epan/prefs.c which is
* probably a bit too much dependency for here...
*/
free_interface_list(if_list);
}
options.cfilter = g_strdup(capture_opts->default_options.cfilter);
options.snaplen = capture_opts->default_options.snaplen;
options.linktype = capture_opts->default_options.linktype;
options.promisc_mode = capture_opts->default_options.promisc_mode;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
options.buffer_size = capture_opts->default_options.buffer_size;
#endif
options.monitor_mode = capture_opts->default_options.monitor_mode;
g_array_append_val(capture_opts->ifaces, options);
capture_opts->number_of_ifaces++;
}
return TRUE;

View File

@ -73,21 +73,46 @@ typedef enum {
} capture_sampling;
#endif
typedef struct interface_options_tag {
gchar *name;
gchar *descr;
gchar *cfilter;
int snaplen;
int linktype;
gboolean promisc_mode;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
int buffer_size;
#endif
gboolean monitor_mode;
} interface_options;
/** Capture options coming from user interface */
typedef struct capture_options_tag {
/* general */
void *cf; /**< handle to cfile (note: untyped handle) */
gboolean has_cfilter; /**< TRUE if capture filter specified on command line */
gchar *cfilter; /**< Capture filter string */
gchar *iface; /**< the network interface to capture from */
gchar *cfilter; /**< Capture filter string
*< XXX: Can finally be be removed.
*< Replaced by interface_options.cfilter */
gchar *iface; /**< the network interface to capture from
*< XXX: Can finally be be removed.
*< Replaced by interface_options.name */
gchar *iface_descr; /**< A human readable description of iface.
*< NOTE: capture_opts.c is not able to
*< set this field because doing so
*< requires too many dependencies.
*< Readers of this field should use
*< get_iface_description() from
*< "capture_ui_utils.h" to access it. */
*< "capture_ui_utils.h" to access it.
*< XXX: Can finally be be removed.
*< Replaced by interface_options.descr */
GArray *ifaces; /**< array of interfaces.
Currently only used by dumpcap. */
gint number_of_ifaces; /**< Curently only used by dumpcap. */
interface_options default_options;
#ifdef HAVE_PCAP_REMOTE
/**< XXX: Should this whole block moved to
*< interface_options ?*/
capture_source src_type; /**< Capturing on remote interface */
gchar *remote_host; /**< Host name or network address
*< for remote capturing */
@ -102,19 +127,31 @@ typedef struct capture_options_tag {
gboolean nocap_local; /**< TODO: Whether to capture local traffic */
#endif
#ifdef HAVE_PCAP_SETSAMPLING
/**< XXX: Should this whole block moved to
*< interface_options ?*/
capture_sampling sampling_method; /**< PCAP packet sampling method */
int sampling_param; /**< PCAP packet sampling parameter */
#endif
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
int buffer_size; /**< the capture buffer size (MB) */
int buffer_size; /**< the capture buffer size (MB)
*< XXX: Can finally be be removed.
*< Replaced by interface_options.buffer_size */
#endif
gboolean has_snaplen; /**< TRUE if maximum capture packet length
is specified */
int snaplen; /**< Maximum captured packet length */
gboolean promisc_mode; /**< Capture in promiscuous mode */
int snaplen; /**< Maximum captured packet length
*< XXX: Can finally be be removed.
*< Replaced by interface_options.snaplen */
gboolean promisc_mode; /**< Capture in promiscuous mode
*< XXX: Can finally be be removed.
*< Replaced by interface_options.promisc_mode */
int linktype; /**< Data link type to use, or -1 for
"use default" */
gboolean monitor_mode; /**< Capture in monitor mode, if available */
"use default"
*< XXX: Can finally be be removed.
*< Replaced by interface_options.linktype */
gboolean monitor_mode; /**< Capture in monitor mode, if available
*< XXX: Can finally be be removed.
*< Replaced by interface_options.monitor_mode */
gboolean saving_to_file; /**< TRUE if capture is writing to a file */
gchar *save_file; /**< the capture file name */
gboolean group_read_access; /**< TRUE is group read permission needs to be set */