Get -L and -d working with multiple interface. Internally get some functions

using the array of interface data.
Improve output of -L by printing the interface name.

svn path=/trunk/; revision=37120
This commit is contained in:
Michael Tüxen 2011-05-13 11:28:51 +00:00
parent a7c5d642d5
commit cfe3d2d0da
5 changed files with 84 additions and 77 deletions

View File

@ -661,17 +661,17 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
} }
void void
capture_opts_print_if_capabilities(if_capabilities_t *caps, capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name,
gboolean monitor_mode) gboolean monitor_mode)
{ {
GList *lt_entry; GList *lt_entry;
data_link_info_t *data_link_info; data_link_info_t *data_link_info;
if (caps->can_set_rfmon) if (caps->can_set_rfmon)
fprintf_stderr("Data link types when %sin monitor mode (use option -y to set):\n", fprintf_stderr("Data link types of interface %s when %sin monitor mode (use option -y to set):\n",
monitor_mode ? "" : "not "); name, monitor_mode ? "" : "not ");
else else
fprintf_stderr("Data link types (use option -y to set):\n"); fprintf_stderr("Data link types of interface %s (use option -y to set):\n", name);
for (lt_entry = caps->data_link_types; lt_entry != NULL; for (lt_entry = caps->data_link_types; lt_entry != NULL;
lt_entry = g_list_next(lt_entry)) { lt_entry = g_list_next(lt_entry)) {
data_link_info = (data_link_info_t *)lt_entry->data; data_link_info = (data_link_info_t *)lt_entry->data;

View File

@ -214,7 +214,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
/* print interface capabilities, including link layer types */ /* print interface capabilities, including link layer types */
extern void extern void
capture_opts_print_if_capabilities(if_capabilities_t *caps, capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name,
gboolean monitor_mode); gboolean monitor_mode);
/* print list of interfaces */ /* print list of interfaces */

146
dumpcap.c
View File

@ -522,7 +522,12 @@ relinquish_all_capabilities(void)
#endif #endif
static pcap_t * static pcap_t *
open_capture_device(capture_options *capture_opts, open_capture_device(interface_options *interface_opts,
#ifdef HAVE_PCAP_OPEN
capture_options *capture_opts,
#else
capture_options *capture_opts _U_,
#endif
char (*open_err_str)[PCAP_ERRBUF_SIZE]) char (*open_err_str)[PCAP_ERRBUF_SIZE])
{ {
pcap_t *pcap_h; pcap_t *pcap_h;
@ -543,17 +548,15 @@ open_capture_device(capture_options *capture_opts,
* If we're opening a remote device, use pcap_open(); that's currently * If we're opening a remote device, use pcap_open(); that's currently
* the only open routine that supports remote devices. * the only open routine that supports remote devices.
*/ */
if (strncmp (capture_opts->iface, "rpcap://", 8) == 0) { if (strncmp (interface_opts->name, "rpcap://", 8) == 0) {
auth.type = capture_opts->auth_type == CAPTURE_AUTH_PWD ? auth.type = capture_opts->auth_type == CAPTURE_AUTH_PWD ?
RPCAP_RMTAUTH_PWD : RPCAP_RMTAUTH_NULL; RPCAP_RMTAUTH_PWD : RPCAP_RMTAUTH_NULL;
auth.username = capture_opts->auth_username; auth.username = capture_opts->auth_username;
auth.password = capture_opts->auth_password; auth.password = capture_opts->auth_password;
pcap_h = pcap_open(capture_opts->iface, pcap_h = pcap_open(interface_opts->name, interface_opts->snaplen,
capture_opts->has_snaplen ? capture_opts->snaplen :
WTAP_MAX_PACKET_SIZE,
/* flags */ /* flags */
(capture_opts->promisc_mode ? PCAP_OPENFLAG_PROMISCUOUS : 0) | (interface_opts->promisc_mode ? PCAP_OPENFLAG_PROMISCUOUS : 0) |
(capture_opts->datatx_udp ? PCAP_OPENFLAG_DATATX_UDP : 0) | (capture_opts->datatx_udp ? PCAP_OPENFLAG_DATATX_UDP : 0) |
(capture_opts->nocap_rpcap ? PCAP_OPENFLAG_NOCAPTURE_RPCAP : 0), (capture_opts->nocap_rpcap ? PCAP_OPENFLAG_NOCAPTURE_RPCAP : 0),
CAP_READ_TIMEOUT, &auth, *open_err_str); CAP_READ_TIMEOUT, &auth, *open_err_str);
@ -566,16 +569,16 @@ open_capture_device(capture_options *capture_opts,
* size, otherwise use pcap_open_live(). * size, otherwise use pcap_open_live().
*/ */
#ifdef HAVE_PCAP_CREATE #ifdef HAVE_PCAP_CREATE
pcap_h = pcap_create(capture_opts->iface, *open_err_str); pcap_h = pcap_create(interface_opts->name, *open_err_str);
if (pcap_h != NULL) { if (pcap_h != NULL) {
pcap_set_snaplen(pcap_h, capture_opts->has_snaplen ? capture_opts->snaplen : WTAP_MAX_PACKET_SIZE); pcap_set_snaplen(pcap_h, interface_opts->snaplen);
pcap_set_promisc(pcap_h, capture_opts->promisc_mode); pcap_set_promisc(pcap_h, interface_opts->promisc_mode);
pcap_set_timeout(pcap_h, CAP_READ_TIMEOUT); pcap_set_timeout(pcap_h, CAP_READ_TIMEOUT);
if (capture_opts->buffer_size > 1) { if (interface_opts->buffer_size > 1) {
pcap_set_buffer_size(pcap_h, capture_opts->buffer_size * 1024 * 1024); pcap_set_buffer_size(pcap_h, interface_opts->buffer_size * 1024 * 1024);
} }
if (capture_opts->monitor_mode) if (interface_opts->monitor_mode)
pcap_set_rfmon(pcap_h, 1); pcap_set_rfmon(pcap_h, 1);
err = pcap_activate(pcap_h); err = pcap_activate(pcap_h);
if (err < 0) { if (err < 0) {
@ -589,10 +592,8 @@ open_capture_device(capture_options *capture_opts,
} }
} }
#else #else
pcap_h = pcap_open_live(capture_opts->iface, pcap_h = pcap_open_live(interface_opts->interface_opts, interface_opts->snaplen,
capture_opts->has_snaplen ? capture_opts->snaplen : interface_opts->promisc_mode, CAP_READ_TIMEOUT,
WTAP_MAX_PACKET_SIZE,
capture_opts->promisc_mode, CAP_READ_TIMEOUT,
*open_err_str); *open_err_str);
#endif #endif
} }
@ -728,6 +729,7 @@ compile_capture_filter(const char *iface, pcap_t *pcap_h,
static gboolean static gboolean
show_filter_code(capture_options *capture_opts) show_filter_code(capture_options *capture_opts)
{ {
interface_options interface_opts;
pcap_t *pcap_h; pcap_t *pcap_h;
gchar open_err_str[PCAP_ERRBUF_SIZE]; gchar open_err_str[PCAP_ERRBUF_SIZE];
char errmsg[MSG_MAX_LENGTH+1]; char errmsg[MSG_MAX_LENGTH+1];
@ -735,47 +737,50 @@ show_filter_code(capture_options *capture_opts)
struct bpf_program fcode; struct bpf_program fcode;
struct bpf_insn *insn; struct bpf_insn *insn;
u_int i; u_int i;
gint j;
pcap_h = open_capture_device(capture_opts, &open_err_str); for (j = 0; j < capture_opts->number_of_ifaces; j++) {
if (pcap_h == NULL) { interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
/* Open failed; get messages */ pcap_h = open_capture_device(&interface_opts, capture_opts, &open_err_str);
get_capture_device_open_failure_messages(open_err_str, if (pcap_h == NULL) {
capture_opts->iface, /* Open failed; get messages */
errmsg, sizeof errmsg, get_capture_device_open_failure_messages(open_err_str,
secondary_errmsg, interface_opts.name,
sizeof secondary_errmsg); errmsg, sizeof errmsg,
/* And report them */ secondary_errmsg,
report_capture_error(errmsg, secondary_errmsg); sizeof secondary_errmsg);
return FALSE; /* And report them */
} report_capture_error(errmsg, secondary_errmsg);
return FALSE;
}
/* Set the link-layer type. */ /* Set the link-layer type. */
if (!set_pcap_linktype(pcap_h, capture_opts, errmsg, sizeof errmsg, if (!set_pcap_linktype(pcap_h, capture_opts, errmsg, sizeof errmsg,
secondary_errmsg, sizeof secondary_errmsg)) { secondary_errmsg, sizeof secondary_errmsg)) {
pcap_close(pcap_h);
report_capture_error(errmsg, secondary_errmsg);
return FALSE;
}
/* OK, try to compile the capture filter. */
if (!compile_capture_filter(interface_opts.name, pcap_h, &fcode,
interface_opts.cfilter)) {
pcap_close(pcap_h);
report_cfilter_error(interface_opts.cfilter, errmsg);
return FALSE;
}
pcap_close(pcap_h); pcap_close(pcap_h);
report_capture_error(errmsg, secondary_errmsg);
return FALSE;
}
/* OK, try to compile the capture filter. */ /* Now print the filter code. */
if (!compile_capture_filter(capture_opts->iface, pcap_h, &fcode, insn = fcode.bf_insns;
capture_opts->cfilter)) {
pcap_close(pcap_h);
report_cfilter_error(capture_opts->cfilter, errmsg);
return FALSE;
}
pcap_close(pcap_h);
for (i = 0; i < fcode.bf_len; insn++, i++)
printf("%s\n", bpf_image(insn, i));
}
if (capture_child) { if (capture_child) {
/* Let our parent know we succeeded. */ /* Let our parent know we succeeded. */
pipe_write_block(2, SP_SUCCESS, NULL); pipe_write_block(2, SP_SUCCESS, NULL);
} }
/* Now print the filter code. */
insn = fcode.bf_insns;
for (i = 0; i < fcode.bf_len; insn++, i++)
printf("%s\n", bpf_image(insn, i));
return TRUE; return TRUE;
} }
#endif #endif
@ -2139,6 +2144,7 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
{ {
gchar open_err_str[PCAP_ERRBUF_SIZE]; gchar open_err_str[PCAP_ERRBUF_SIZE];
gchar *sync_msg_str; gchar *sync_msg_str;
interface_options interface_opts;
#ifdef _WIN32 #ifdef _WIN32
int err; int err;
gchar *sync_secondary_msg_str; gchar *sync_secondary_msg_str;
@ -2196,21 +2202,21 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
return FALSE; return FALSE;
} }
#endif #endif
interface_opts = g_array_index(capture_opts->ifaces, interface_options, 0);
ld->pcap_h = open_capture_device(capture_opts, &open_err_str); ld->pcap_h = open_capture_device(&interface_opts, capture_opts, &open_err_str);
if (ld->pcap_h != NULL) { if (ld->pcap_h != NULL) {
/* we've opened "iface" as a network device */ /* we've opened "iface" as a network device */
#ifdef _WIN32 #ifdef _WIN32
/* try to set the capture buffer size */ /* try to set the capture buffer size */
if (capture_opts->buffer_size > 1 && if (interface_opts.buffer_size > 1 &&
pcap_setbuff(ld->pcap_h, capture_opts->buffer_size * 1024 * 1024) != 0) { pcap_setbuff(ld->pcap_h, interface_opts.buffer_size * 1024 * 1024) != 0) {
sync_secondary_msg_str = g_strdup_printf( sync_secondary_msg_str = g_strdup_printf(
"The capture buffer size of %dMB seems to be too high for your machine,\n" "The capture buffer size of %dMB seems to be too high for your machine,\n"
"the default of 1MB will be used.\n" "the default of 1MB will be used.\n"
"\n" "\n"
"Nonetheless, the capture is started.\n", "Nonetheless, the capture is started.\n",
capture_opts->buffer_size); interface_opts.buffer_size);
report_capture_error("Couldn't set the capture buffer size!", report_capture_error("Couldn't set the capture buffer size!",
sync_secondary_msg_str); sync_secondary_msg_str);
g_free(sync_secondary_msg_str); g_free(sync_secondary_msg_str);
@ -2219,7 +2225,7 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
#if defined(HAVE_PCAP_REMOTE) && defined(HAVE_PCAP_SETSAMPLING) #if defined(HAVE_PCAP_REMOTE) && defined(HAVE_PCAP_SETSAMPLING)
if ((capture_opts->sampling_method != CAPTURE_SAMP_NONE) && if ((capture_opts->sampling_method != CAPTURE_SAMP_NONE) &&
(strncmp (capture_opts->iface, "rpcap://", 8) == 0)) (strncmp (interface_opts.name, "rpcap://", 8) == 0))
{ {
struct pcap_samp *samp; struct pcap_samp *samp;
@ -2259,11 +2265,11 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
if (!set_pcap_linktype(ld->pcap_h, capture_opts, errmsg, errmsg_len, if (!set_pcap_linktype(ld->pcap_h, capture_opts, errmsg, errmsg_len,
secondary_errmsg, secondary_errmsg_len)) secondary_errmsg, secondary_errmsg_len))
return FALSE; return FALSE;
ld->linktype = get_pcap_linktype(ld->pcap_h, capture_opts->iface); ld->linktype = get_pcap_linktype(ld->pcap_h, interface_opts.name);
} else { } else {
/* We couldn't open "iface" as a network device. */ /* We couldn't open "iface" as a network device. */
/* Try to open it as a pipe */ /* Try to open it as a pipe */
cap_pipe_open_live(capture_opts->iface, &ld->cap_pipe_hdr, ld, errmsg, (int) errmsg_len); cap_pipe_open_live(interface_opts.name, &ld->cap_pipe_hdr, ld, errmsg, (int) errmsg_len);
#ifndef _WIN32 #ifndef _WIN32
if (ld->cap_pipe_fd == -1) if (ld->cap_pipe_fd == -1)
@ -2274,7 +2280,7 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
if (ld->cap_pipe_err == PIPNEXIST) { if (ld->cap_pipe_err == PIPNEXIST) {
/* Pipe doesn't exist, so output message for interface */ /* Pipe doesn't exist, so output message for interface */
get_capture_device_open_failure_messages(open_err_str, get_capture_device_open_failure_messages(open_err_str,
capture_opts->iface, interface_opts.name,
errmsg, errmsg,
errmsg_len, errmsg_len,
secondary_errmsg, secondary_errmsg,
@ -2352,7 +2358,7 @@ static void capture_loop_close_input(loop_data *ld)
/* init the capture filter */ /* init the capture filter */
static initfilter_status_t static initfilter_status_t
capture_loop_init_filter(pcap_t *pcap_h, gboolean from_cap_pipe, capture_loop_init_filter(pcap_t *pcap_h, gboolean from_cap_pipe,
gchar * iface, gchar * cfilter) gchar * name, gchar * cfilter)
{ {
struct bpf_program fcode; struct bpf_program fcode;
@ -2361,7 +2367,7 @@ capture_loop_init_filter(pcap_t *pcap_h, gboolean from_cap_pipe,
/* capture filters only work on real interfaces */ /* capture filters only work on real interfaces */
if (cfilter && !from_cap_pipe) { if (cfilter && !from_cap_pipe) {
/* A capture filter was specified; set it up. */ /* A capture filter was specified; set it up. */
if (!compile_capture_filter(iface, pcap_h, &fcode, cfilter)) { if (!compile_capture_filter(name, pcap_h, &fcode, cfilter)) {
/* Treat this specially - our caller might try to compile this /* Treat this specially - our caller might try to compile this
as a display filter and, if that succeeds, warn the user that as a display filter and, if that succeeds, warn the user that
the display and capture filter syntaxes are different. */ the display and capture filter syntaxes are different. */
@ -3859,10 +3865,10 @@ main(int argc, char *argv[])
/* Let the user know what interfaces were chosen. */ /* Let the user know what interfaces were chosen. */
/* get_interface_descriptive_name() is not available! */ /* get_interface_descriptive_name() is not available! */
for (i = 0; i < global_capture_opts.number_of_ifaces; i++) { for (i = 0; i < global_capture_opts.number_of_ifaces; i++) {
interface_options options; interface_options interface_opts;
options = g_array_index(global_capture_opts.ifaces, interface_options, i); interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Interface: %s\n", options.name); g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Interface: %s\n", interface_opts.name);
} }
if (list_link_layer_types) { if (list_link_layer_types) {
@ -3872,20 +3878,20 @@ main(int argc, char *argv[])
gint i; gint i;
for (i = 0; i < global_capture_opts.number_of_ifaces; i++) { for (i = 0; i < global_capture_opts.number_of_ifaces; i++) {
interface_options options; interface_options interface_opts;
options = g_array_index(global_capture_opts.ifaces, interface_options, i); interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
caps = get_if_capabilities(options.name, caps = get_if_capabilities(interface_opts.name,
options.monitor_mode, &err_str); interface_opts.monitor_mode, &err_str);
if (caps == NULL) { if (caps == NULL) {
cmdarg_err("The capabilities of the capture device \"%s\" could not be obtained (%s).\n" cmdarg_err("The capabilities of the capture device \"%s\" could not be obtained (%s).\n"
"Please check to make sure you have sufficient permissions, and that\n" "Please check to make sure you have sufficient permissions, and that\n"
"you have the proper interface or pipe specified.", options.name, err_str); "you have the proper interface or pipe specified.", interface_opts.name, err_str);
g_free(err_str); g_free(err_str);
exit_main(2); exit_main(2);
} }
if (caps->data_link_types == NULL) { if (caps->data_link_types == NULL) {
cmdarg_err("The capture device \"%s\" has no data link types.", options.name); cmdarg_err("The capture device \"%s\" has no data link types.", interface_opts.name);
exit_main(2); exit_main(2);
} }
if (machine_readable) /* tab-separated values to stdout */ if (machine_readable) /* tab-separated values to stdout */
@ -3893,8 +3899,8 @@ main(int argc, char *argv[])
print_machine_readable_if_capabilities(caps); print_machine_readable_if_capabilities(caps);
else else
/* XXX: We might want to print also the interface name */ /* XXX: We might want to print also the interface name */
capture_opts_print_if_capabilities(caps, capture_opts_print_if_capabilities(caps, interface_opts.name,
options.monitor_mode); interface_opts.monitor_mode);
free_if_capabilities(caps); free_if_capabilities(caps);
} }
exit_main(0); exit_main(0);

View File

@ -2742,7 +2742,8 @@ main(int argc, char *argv[])
cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface); cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
exit(2); exit(2);
} }
capture_opts_print_if_capabilities(caps, global_capture_opts.monitor_mode); capture_opts_print_if_capabilities(caps, global_capture_opts.iface,
global_capture_opts.monitor_mode);
free_if_capabilities(caps); free_if_capabilities(caps);
exit(0); exit(0);
} }

View File

@ -1780,7 +1780,7 @@ main(int argc, char *argv[])
cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface); cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
return 2; return 2;
} }
capture_opts_print_if_capabilities(caps, capture_opts_print_if_capabilities(caps, global_capture_opts.iface,
global_capture_opts.monitor_mode); global_capture_opts.monitor_mode);
free_if_capabilities(caps); free_if_capabilities(caps);
return 0; return 0;