From 70ae440e158c316e7727af731a9e9af58febf955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20T=C3=BCxen?= Date: Mon, 16 May 2011 15:19:54 +0000 Subject: [PATCH] Make remote capturing settings a per interface thing. You can now configure that you want to capture on multiple remote interfaces on mulitple hosts. Improve some #ifdef mess in dumpcap. svn path=/trunk/; revision=37178 --- capture_opts.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++ capture_opts.h | 13 ++++- dumpcap.c | 23 +++----- 3 files changed, 166 insertions(+), 15 deletions(-) diff --git a/capture_opts.c b/capture_opts.c index b9530556ba..b29e782f58 100644 --- a/capture_opts.c +++ b/capture_opts.c @@ -70,6 +70,17 @@ capture_opts_init(capture_options *capture_opts, void *cf) capture_opts->default_options.buffer_size = 1; /* 1 MB */ #endif capture_opts->default_options.monitor_mode = FALSE; +#ifdef HAVE_PCAP_REMOTE + capture_opts->default_options.src_type = CAPTURE_IFLOCAL; + capture_opts->default_options.remote_host = NULL; + capture_opts->default_options.remote_port = NULL; + capture_opts->default_options.auth_type = CAPTURE_AUTH_NULL; + capture_opts->default_options.auth_username = NULL; + capture_opts->default_options.auth_password = NULL; + capture_opts->default_options.datatx_udp = FALSE; + capture_opts->default_options.nocap_rpcap = TRUE; + capture_opts->default_options.nocap_local = FALSE; +#endif #ifdef HAVE_PCAP_SETSAMPLING capture_opts->default_options.sampling_method = CAPTURE_SAMP_NONE; capture_opts->default_options.sampling_param = 0; @@ -159,6 +170,27 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio g_log(log_domain, log_level, "Buffer size[%02d] : %d (MB)", i, interface_opts.buffer_size); #endif g_log(log_domain, log_level, "Monitor Mode[%02d] : %s", i, interface_opts.monitor_mode?"TRUE":"FALSE"); +#ifdef HAVE_PCAP_REMOTE + g_log(log_domain, log_level, "Capture source[%02d] : %s", i, + interface_opts.src_type == CAPTURE_IFLOCAL ? "Local interface" : + interface_opts.src_type == CAPTURE_IFREMOTE ? "Remote interface" : + "Unknown"); + if (interface_opts.src_type == CAPTURE_IFREMOTE) { + g_log(log_domain, log_level, "Remote host[%02d] : %s", i, interface_opts.remote_host); + g_log(log_domain, log_level, "Remote port[%02d] : %s", i, interface_opts.remote_port); + } + g_log(log_domain, log_level, "Authentication[%02d] : %s", i, + interface_opts.auth_type == CAPTURE_AUTH_NULL ? "Null" : + interface_opts.auth_type == CAPTURE_AUTH_PWD ? "By username/password" : + "Unknown"); + if (interface_opts.auth_type == CAPTURE_AUTH_PWD) { + g_log(log_domain, log_level, "Auth username[%02d] : %s", i, interface_opts.auth_password); + g_log(log_domain, log_level, "Auth password[%02d] : ", i); + } + g_log(log_domain, log_level, "UDP data tfer[%02d] : %u", i, interface_opts.datatx_udp); + g_log(log_domain, log_level, "No cap. RPCAP[%02d] : %u", i, interface_opts.nocap_rpcap); + g_log(log_domain, log_level, "No cap. local[%02d] : %u", i, interface_opts.nocap_local); +#endif #ifdef HAVE_PCAP_SETSAMPLING g_log(log_domain, log_level, "Sampling meth.[%02d] : %d", i, interface_opts.sampling_method); g_log(log_domain, log_level, "Sampling param.[%02d]: %d", i, interface_opts.sampling_param); @@ -174,6 +206,27 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio g_log(log_domain, log_level, "Buffer size[df] : %d (MB)", capture_opts->default_options.buffer_size); #endif g_log(log_domain, log_level, "Monitor Mode[df] : %s", capture_opts->default_options.monitor_mode?"TRUE":"FALSE"); +#ifdef HAVE_PCAP_REMOTE + g_log(log_domain, log_level, "Capture source[df] : %s", + capture_opts->default_options.src_type == CAPTURE_IFLOCAL ? "Local interface" : + capture_opts->default_options.src_type == CAPTURE_IFREMOTE ? "Remote interface" : + "Unknown"); + if (capture_opts->default_options.src_type == CAPTURE_IFREMOTE) { + g_log(log_domain, log_level, "Remote host[df] : %s", capture_opts->default_options.remote_host); + g_log(log_domain, log_level, "Remote port[df] : %s", capture_opts->default_options.remote_port); + } + g_log(log_domain, log_level, "Authentication[df] : %s", + capture_opts->default_options.auth_type == CAPTURE_AUTH_NULL ? "Null" : + capture_opts->default_options.auth_type == CAPTURE_AUTH_PWD ? "By username/password" : + "Unknown"); + if (capture_opts->default_options.auth_type == CAPTURE_AUTH_PWD) { + g_log(log_domain, log_level, "Auth username[df] : %s", capture_opts->default_options.auth_password); + g_log(log_domain, log_level, "Auth password[df] : "); + } + g_log(log_domain, log_level, "UDP data tfer[df] : %u", capture_opts->default_options.datatx_udp); + g_log(log_domain, log_level, "No cap. RPCAP[df] : %u", capture_opts->default_options.nocap_rpcap); + g_log(log_domain, log_level, "No cap. local[df] : %u", capture_opts->default_options.nocap_local); +#endif #ifdef HAVE_PCAP_SETSAMPLING g_log(log_domain, log_level, "Sampling meth. [df]: %d", capture_opts->default_options.sampling_method); g_log(log_domain, log_level, "Sampling param.[df]: %d", capture_opts->default_options.sampling_param); @@ -200,6 +253,10 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio g_log(log_domain, log_level, "No capture RPCAP : %u", capture_opts->nocap_rpcap); g_log(log_domain, log_level, "No capture local : %u", capture_opts->nocap_local); #endif +#ifdef HAVE_PCAP_SETSAMPLING + g_log(log_domain, log_level, "Sampling meth. : %d", capture_opts->sampling_method); + g_log(log_domain, log_level, "Sampling param. : %d", capture_opts->sampling_param); +#endif #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) g_log(log_domain, log_level, "BufferSize : %u (MB)", capture_opts->buffer_size); #endif @@ -419,6 +476,20 @@ get_auth_arguments(capture_options *capture_opts, const char *arg) capture_opts->auth_type = CAPTURE_AUTH_PWD; capture_opts->auth_username = g_strdup(arg); capture_opts->auth_password = g_strdup(p); + if (capture_opts->ifaces->len > 0) { + interface_options interface_opts; + + interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); + capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); + interface_opts.auth_type = CAPTURE_AUTH_PWD; + interface_opts.auth_username = g_strdup(arg); + interface_opts.auth_password = g_strdup(p); + g_array_append_val(capture_opts->ifaces, interface_opts); + } else { + capture_opts->default_options.auth_type = CAPTURE_AUTH_PWD; + capture_opts->default_options.auth_username = g_strdup(arg); + capture_opts->default_options.auth_password = g_strdup(p); + } *colonp = ':'; return TRUE; } @@ -503,6 +574,33 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str interface_opts.buffer_size = capture_opts->default_options.buffer_size; #endif interface_opts.monitor_mode = capture_opts->default_options.monitor_mode; +#ifdef HAVE_PCAP_REMOTE + interface_opts.src_type = capture_opts->default_options.src_type; + if (capture_opts->default_options.remote_host) { + interface_opts.remote_host = g_strdup(capture_opts->default_options.remote_host); + } else { + interface_opts.remote_host = NULL; + } + if (capture_opts->default_options.remote_port) { + interface_opts.remote_port = g_strdup(capture_opts->default_options.remote_port); + } else { + interface_opts.remote_port = NULL; + } + interface_opts.auth_type = capture_opts->default_options.auth_type; + if (capture_opts->default_options.auth_username) { + interface_opts.auth_username = g_strdup(capture_opts->default_options.auth_username); + } else { + interface_opts.auth_username = NULL; + } + if (capture_opts->default_options.auth_password) { + interface_opts.auth_password = g_strdup(capture_opts->default_options.auth_password); + } else { + interface_opts.auth_password = NULL; + } + interface_opts.datatx_udp = capture_opts->default_options.datatx_udp; + interface_opts.nocap_rpcap = capture_opts->default_options.nocap_rpcap; + interface_opts.nocap_local = capture_opts->default_options.nocap_local; +#endif #ifdef HAVE_PCAP_SETSAMPLING interface_opts.sampling_method = capture_opts->default_options.sampling_method; interface_opts.sampling_param = capture_opts->default_options.sampling_param; @@ -639,6 +737,16 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_ #ifdef HAVE_PCAP_REMOTE case 'r': capture_opts->nocap_rpcap = FALSE; + if (capture_opts->ifaces->len > 0) { + interface_options interface_opts; + + interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); + capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); + interface_opts.nocap_rpcap = FALSE; + g_array_append_val(capture_opts->ifaces, interface_opts); + } else { + capture_opts->default_options.nocap_rpcap = FALSE; + } break; #endif case 's': /* Set the snapshot (capture) length */ @@ -667,6 +775,16 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_ #ifdef HAVE_PCAP_REMOTE case 'u': capture_opts->datatx_udp = TRUE; + if (capture_opts->ifaces->len > 0) { + interface_options interface_opts; + + interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); + capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); + interface_opts.datatx_udp = TRUE; + g_array_append_val(capture_opts->ifaces, interface_opts); + } else { + capture_opts->default_options.datatx_udp = TRUE; + } break; #endif case 'w': /* Write to capture file x */ @@ -853,6 +971,33 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt interface_opts.buffer_size = capture_opts->default_options.buffer_size; #endif interface_opts.monitor_mode = capture_opts->default_options.monitor_mode; +#ifdef HAVE_PCAP_REMOTE + interface_opts.src_type = capture_opts->default_options.src_type; + if (capture_opts->default_options.remote_host) { + interface_opts.remote_host = g_strdup(capture_opts->default_options.remote_host); + } else { + interface_opts.remote_host = NULL; + } + if (capture_opts->default_options.remote_port) { + interface_opts.remote_port = g_strdup(capture_opts->default_options.remote_port); + } else { + interface_opts.remote_port = NULL; + } + interface_opts.auth_type = capture_opts->default_options.auth_type; + if (capture_opts->default_options.auth_username) { + interface_opts.auth_username = g_strdup(capture_opts->default_options.auth_username); + } else { + interface_opts.auth_username = NULL; + } + if (capture_opts->default_options.auth_password) { + interface_opts.auth_password = g_strdup(capture_opts->default_options.auth_password); + } else { + interface_opts.auth_password = NULL; + } + interface_opts.datatx_udp = capture_opts->default_options.datatx_udp; + interface_opts.nocap_rpcap = capture_opts->default_options.nocap_rpcap; + interface_opts.nocap_local = capture_opts->default_options.nocap_local; +#endif #ifdef HAVE_PCAP_SETSAMPLING interface_opts.sampling_method = capture_opts->default_options.sampling_method; interface_opts.sampling_param = capture_opts->default_options.sampling_param; diff --git a/capture_opts.h b/capture_opts.h index f67632169d..8eda37b2b2 100644 --- a/capture_opts.h +++ b/capture_opts.h @@ -84,6 +84,17 @@ typedef struct interface_options_tag { int buffer_size; #endif gboolean monitor_mode; +#ifdef HAVE_PCAP_REMOTE + capture_source src_type; + gchar *remote_host; + gchar *remote_port; + capture_auth auth_type; + gchar *auth_username; + gchar *auth_password; + gboolean datatx_udp; + gboolean nocap_rpcap; + gboolean nocap_local; +#endif #ifdef HAVE_PCAP_SETSAMPLING capture_sampling sampling_method; int sampling_param; @@ -115,7 +126,7 @@ typedef struct capture_options_tag { interface_options default_options; #ifdef HAVE_PCAP_REMOTE /**< XXX: Should this whole block moved to - *< interface_options ?*/ + *< interface_options ? Yes!*/ capture_source src_type; /**< Capturing on remote interface */ gchar *remote_host; /**< Host name or network address *< for remote capturing */ diff --git a/dumpcap.c b/dumpcap.c index fac1f58025..552b169fce 100644 --- a/dumpcap.c +++ b/dumpcap.c @@ -524,18 +524,13 @@ relinquish_all_capabilities(void) static pcap_t * 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]) { pcap_t *pcap_h; #ifdef HAVE_PCAP_CREATE int err; #endif -#ifdef HAVE_PCAP_REMOTE +#if defined(HAVE_PCAP_OPEN) && defined(HAVE_PCAP_REMOTE) struct pcap_rmtauth auth; #endif @@ -544,7 +539,7 @@ open_capture_device(interface_options *interface_opts, if they succeed; to tell if that's happened, we have to clear the error buffer, and check if it's still a null string. */ (*open_err_str)[0] = '\0'; -#ifdef HAVE_PCAP_OPEN +#if defined(HAVE_PCAP_OPEN) && defined(HAVE_PCAP_REMOTE) /* * If we're opening a remote device, use pcap_open(); that's currently * the only open routine that supports remote devices. @@ -552,17 +547,17 @@ open_capture_device(interface_options *interface_opts, if (strncmp (interface_opts->name, "rpcap://", 8) == 0) { auth.type = capture_opts->auth_type == CAPTURE_AUTH_PWD ? RPCAP_RMTAUTH_PWD : RPCAP_RMTAUTH_NULL; - auth.username = capture_opts->auth_username; - auth.password = capture_opts->auth_password; + auth.username = interface_opts->auth_username; + auth.password = interface_opts->auth_password; pcap_h = pcap_open(interface_opts->name, interface_opts->snaplen, /* flags */ (interface_opts->promisc_mode ? PCAP_OPENFLAG_PROMISCUOUS : 0) | - (capture_opts->datatx_udp ? PCAP_OPENFLAG_DATATX_UDP : 0) | - (capture_opts->nocap_rpcap ? PCAP_OPENFLAG_NOCAPTURE_RPCAP : 0), + (interface_opts->datatx_udp ? PCAP_OPENFLAG_DATATX_UDP : 0) | + (interface_opts->nocap_rpcap ? PCAP_OPENFLAG_NOCAPTURE_RPCAP : 0), CAP_READ_TIMEOUT, &auth, *open_err_str); } else -#endif /* HAVE_PCAP_OPEN */ +#endif { /* * If we're not opening a remote device, use pcap_create() and @@ -747,7 +742,7 @@ show_filter_code(capture_options *capture_opts) for (j = 0; j < capture_opts->ifaces->len; j++) { interface_opts = g_array_index(capture_opts->ifaces, interface_options, j); - pcap_h = open_capture_device(&interface_opts, capture_opts, &open_err_str); + pcap_h = open_capture_device(&interface_opts, &open_err_str); if (pcap_h == NULL) { /* Open failed; get messages */ get_capture_device_open_failure_messages(open_err_str, @@ -2246,7 +2241,7 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld, #endif g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_open_input : %s", interface_opts.name); - pcap_opts.pcap_h = open_capture_device(&interface_opts, capture_opts, &open_err_str); + pcap_opts.pcap_h = open_capture_device(&interface_opts, &open_err_str); if (pcap_opts.pcap_h != NULL) { /* we've opened "iface" as a network device */