Support for RPCAP features in GUI (from Boris Misenov, see Bug 1366)
authorkukosa <kukosa@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 4 Dec 2007 11:19:29 +0000 (11:19 +0000)
committerkukosa <kukosa@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 4 Dec 2007 11:19:29 +0000 (11:19 +0000)
  - retrieving the list of remote PCAP interfaces
  - password authentication support
  - UDP data fransfer
  - packet sampling (available in WinPcap 4.x)
  etc.

fix problem if non-default rpcap port is used

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@23750 f5534014-38df-0310-8fa8-9805f1628bb7

19 files changed:
Makefile.nmake
acinclude.m4
capture-pcap-util-int.h
capture-pcap-util-unix.c
capture-pcap-util.c
capture-pcap-util.h
capture-wpcap.c
capture_loop.c
capture_opts.c
capture_opts.h
capture_sync.c
capture_ui_utils.c
config.h.win32
config.nmake
configure.in
dumpcap.c
epan/dissectors/packet-ldap.c
epan/dissectors/packet-ldap.h
gtk/capture_dlg.c

index 4f38e2bfcfcdd102251e488278fdf6b6dc3fdd74..12e2b6cb8273c922c31f912d6c50002ea7a4535c 100644 (file)
@@ -305,6 +305,12 @@ config.h   : config.h.win32 config.nmake
            -e "s/@HAVE_PCAP_DATALINK_NAME_TO_VAL@/$(PCAP_DATALINK_NAME_TO_VAL_CONFIG)/" \
            -e "s/@HAVE_PCAP_DATALINK_VAL_TO_NAME@/$(PCAP_DATALINK_VAL_TO_NAME_CONFIG)/" \
            -e "s/@HAVE_PCAP_BREAKLOOP@/$(PCAP_BREAKLOOP_CONFIG)/" \
+           -e "s/@HAVE_REMOTE@/$(PCAP_HAVE_REMOTE_CONFIG)/" \
+           -e "s/@HAVE_PCAP_REMOTE@/$(PCAP_REMOTE_CONFIG)/" \
+           -e "s/@HAVE_PCAP_OPEN@/$(PCAP_OPEN_CONFIG)/" \
+           -e "s/@HAVE_PCAP_FINDALLDEVS_EX@/$(PCAP_FINDALLDEVS_EX_CONFIG)/" \
+           -e "s/@HAVE_PCAP_CREATESRCSTR@/$(PCAP_CREATESRCSTR_CONFIG)/" \
+           -e "s/@HAVE_PCAP_SETSAMPLING@/$(PCAP_SETSAMPLING_CONFIG)/" \
            -e "s/@HAVE_LIBWIRESHARKDLL@/$(LIBWIRESHARK_CONFIG)/" \
            -e "s/@WPCAP_CONSTIFIED@/$(WPCAP_CONSTIFIED_CONFIG)/" \
            -e "s/@HAVE_LIBGNUTLS@/$(GNUTLS_CONFIG)/" \
@@ -1067,3 +1073,4 @@ clean-deps2:
 clean-deps: clean-deps1 clean-deps2
 
 
+
index ff9c31fba92edc4c34bb6622c9946271977f82f3..d711fe83618fb3fdd49faa8575c9461fd6ba9b7b 100644 (file)
@@ -557,6 +557,23 @@ and did you also install that package?]]))
        LIBS="$ac_save_LIBS"
 ])
 
+AC_DEFUN([AC_WIRESHARK_PCAP_REMOTE_CHECK],
+[
+    ac_save_LIBS="$LIBS"
+    LIBS="$PCAP_LIBS $SOCKET_LIBS $NSL_LIBS $LIBS"
+    AC_DEFINE(HAVE_REMOTE, 1, [Define to 1 to enable remote
+              capturing feature in WinPcap library])
+    AC_CHECK_FUNCS(pcap_open pcap_findalldevs_ex pcap_createsrcstr)
+    if test $ac_cv_func_pcap_open = "yes" -a \
+            $ac_cv_func_pcap_findalldevs_ex = "yes" -a \
+            $ac_cv_func_pcap_createsrcstr = "yes" ; then
+        AC_DEFINE(HAVE_PCAP_REMOTE, 1,
+            [Define to 1 if you have WinPcap remote capturing support and prefer to use these new API features.])
+    fi
+    AC_CHECK_FUNCS(pcap_setsampling)
+    LIBS="$ac_save_LIBS"
+])
+
 #
 # AC_WIRESHARK_ZLIB_CHECK
 #
index 3ab330aeddfcb070f7681f9a76aad2d68b37ac13..ccdd54dfdbfc4c6347ff42f4f1f5a9823246503e 100644 (file)
 #define __PCAP_UTIL_INT_H__
 
 #ifdef HAVE_LIBPCAP
+#ifdef HAVE_PCAP_REMOTE
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <pcap.h>
+#endif
 
 extern if_info_t *if_info_new(char *name, char *description);
 extern void if_info_add_address(if_info_t *if_info, struct sockaddr *addr);
 #ifdef HAVE_PCAP_FINDALLDEVS
+#ifdef HAVE_PCAP_REMOTE
+extern GList *get_interface_list_findalldevs_ex(const char *source,
+        struct pcap_rmtauth *auth, int *err, char **err_str);
+#else
 extern GList *get_interface_list_findalldevs(int *err, char **err_str);
 #endif
+#endif
 
 /*
  * Get an error message string for a CANT_GET_INTERFACE_LIST error from
index ea8968b7d0322b8360684c843f3b887c683fe81e..d707cc695ac3eff0a5cd541361a4b44f14a2ca89 100644 (file)
@@ -73,11 +73,50 @@ static void
 search_for_if_cb(gpointer data, gpointer user_data);
 #endif
 
+#ifdef HAVE_PCAP_REMOTE
+GList *
+get_remote_interface_list(const char *hostname, const char *port,
+                          int auth_type, const char *username,
+                          const char *passwd, int *err, char **err_str)
+{
+    struct pcap_rmtauth auth;
+    char source[PCAP_BUF_SIZE];
+    char errbuf[PCAP_ERRBUF_SIZE];
+
+    auth.type = auth_type;
+    auth.username = username;
+    auth.password = passwd;
+
+    if (pcap_createsrcstr(source, PCAP_SRC_IFREMOTE, hostname, port,
+                          NULL, errbuf) == -1) {
+        *err = CANT_GET_INTERFACE_LIST;
+        if (err_str != NULL)
+            *err_str = cant_get_if_list_error_message(errbuf);
+        return NULL;
+    }
+    return get_interface_list_findalldevs_ex(source, &auth, err, err_str);
+}
+#endif
+
 GList *
 get_interface_list(int *err, char **err_str)
 {
 #ifdef HAVE_PCAP_FINDALLDEVS
+#ifdef HAVE_PCAP_REMOTE
+    char source[PCAP_BUF_SIZE];
+    char errbuf[PCAP_ERRBUF_SIZE];
+
+    if (pcap_createsrcstr(source, PCAP_SRC_IFLOCAL,
+                          NULL, NULL, NULL, errbuf) == -1) {
+        *err = CANT_GET_INTERFACE_LIST;
+        if (err_str != NULL)
+            *err_str = cant_get_if_list_error_message(errbuf);
+        return NULL;
+    }
+    return get_interface_list_findalldevs_ex(source, NULL, err, err_str);
+#else
        return get_interface_list_findalldevs(err, err_str);
+#endif
 #else
        GList  *il = NULL;
        gint    nonloopback_pos = 0;
index 1c24afd485500eb5d0a911397d8a5bcda3acc497..4cf7f4995d5b9aea9713949bc1ac0d26947b4452 100644 (file)
@@ -249,15 +249,26 @@ if_info_ip(if_info_t *if_info, pcap_if_t *d)
        }
 }
 
+#ifdef HAVE_PCAP_REMOTE
+GList *
+get_interface_list_findalldevs_ex(const char *source,
+                                  struct pcap_rmtauth *auth,
+                                  int *err, char **err_str)
+#else
 GList *
 get_interface_list_findalldevs(int *err, char **err_str)
+#endif
 {
        GList  *il = NULL;
        pcap_if_t *alldevs, *dev;
        if_info_t *if_info;
        char errbuf[PCAP_ERRBUF_SIZE];
 
+#ifdef HAVE_PCAP_REMOTE
+    if (pcap_findalldevs_ex((char *)source, auth, &alldevs, errbuf) == -1) {
+#else
        if (pcap_findalldevs(&alldevs, errbuf) == -1) {
+#endif
                *err = CANT_GET_INTERFACE_LIST;
                if (err_str != NULL)
                        *err_str = cant_get_if_list_error_message(errbuf);
@@ -367,7 +378,11 @@ get_pcap_linktype_list(char *devname, char **err_str)
 #endif
        data_link_info_t *data_link_info;
 
+#ifdef HAVE_PCAP_OPEN
+       pch = pcap_open(devname, MIN_PACKET_SIZE, 0, 0, NULL, errbuf);
+#else
        pch = pcap_open_live(devname, MIN_PACKET_SIZE, 0, 0, errbuf);
+#endif
        if (pch == NULL) {
                if (err_str != NULL)
                        *err_str = g_strdup(errbuf);
index 6de58441a90b6460340230be3c834c0b23fbf05c..259a8ed48cb022c700fd52095c656811fbf63a04 100644 (file)
@@ -68,6 +68,11 @@ typedef struct {
 } if_addr_t;
 
 GList *get_interface_list(int *err, char **err_str);
+#ifdef HAVE_PCAP_REMOTE
+GList *get_remote_interface_list(const char *hostname, const char *port,
+                                 int auth_type, const char *username,
+                                 const char *passwd, int *err, char **err_str);
+#endif
 
 /* Error values from "get_interface_list()/capture_interface_list()". */
 #define        CANT_GET_INTERFACE_LIST 1       /* error getting list */
index 81d06abecbd6f7f627d00ead31f114c7a0c7d896..04ebe5e3225f2cb2de71d24c8c6355db4bc912b4 100644 (file)
@@ -96,6 +96,17 @@ static void    (*p_pcap_breakloop) (pcap_t *);
 static const char *(*p_pcap_lib_version) (void);
 static int     (*p_pcap_setbuff) (pcap_t *, int dim);
 static int     (*p_pcap_next_ex) (pcap_t *, struct pcap_pkthdr **pkt_header, const u_char **pkt_data);
+#ifdef HAVE_PCAP_REMOTE
+static pcap_t* (*p_pcap_open) (const char *, int, int, int,
+                               struct pcap_rmtauth *, char *);
+static int     (*p_pcap_findalldevs_ex) (char *, struct pcap_rmtauth *,
+                                         pcap_if_t **, char *);
+static int     (*p_pcap_createsrcstr) (char *, int, const char *, const char *,
+                                       const char *, char *);
+#endif
+#ifdef HAVE_PCAP_SETSAMPLING
+static struct pcap_samp* (*p_pcap_setsampling)(pcap_t *);
+#endif
 
 typedef struct {
        const char      *name;
@@ -121,7 +132,16 @@ load_wpcap(void)
                SYM(pcap_geterr, FALSE),
                SYM(pcap_compile, FALSE),
                SYM(pcap_lookupnet, FALSE),
+#ifdef HAVE_PCAP_REMOTE
+               SYM(pcap_open, FALSE),
+               SYM(pcap_findalldevs_ex, FALSE),
+               SYM(pcap_createsrcstr, FALSE),
+#else
                SYM(pcap_open_live, FALSE),
+#endif
+#ifdef HAVE_PCAP_SETSAMPLING
+               SYM(pcap_setsampling, TRUE),
+#endif
                SYM(pcap_loop, FALSE),
                SYM(pcap_freecode, TRUE),
 #ifdef HAVE_PCAP_FINDALLDEVS
@@ -266,6 +286,42 @@ pcap_open_live(char *a, int b, int c, int d, char *e)
        return p_pcap_open_live(a, b, c, d, e);
 }
 
+#ifdef HAVE_PCAP_REMOTE
+pcap_t*
+pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *f)
+{
+    g_assert(has_wpcap);
+    return p_pcap_open(a, b, c, d, e, f);
+}
+
+int
+pcap_findalldevs_ex(char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *d)
+{
+    g_assert(has_wpcap);
+    return p_pcap_findalldevs_ex(a, b, c, d);
+}
+
+int
+pcap_createsrcstr(char *a, int b, const char *c, const char *d, const char *e,
+                  char *f)
+{
+    g_assert(has_wpcap);
+    return p_pcap_createsrcstr(a, b, c, d, e, f);
+}
+#endif
+
+#ifdef HAVE_PCAP_SETSAMPLING
+struct pcap_samp *
+pcap_setsampling(pcap_t *a)
+{
+    g_assert(has_wpcap);
+    if (p_pcap_setsampling != NULL) {
+        return p_pcap_setsampling(a);
+    }
+    return NULL;
+}
+#endif
+
 int
 pcap_loop(pcap_t *a, int b, pcap_handler c, guchar *d)
 {
@@ -465,6 +521,37 @@ int pcap_next_ex (pcap_t *a, struct pcap_pkthdr **b, const u_char **c)
        return p_pcap_next_ex(a, b, c);
 }
 
+#ifdef HAVE_PCAP_REMOTE
+GList *
+get_remote_interface_list(const char *hostname, const char *port,
+                          int auth_type, const char *username,
+                          const char *passwd, int *err, char **err_str)
+{
+    struct pcap_rmtauth auth;
+    char source[PCAP_BUF_SIZE];
+    char errbuf[PCAP_ERRBUF_SIZE];
+    GList *result;
+
+    if (pcap_createsrcstr(source, PCAP_SRC_IFREMOTE, hostname, port,
+                          NULL, errbuf) == -1) {
+        *err = CANT_GET_INTERFACE_LIST;
+        if (err_str != NULL)
+            *err_str = cant_get_if_list_error_message(errbuf);
+        return NULL;
+    }
+
+    auth.type = auth_type;
+    auth.username = g_strdup(username);
+    auth.password = g_strdup(passwd);
+
+    result = get_interface_list_findalldevs_ex(source, &auth, err, err_str);
+    g_free(auth.username);
+    g_free(auth.password);
+
+    return result;
+}
+#endif
+
 /*
  * This will use "pcap_findalldevs()" if we have it, otherwise it'll
  * fall back on "pcap_lookupdev()".
@@ -472,14 +559,29 @@ int pcap_next_ex (pcap_t *a, struct pcap_pkthdr **b, const u_char **c)
 GList *
 get_interface_list(int *err, char **err_str)
 {
+#ifdef HAVE_PCAP_REMOTE
+       char source[PCAP_BUF_SIZE];
+#else
        GList  *il = NULL;
        wchar_t *names;
        char *win95names;
        char ascii_name[MAX_WIN_IF_NAME_LEN + 1];
        char ascii_desc[MAX_WIN_IF_NAME_LEN + 1];
        int i, j;
+#endif
        char errbuf[PCAP_ERRBUF_SIZE];
 
+#ifdef HAVE_PCAP_REMOTE
+    if (p_pcap_createsrcstr(source, PCAP_SRC_IFLOCAL, NULL, NULL,
+                            NULL, errbuf) == -1) {
+        *err = CANT_GET_INTERFACE_LIST;
+        if (err_str != NULL)
+            *err_str = cant_get_if_list_error_message(errbuf);
+        return NULL;
+    }
+    return get_interface_list_findalldevs_ex(source, NULL, err, err_str);
+#else
+
 #ifdef HAVE_PCAP_FINDALLDEVS
        if (p_pcap_findalldevs != NULL)
                return get_interface_list_findalldevs(err, err_str);
@@ -620,6 +722,7 @@ get_interface_list(int *err, char **err_str)
        }
 
        return il;
+#endif  /* HAVE_PCAP_REMOTE */
 }
 
 /*
index 822a95f079859565e0bf1e0ee354f597c1f7fef6..8c602a4a16ed2b3a00d9812a01e871d01dae208a 100644 (file)
@@ -639,6 +639,9 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
   WORD        wVersionRequested;
   WSADATA     wsaData;
 #endif
+#ifdef HAVE_PCAP_REMOTE
+  struct pcap_rmtauth auth;
+#endif
 
 
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_open_input : %s", capture_opts->iface);
@@ -697,11 +700,27 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
      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
+  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;
+
+  ld->pcap_h = pcap_open(capture_opts->iface,
+               capture_opts->has_snaplen ? capture_opts->snaplen :
+                          WTAP_MAX_PACKET_SIZE,
+               /* flags */
+               (capture_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),
+               CAP_READ_TIMEOUT, &auth, open_err_str);
+#else
   ld->pcap_h = pcap_open_live(capture_opts->iface,
                       capture_opts->has_snaplen ? capture_opts->snaplen :
                                                  WTAP_MAX_PACKET_SIZE,
                       capture_opts->promisc_mode, CAP_READ_TIMEOUT,
                       open_err_str);
+#endif
 
   if (ld->pcap_h != NULL) {
     /* we've opened "iface" as a network device */
@@ -720,6 +739,43 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
     }
 #endif
 
+#if defined(HAVE_PCAP_REMOTE) && defined(HAVE_PCAP_SETSAMPLING)
+    if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
+    {
+        struct pcap_samp *samp;
+
+        if ((samp = pcap_setsampling(ld->pcap_h)) != NULL)
+        {
+            switch (capture_opts->sampling_method)
+            {
+                case CAPTURE_SAMP_BY_COUNT:
+                    samp->method = PCAP_SAMP_1_EVERY_N;
+                    break;
+
+                case CAPTURE_SAMP_BY_TIMER:
+                    samp->method = PCAP_SAMP_FIRST_AFTER_N_MS;
+                    break;
+
+                default:
+                    sync_msg_str = g_strdup_printf(
+                            "Unknown sampling method %d specified,\n"
+                            "continue without packet sampling",
+                            capture_opts->sampling_method);
+                    report_capture_error("Couldn't set the capture "
+                            "sampling", sync_msg_str);
+                    g_free(sync_msg_str);
+            }
+            samp->value = capture_opts->sampling_param;
+        }
+        else
+        {
+            report_capture_error("Couldn't set the capture sampling",
+                    "Cannot get packet sampling data structure");
+        }
+
+    }
+#endif
+
     /* setting the data link type only works on real interfaces */
     if (capture_opts->linktype != -1) {
       set_linktype_err_str = set_pcap_linktype(ld->pcap_h, capture_opts->iface,
index 6e9b63152ca4db20533daef8a477e637d363d91c..a72f6c88f007775401d3762595ddd9f333ce4a9b 100644 (file)
@@ -86,6 +86,21 @@ capture_opts_init(capture_options *capture_opts, void *cfile)
   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;
+#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;
+#ifdef HAVE_PCAP_SETSAMPLING
+  capture_opts->sampling_method         = CAPTURE_SAMP_NONE;
+  capture_opts->sampling_param          = 0;
+#endif
+#endif
 #ifdef _WIN32
   capture_opts->buffer_size             = 1;                /* 1 MB */
 #endif
@@ -140,6 +155,27 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
     /* 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>");
+#ifdef HAVE_PCAP_REMOTE
+    g_log(log_domain, log_level, "Capture source     : %s",
+        capture_opts->src_type == CAPTURE_IFLOCAL ? "Local interface" :
+        capture_opts->src_type == CAPTURE_IFREMOTE ? "Remote interface" :
+        "Unknown");
+    if (capture_opts->src_type == CAPTURE_IFREMOTE) {
+        g_log(log_domain, log_level, "Remote host        : %s", capture_opts->remote_host);
+        g_log(log_domain, log_level, "Remote port        : %u", capture_opts->remote_port);
+    }
+    g_log(log_domain, log_level, "Authentication     : %s",
+        capture_opts->auth_type == CAPTURE_AUTH_NULL ? "Null" :
+        capture_opts->auth_type == CAPTURE_AUTH_PWD ? "By username/password" :
+        "Unknown");
+    if (capture_opts->auth_type == CAPTURE_AUTH_PWD) {
+        g_log(log_domain, log_level, "Auth username      : %s", capture_opts->auth_password);
+        g_log(log_domain, log_level, "Auth password      : <hidden>");
+    }
+    g_log(log_domain, log_level, "UDP data transfer  : %u", capture_opts->datatx_udp);
+    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 _WIN32
     g_log(log_domain, log_level, "BufferSize         : %u (MB)", capture_opts->buffer_size);
 #endif
@@ -268,6 +304,73 @@ get_ring_arguments(capture_options *capture_opts, const char *arg)
   return TRUE;
 }
 
+#ifdef HAVE_PCAP_SETSAMPLING
+/*
+ * Given a string of the form "<sampling type>:<value>", as might appear
+ * as an argument to a "-m" option, parse it and set the arguments in
+ * question.  Return an indication of whether it succeeded or failed
+ * in some fashion.
+ */
+static gboolean
+get_sampling_arguments(capture_options *capture_opts, const char *arg)
+{
+    gchar *p = NULL, *colonp;
+
+    colonp = strchr(arg, ':');
+    if (colonp == NULL)
+        return FALSE;
+
+    p = colonp;
+    *p++ = '\0';
+
+    while (isspace((guchar)*p))
+        p++;
+    if (*p == '\0') {
+        *colonp = ':';
+        return FALSE;
+    }
+
+    if (strcmp(arg, "count") == 0) {
+        capture_opts->sampling_method = CAPTURE_SAMP_BY_COUNT;
+        capture_opts->sampling_param = get_positive_int(p, "sampling count");
+    } else if (strcmp(arg, "timer") == 0) {
+        capture_opts->sampling_method = CAPTURE_SAMP_BY_TIMER;
+        capture_opts->sampling_param = get_positive_int(p, "sampling timer");
+    }
+    *colonp = ':';
+    return TRUE;
+}
+#endif
+
+#ifdef HAVE_PCAP_REMOTE
+/*
+ * Given a string of the form "<username>:<password>", as might appear
+ * as an argument to a "-A" option, parse it and set the arguments in
+ * question.  Return an indication of whether it succeeded or failed
+ * in some fashion.
+ */
+static gboolean
+get_auth_arguments(capture_options *capture_opts, const char *arg)
+{
+    gchar *p = NULL, *colonp;
+
+    colonp = strchr(arg, ':');
+    if (colonp == NULL)
+        return FALSE;
+
+    p = colonp;
+    *p++ = '\0';
+
+    while (isspace((guchar)*p))
+        p++;
+
+    capture_opts->auth_type = CAPTURE_AUTH_PWD;
+    capture_opts->auth_username = g_strdup(arg);
+    capture_opts->auth_password = g_strdup(p);
+    *colonp = ':';
+    return TRUE;
+}
+#endif
 
 static int
 capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg)
@@ -348,6 +451,14 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
           return 1;
         }
         break;
+#ifdef HAVE_PCAP_REMOTE
+    case 'A':
+        if (get_auth_arguments(capture_opts, optarg) == FALSE) {
+            cmdarg_err("Invalid or unknown -A arg \"%s\"", optarg);
+            return 1;
+        }
+        break;
+#endif
     case 'b':        /* Ringbuffer option */
         capture_opts->multi_files_on = TRUE;
         if (get_ring_arguments(capture_opts, optarg) == FALSE) {
@@ -386,6 +497,14 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
         *start_capture = TRUE;
         break;
     /*case 'l':*/    /* Automatic scrolling in live capture mode */
+#ifdef HAVE_PCAP_SETSAMPLING
+    case 'm':
+        if (get_sampling_arguments(capture_opts, optarg) == FALSE) {
+            cmdarg_err("Invalid or unknown -m arg \"%s\"", optarg);
+            return 1;
+        }
+        break;
+#endif
     case 'p':        /* Don't capture in promiscuous mode */
         capture_opts->promisc_mode = FALSE;
         break;
@@ -393,6 +512,11 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
         capture_opts->quit_after_cap  = TRUE;
         *start_capture   = TRUE;  /*** -Q implies -k !! ***/
         break;
+#ifdef HAVE_PCAP_REMOTE
+    case 'r':
+        capture_opts->nocap_rpcap = FALSE;
+        break;
+#endif
     case 's':        /* Set the snapshot (capture) length */
         capture_opts->has_snaplen = TRUE;
         capture_opts->snaplen = get_positive_int(optarg, "snapshot length");
@@ -400,6 +524,11 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
     case 'S':        /* "Real-Time" mode: used for following file ala tail -f */
         capture_opts->real_time_mode = TRUE;
         break;
+#ifdef HAVE_PCAP_REMOTE
+    case 'u':
+        capture_opts->datatx_udp = TRUE;
+        break;
+#endif
     case 'w':        /* Write to capture file x */
         capture_opts->saving_to_file = TRUE;
         g_free(capture_opts->save_file);
index c47519329d543011f67232a4bb557936fd59efba..7b91c0947371129ae6de7b78c4676ff4072b57fd 100644 (file)
@@ -40,6 +40,34 @@ typedef enum {
     CAPTURE_RUNNING         /**< capture child signalled ok, capture is running now */
 } capture_state;
 
+#ifdef HAVE_PCAP_REMOTE
+/* Type of capture source */
+typedef enum {
+    CAPTURE_IFLOCAL,        /**< Local network interface */
+    CAPTURE_IFREMOTE        /**< Remote network interface */
+} capture_source;
+
+/* Type of RPCAPD Authentication */
+typedef enum {
+    CAPTURE_AUTH_NULL,      /**< No authentication */
+    CAPTURE_AUTH_PWD        /**< User/password authentication */
+} capture_auth;
+
+#ifdef HAVE_PCAP_SETSAMPLING
+/**
+ * Method of packet sampling (dropping some captured packets),
+ * may require additional integer parameter, marked here as N
+ */
+typedef enum {
+    CAPTURE_SAMP_NONE,      /**< No sampling - capture all packets */
+    CAPTURE_SAMP_BY_COUNT,  /**< Counter-based sampling -
+                                 capture 1 packet from every N */
+    CAPTURE_SAMP_BY_TIMER   /**< Timer-based sampling -
+                                 capture no more than 1 packet
+                                 in N milliseconds */
+} capture_sampling;
+#endif
+#endif
 
 /** Capture options coming from user interface */
 typedef struct capture_options_tag {
@@ -55,7 +83,24 @@ typedef struct capture_options_tag {
                                      *< Readers of this field should use
                                      *< get_iface_description() from
                                      *< "capture_ui_utils.h" to access it. */
-
+#ifdef HAVE_PCAP_REMOTE
+    capture_source src_type;        /**< Capturing on remote interface */
+    gchar    *remote_host;          /**< Host name or network address
+                                     *< for remote capturing */
+    gchar    *remote_port;          /**< TCP port of remote RPCAP server */
+
+    capture_auth  auth_type;
+    gchar    *auth_username;
+    gchar    *auth_password;        /**< Remote authentication parameters */
+
+    gboolean datatx_udp;            /**< Whether to use UDP for data transfer */
+    gboolean nocap_rpcap;           /**< Whether to capture RPCAP own traffic */
+    gboolean nocap_local;           /**< TODO: Whether to capture local traffic */
+#ifdef HAVE_PCAP_SETSAMPLING
+    capture_sampling sampling_method; /**< PCAP packet sampling method */
+    int sampling_param;             /**< PCAP packet sampling parameter */
+#endif
+#endif
 #ifdef _WIN32
     int      buffer_size;           /**< the capture buffer size (MB) */
 #endif
index d07f8a6151272227e679fa5926cac1d95e05e5f3..b2cc825dd504469c92dbafd34db265d82fd1449c 100644 (file)
@@ -251,6 +251,12 @@ sync_pipe_start(capture_options *capture_opts) {
     char sautostop_files[ARGV_NUMBER_LEN];
     char sautostop_filesize[ARGV_NUMBER_LEN];
     char sautostop_duration[ARGV_NUMBER_LEN];
+#ifdef HAVE_PCAP_REMOTE
+    char sauth[256];
+#endif
+#ifdef HAVE_PCAP_SETSAMPLING
+    char ssampling[ARGV_NUMBER_LEN];
+#endif
 #ifdef _WIN32
     char buffer_size[ARGV_NUMBER_LEN];
     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
@@ -352,6 +358,33 @@ sync_pipe_start(capture_options *capture_opts) {
 
     if (!capture_opts->promisc_mode)
       argv = sync_pipe_add_arg(argv, &argc, "-p");
+#ifdef HAVE_PCAP_REMOTE
+    if (capture_opts->datatx_udp)
+      argv = sync_pipe_add_arg(argv, &argc, "-u");
+
+    if (!capture_opts->nocap_rpcap)
+      argv = sync_pipe_add_arg(argv, &argc, "-r");
+
+    if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
+    {
+        argv = sync_pipe_add_arg(argv, &argc, "-A");
+        g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
+                   capture_opts->auth_password);
+        argv = sync_pipe_add_arg(argv, &argc, sauth);
+    }
+#endif
+#ifdef HAVE_PCAP_SETSAMPLING
+    if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
+    {
+        argv = sync_pipe_add_arg(argv, &argc, "-m");
+        g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
+             capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
+             capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
+             "undef",
+             capture_opts->sampling_param);
+        argv = sync_pipe_add_arg(argv, &argc, ssampling);
+    }
+#endif
 
     /* dumpcap should be running in capture child mode (hidden feature) */
 #ifndef DEBUG_CHILD
index 1d4b523dc683114dab2484344848cfa897aa5dc6..aaa20eeb79b86acd6756deaa9ea821b35221307a 100644 (file)
@@ -319,11 +319,13 @@ get_if_name(const char *if_text)
         * it'll be followed by a blank if it separates the description
         * and the interface name.  (We don't wire in "rpcap", in case we
         * support other protocols in the same syntax.)
+        * Unfortunately, another colon can be used in "rpcap://host:port/"
+        * before port. Check if colon is followed by digit.
         */
-       if (strncmp(if_name, "://", 3) != 0) {
+       if ((strncmp(if_name, "://", 3) != 0) && !isdigit(if_name[1])) {
          /*
-          * OK, we've found a colon not followed by "//".  Skip blanks
-          * following it.
+          * OK, we've found a colon followed neither by "//" nor by digit.  
+          * Skip blanks following it.
           */
          if_name++;
          while (*if_name == ' ')
index 617ada715e5dcb3cadc84fe305250de038259c4e..1e4e1e583f4ab9e2593949bf5c78ef9ccba473ee 100644 (file)
 @WPCAP_CONSTIFIED@
 @HAVE_LIBWIRESHARKDLL@
 
+@HAVE_REMOTE@
+@HAVE_PCAP_REMOTE@
+@HAVE_PCAP_OPEN@
+@HAVE_PCAP_FINDALLDEVS_EX@
+@HAVE_PCAP_CREATESRCSTR@
+@HAVE_PCAP_SETSAMPLING@
+
 @HAVE_AIRPCAP@
 @HAVE_AIRPDCAP@
 
index 9dae3f36d8f06b809cb999d05f853f0d2a45faf3..af4abd9958149a5bd1d3e83b36faec1c77c2507d 100644 (file)
@@ -166,6 +166,12 @@ GTK_WIMP_DIR=$(WIRESHARK_LIBS)\gtk-wimp\gtk-wimp-0.7.0-bin
 #
 PCAP_DIR=$(WIRESHARK_LIBS)\WPdpack
 
+#
+# Optional: WinPcap remote capture support and new API
+# (pcap_open(), pcap_findalldevs_ex(), etc.)
+#
+#PCAP_REMOTE=1
+
 #
 # Optional: The ZLib enables unzipping of gzip compressed capture files 
 # "on the fly".
@@ -690,6 +696,22 @@ PCAP_BREAKLOOP_CONFIG=
 WPCAP_CONSTIFIED=
 !ENDIF
 
+!IF DEFINED(PCAP_DIR) && DEFINED(PCAP_REMOTE)
+PCAP_HAVE_REMOTE_CONFIG=^#define HAVE_REMOTE 1
+PCAP_REMOTE_CONFIG=^#define HAVE_PCAP_REMOTE 1
+PCAP_OPEN_CONFIG=^#define HAVE_PCAP_OPEN 1
+PCAP_FINDALLDEVS_EX_CONFIG=^#define HAVE_PCAP_FINDALLDEVS_EX 1
+PCAP_CREATESRCSTR_CONFIG=^#define HAVE_PCAP_CREATESRCSTR 1
+PCAP_SETSAMPLING_CONFIG=^#define HAVE_PCAP_SETSAMPLING 1
+!ELSE
+PCAP_HAVE_REMOTE_CONFIG=
+PCAP_REMOTE_CONFIG=
+PCAP_OPEN_CONFIG=
+PCAP_FINDALLDEVS_EX_CONFIG=
+PCAP_CREATESRCSTR_CONFIG=
+PCAP_SETSAMPLING_CONFIG=
+!ENDIF
+
 !IFDEF ZLIB_DIR
 ZLIB_PATH=$(ZLIB_DIR)
 ZLIB_CFLAGS=/I$(ZLIB_DIR)\include
index b4d50f1594e32b9635e73053e645c594137d950f..72c67e6cdac576009e1d613886786fb79372ae34 100644 (file)
@@ -884,6 +884,28 @@ fi
 AC_SUBST(dumpcap_bin)
 AC_SUBST(dumpcap_man)
 
+dnl pcap remote check
+AC_MSG_CHECKING(whether to use libpcap remote capturing feature)
+
+AC_ARG_WITH(pcap-remote,
+[  --with-pcap-remote        use libpcap remote capturing (requires libpcap)],
+[
+    if test $withval = no
+    then
+        want_pcap_remote=no
+    else
+        want_pcap_remote=yes
+    fi
+],[
+    want_pcap_remote=no
+])
+if test "x$want_pcap_remote" = "xno" -o "x$want_pcap" = "xno" ; then
+    AC_MSG_RESULT(no)
+else
+    AC_MSG_RESULT(yes)
+    AC_WIRESHARK_PCAP_REMOTE_CHECK
+fi
+
 dnl zlib check
 AC_MSG_CHECKING(whether to use zlib for reading compressed capture files)
 
index ed4f5fa81eb3dcff8b763eee1cf5a4c578c26af0..97a5dfbc307d2503c94e14c76bfb91baa6544b36 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -138,6 +138,17 @@ print_usage(gboolean print_ver) {
   fprintf(output, "  -S                       print statistics for each interface once every second\n");
   fprintf(output, "  -M                       for -D, -L, and -S produce machine-readable output\n");
   fprintf(output, "\n");
+#ifdef HAVE_PCAP_REMOTE
+  fprintf(output, "\nRPCAP options:\n");
+  fprintf(output, "  -r                       don't ignore own RPCAP traffic in capture\n");
+  fprintf(output, "  -u                       use UDP for RPCAP data transfer\n");
+  fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
+#ifdef HAVE_PCAP_SETSAMPLING
+  fprintf(output, "  -m <sampling type>       use packet sampling\n");
+  fprintf(output, "                           count:NUM - capture one packet of every NUM\n");
+  fprintf(output, "                           timer:NUM - capture no more than 1 packet in NUM ms\n");
+#endif
+#endif
   fprintf(output, "Stop conditions:\n");
   fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
   fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
@@ -363,7 +374,11 @@ main(int argc, char *argv[])
   gboolean             print_statistics = FALSE;
   int                  status, run_once_args = 0;
 
+#ifdef HAVE_PCAP_REMOTE
+#define OPTSTRING_INIT "a:A:b:c:Df:hi:Lm:MprSs:uvw:y:Z:"
+#else
 #define OPTSTRING_INIT "a:b:c:Df:hi:LMpSs:vw:y:Z:"
+#endif
 
 #ifdef _WIN32
 #define OPTSTRING_WIN32 "B:"
@@ -476,6 +491,14 @@ main(int argc, char *argv[])
       case 's':        /* Set the snapshot (capture) length */
       case 'w':        /* Write to capture file x */
       case 'y':        /* Set the pcap data link type */
+#ifdef HAVE_PCAP_REMOTE
+      case 'u':        /* Use UDP for data transfer */
+      case 'r':        /* Capture own RPCAP traffic too */
+      case 'A':        /* Authentication */
+#endif
+#ifdef HAVE_PCAP_SETSAMPLING
+      case 'm':        /* Sampling */
+#endif
 #ifdef _WIN32
       case 'B':        /* Buffer size */
 #endif /* _WIN32 */
index 96c8c84821b12af0c8eeeec9308e19b24f6f9470..01204f4708505e3d706dc338d3e047db90f36aac 100644 (file)
@@ -1,7 +1,7 @@
 /* Do not modify this file.                                                   */
 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
 /* packet-ldap.c                                                              */
-/* ../../tools/asn2wrs.py -b -X -T -p ldap -c ./ldap.cnf -s ./packet-ldap-template -D . Lightweight-Directory-Access-Protocol-V3.asn */
+/* ../../tools/asn2wrs.py -b -X -T -p ldap -c ldap.cnf -s packet-ldap-template Lightweight-Directory-Access-Protocol-V3.asn */
 
 /* Input file: packet-ldap-template.c */
 
index e1004958698c81c826de5af028dc694677248445..60a3664a4d5a7c58ec438f830b9fa79a37bfc3c2 100644 (file)
@@ -1,7 +1,7 @@
 /* Do not modify this file.                                                   */
 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
 /* packet-ldap.h                                                              */
-/* ../../tools/asn2wrs.py -b -X -T -p ldap -c ./ldap.cnf -s ./packet-ldap-template -D . Lightweight-Directory-Access-Protocol-V3.asn */
+/* ../../tools/asn2wrs.py -b -X -T -p ldap -c ldap.cnf -s packet-ldap-template Lightweight-Directory-Access-Protocol-V3.asn */
 
 /* Input file: packet-ldap-template.h */
 
index 42e1ebd6620e96f258467c5c26fc3f387856abff..ebe1f9c010f88314224501497c979bb8e14800a8 100644 (file)
 #define E_CAP_N_RESOLVE_KEY         "cap_n_resolve"
 #define E_CAP_T_RESOLVE_KEY         "cap_t_resolve"
 
+#ifdef HAVE_PCAP_REMOTE
+#define E_CAP_IFTYPE_OM_KEY         "cap_iftype_om"
+#define E_CAP_DATATX_UDP_CB_KEY     "cap_datatx_udp_cb"
+#define E_CAP_NOCAP_RPCAP_CB_KEY    "cap_nocap_rpcap_cb"
+#define E_CAP_REMOTE_DIALOG_PTR_KEY "cap_remote_dialog"
+#define E_CAP_REMOTE_CALLER_PTR_KEY "cap_remote_caller"
+#define E_REMOTE_HOST_TE_KEY        "cap_remote_host"
+#define E_REMOTE_PORT_TE_KEY        "cap_remote_port"
+#define E_REMOTE_AUTH_NULL_KEY      "cap_remote_auth_null"
+#define E_REMOTE_AUTH_PASSWD_KEY    "cap_remote_auth_passwd"
+#define E_REMOTE_USERNAME_LB_KEY    "cap_remote_username_lb"
+#define E_REMOTE_USERNAME_TE_KEY    "cap_remote_username_te"
+#define E_REMOTE_PASSWD_LB_KEY      "cap_remote_passwd_lb"
+#define E_REMOTE_PASSWD_TE_KEY      "cap_remote_passwd_te"
+#define E_CAP_OM_IFTYPE_VALUE_KEY   "cap_om_iftype_value"
+#endif
+#ifdef HAVE_PCAP_SETSAMPLING
+#define E_CAP_SAMP_NONE_RB_KEY      "cap_samp_none_rb"
+#define E_CAP_SAMP_COUNT_RB_KEY     "cap_samp_count_rb"
+#define E_CAP_SAMP_COUNT_SB_KEY     "cap_samp_count_sb"
+#define E_CAP_SAMP_TIMER_RB_KEY     "cap_samp_timer_rb"
+#define E_CAP_SAMP_TIMER_SB_KEY     "cap_samp_timer_sb"
+#endif
+
 #define E_CAP_OM_LT_VALUE_KEY       "cap_om_lt_value"
 
 
@@ -134,6 +158,14 @@ capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te);
 static void
 select_link_type_cb(GtkWidget *w, gpointer data);
 
+#ifdef HAVE_PCAP_REMOTE
+static void
+select_if_type_cb(GtkWidget *w, gpointer data);
+
+static void
+capture_remote_cb(GtkWidget *w, gpointer data);
+#endif
+
 static void
 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
 
@@ -551,6 +583,314 @@ display_airpcap_advanced_cb(w,d);
 }
 #endif
 
+#ifdef HAVE_PCAP_REMOTE
+/* PCAP interface type menu item */
+struct iftype_info {
+    capture_source  id;
+    const char     *name;
+};
+
+/* List of available types of PCAP interface */
+static struct iftype_info iftype[] = {
+    { CAPTURE_IFLOCAL, "Local" },
+    { CAPTURE_IFREMOTE, "Remote" }
+};
+
+/* Fill the menu of available types of interfaces */
+static GtkWidget *
+iftype_option_menu_new(capture_source value)
+{
+    GtkWidget *iftype_om, *menu, *menu_item;
+    unsigned int i, active = 0;
+
+    iftype_om = gtk_option_menu_new();
+    menu = gtk_menu_new();
+
+    for (i = 0; i < sizeof(iftype) / sizeof(iftype[0]); i++)
+    {
+        menu_item = gtk_menu_item_new_with_label(iftype[i].name);
+        OBJECT_SET_DATA(menu_item, E_CAP_IFTYPE_OM_KEY, iftype_om);
+        SIGNAL_CONNECT(menu_item, "activate", select_if_type_cb,
+                       GINT_TO_POINTER((int)iftype[i].id));
+        gtk_menu_append(GTK_MENU(menu), menu_item);
+        if (value == iftype[i].id)
+            active = i;
+    }
+
+    gtk_menu_set_active(GTK_MENU(menu), active);
+    gtk_option_menu_set_menu(GTK_OPTION_MENU(iftype_om), menu);
+
+    return iftype_om;
+}
+
+/* Retrieve the list of local or remote interfaces according to selected
+ * options and re-fill inteface name combobox */
+static void
+update_interface_list()
+{
+    GtkWidget *if_cb;
+    GList     *if_list, *combo_list;
+    int        err;
+    gchar     *err_str;
+
+    if (cap_open_w == NULL)
+        return;
+
+    if_cb = (GtkWidget *)OBJECT_GET_DATA(cap_open_w, E_CAP_IFACE_KEY);
+
+    if (capture_opts->src_type == CAPTURE_IFREMOTE)
+        if_list = get_remote_interface_list(capture_opts->remote_host,
+                        capture_opts->remote_port,
+                        capture_opts->auth_type,
+                        capture_opts->auth_username,
+                        capture_opts->auth_password,
+                        &err, &err_str);
+    else
+        if_list = get_interface_list(&err, &err_str);
+
+    if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
+        g_free(err_str);
+
+        gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), NULL);
+        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), "");
+    }
+    combo_list = build_capture_combo_list(if_list, TRUE);
+    if (combo_list != NULL)
+        gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
+
+    free_capture_combo_list(combo_list);
+    free_interface_list(if_list);
+}
+
+/* User changed an interface entry of "Remote interface" dialog */
+static void
+capture_remote_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
+{
+    GtkWidget *auth_passwd_rb,
+              *username_lb, *username_te,
+              *passwd_lb, *passwd_te;
+    gboolean  state;
+
+    auth_passwd_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w,
+                                                  E_REMOTE_AUTH_PASSWD_KEY);
+    username_lb = (GtkWidget *)OBJECT_GET_DATA(parent_w,
+                                                E_REMOTE_USERNAME_LB_KEY);
+    username_te = (GtkWidget *)OBJECT_GET_DATA(parent_w,
+                                                E_REMOTE_USERNAME_TE_KEY);
+    passwd_lb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_REMOTE_PASSWD_LB_KEY);
+    passwd_te = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_REMOTE_PASSWD_TE_KEY);
+
+    state =  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auth_passwd_rb));
+    gtk_widget_set_sensitive(GTK_WIDGET(username_lb), state);
+    gtk_widget_set_sensitive(GTK_WIDGET(username_te), state);
+    gtk_widget_set_sensitive(GTK_WIDGET(passwd_lb), state);
+    gtk_widget_set_sensitive(GTK_WIDGET(passwd_te), state);
+}
+
+/* user requested to destroy the dialog */
+static void
+capture_remote_destroy_cb(GtkWidget *win, gpointer user_data _U_)
+{
+    GtkWidget *caller;
+
+    caller = OBJECT_GET_DATA(win, E_CAP_REMOTE_CALLER_PTR_KEY);
+    OBJECT_SET_DATA(caller, E_CAP_REMOTE_DIALOG_PTR_KEY, NULL);
+}
+
+/* user requested to accept remote interface options */
+static void
+capture_remote_ok_cb(GtkWidget *win _U_, GtkWidget *remote_w)
+{
+    GtkWidget *host_te, *port_te, *auth_pwd_rb, *username_te, *passwd_te,
+              *auth_null_rb, *auth_passwd_rb;
+
+    if (remote_w == NULL)
+        return;
+
+    host_te = (GtkWidget *)OBJECT_GET_DATA(remote_w, E_REMOTE_HOST_TE_KEY);
+    port_te = (GtkWidget *)OBJECT_GET_DATA(remote_w, E_REMOTE_PORT_TE_KEY);
+    auth_pwd_rb = (GtkWidget *)OBJECT_GET_DATA(remote_w,
+                                                  E_REMOTE_AUTH_PASSWD_KEY);
+    username_te = (GtkWidget *)OBJECT_GET_DATA(remote_w,
+                                                E_REMOTE_USERNAME_TE_KEY);
+    passwd_te = (GtkWidget *)OBJECT_GET_DATA(remote_w, E_REMOTE_PASSWD_TE_KEY);
+    auth_null_rb = (GtkWidget *) OBJECT_GET_DATA(remote_w, E_REMOTE_AUTH_NULL_KEY);
+    auth_passwd_rb = (GtkWidget *) OBJECT_GET_DATA(remote_w, E_REMOTE_AUTH_PASSWD_KEY);
+
+    g_free(capture_opts->remote_host);
+    capture_opts->remote_host = g_strdup(gtk_entry_get_text(GTK_ENTRY(host_te)));
+    g_free(capture_opts->remote_port);
+    capture_opts->remote_port = g_strdup(gtk_entry_get_text(GTK_ENTRY(port_te)));
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auth_passwd_rb)))
+        capture_opts->auth_type = CAPTURE_AUTH_PWD;
+    else
+        capture_opts->auth_type = CAPTURE_AUTH_NULL;
+
+    g_free(capture_opts->auth_username);
+    capture_opts->auth_username =
+        g_strdup(gtk_entry_get_text(GTK_ENTRY(username_te)));
+
+    g_free(capture_opts->auth_password);
+    capture_opts->auth_password =
+        g_strdup(gtk_entry_get_text(GTK_ENTRY(passwd_te)));
+
+    capture_opts->src_type = CAPTURE_IFREMOTE;
+
+    window_destroy(GTK_WIDGET(remote_w));
+    update_interface_list();
+}
+
+/* Show remote capture interface parameters dialog */
+static void
+capture_remote_cb(GtkWidget *w _U_, gpointer d _U_)
+{
+    GtkWidget   *caller, *remote_w,
+                *main_vb, *host_tb,
+                *host_lb, *host_te, *port_lb, *port_te,
+                *auth_fr, *auth_vb,
+                *auth_null_rb, *auth_passwd_rb, *auth_passwd_tb,
+                *user_lb, *user_te, *passwd_lb, *passwd_te,
+                *bbox, *ok_bt, *cancel_bt;
+    gchar       *title;
+    GtkTooltips *tooltips;
+    GSList      *auth_group;
+
+    caller = gtk_widget_get_toplevel(w);
+    remote_w = OBJECT_GET_DATA(caller, E_CAP_REMOTE_DIALOG_PTR_KEY);
+    if (remote_w != NULL)
+    {
+        reactivate_window(remote_w);
+        return;
+    }
+
+    title = create_user_window_title("Wireshark: Remote Interface");
+    remote_w = dlg_window_new(title);
+    OBJECT_SET_DATA(remote_w, E_CAP_REMOTE_CALLER_PTR_KEY, caller);
+    OBJECT_SET_DATA(caller, E_CAP_REMOTE_DIALOG_PTR_KEY, remote_w);
+    g_free(title);
+
+    tooltips = gtk_tooltips_new();
+
+    main_vb = gtk_vbox_new(FALSE, 0);
+    gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+    gtk_container_add(GTK_CONTAINER(remote_w), main_vb);
+
+    /* Host/port table */
+    host_tb = gtk_table_new(2, 2, FALSE);
+    gtk_table_set_row_spacings(GTK_TABLE(host_tb), 3);
+    gtk_table_set_col_spacings(GTK_TABLE(host_tb), 3);
+    gtk_box_pack_start(GTK_BOX(main_vb), host_tb, FALSE, FALSE, 0);
+
+    /* Host row */
+    host_lb = gtk_label_new("Host:");
+    gtk_table_attach_defaults(GTK_TABLE(host_tb), host_lb, 0, 1, 0, 1);
+
+    host_te = gtk_entry_new();
+    gtk_tooltips_set_tip(tooltips, host_te,
+        "Enter the hostname or host IP address to be used as a source "
+        "for remote capture.", NULL);
+    gtk_table_attach_defaults(GTK_TABLE(host_tb), host_te, 1, 2, 0, 1);
+    if (capture_opts->remote_host != NULL)
+        gtk_entry_set_text(GTK_ENTRY(host_te), capture_opts->remote_host);
+
+    /* Port row */
+    port_lb = gtk_label_new("Port:");
+    gtk_table_attach_defaults(GTK_TABLE(host_tb), port_lb, 0, 1, 1, 2);
+
+    port_te = gtk_entry_new();
+    gtk_tooltips_set_tip(tooltips, port_te,
+        "Enter the TCP port number used by RPCAP server at remote host "
+        "(leave it empty for default port number).", NULL);
+    gtk_table_attach_defaults(GTK_TABLE(host_tb), port_te, 1, 2, 1, 2);
+    if (capture_opts->remote_port != NULL)
+        gtk_entry_set_text(GTK_ENTRY(port_te), capture_opts->remote_port);
+
+    /* Authentication options frame */
+    auth_fr = gtk_frame_new("Authentication");
+    gtk_container_add(GTK_CONTAINER(main_vb), auth_fr);
+
+    auth_vb = gtk_vbox_new(FALSE, 3);
+    gtk_container_border_width(GTK_CONTAINER(auth_vb), 5);
+    gtk_container_add(GTK_CONTAINER(auth_fr), auth_vb);
+
+    auth_null_rb = gtk_radio_button_new_with_label(NULL,
+                                                   "Null authentication");
+    gtk_box_pack_start(GTK_BOX(auth_vb), auth_null_rb, TRUE, TRUE, 0);
+
+#if GTK_MAJOR_VERSION >= 2
+    auth_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(auth_null_rb));
+#else
+    auth_group = gtk_radio_button_group(GTK_RADIO_BUTTON(auth_null_rb));
+#endif
+    auth_passwd_rb = gtk_radio_button_new_with_label(auth_group,
+                                            "Password authentication");
+    gtk_box_pack_start(GTK_BOX(auth_vb), auth_passwd_rb, TRUE, TRUE, 0);
+    SIGNAL_CONNECT(auth_passwd_rb, "toggled", capture_remote_adjust_sensitivity,
+                   remote_w);
+
+    auth_passwd_tb = gtk_table_new(2, 2, FALSE);
+    gtk_table_set_row_spacings(GTK_TABLE(auth_passwd_tb), 3);
+    gtk_table_set_col_spacings(GTK_TABLE(auth_passwd_tb), 3);
+    gtk_box_pack_start(GTK_BOX(auth_vb), auth_passwd_tb, FALSE, FALSE, 0);
+
+    user_lb = gtk_label_new("Username:");
+    gtk_table_attach_defaults(GTK_TABLE(auth_passwd_tb), user_lb, 0, 1, 0, 1);
+
+    user_te = gtk_entry_new();
+    gtk_table_attach_defaults(GTK_TABLE(auth_passwd_tb), user_te, 1, 2, 0, 1);
+    if (capture_opts->auth_username != NULL)
+        gtk_entry_set_text(GTK_ENTRY(user_te), capture_opts->auth_username);
+
+    passwd_lb = gtk_label_new("Password:");
+    gtk_table_attach_defaults(GTK_TABLE(auth_passwd_tb), passwd_lb, 0, 1, 1, 2);
+
+    passwd_te = gtk_entry_new();
+    gtk_entry_set_visibility(GTK_ENTRY(passwd_te), FALSE);
+    gtk_table_attach_defaults(GTK_TABLE(auth_passwd_tb), passwd_te, 1, 2, 1, 2);
+    if (capture_opts->auth_password != NULL)
+        gtk_entry_set_text(GTK_ENTRY(passwd_te), capture_opts->auth_password);
+
+    /* Button row: "Start" and "Cancel" buttons */
+    bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL);
+    gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
+
+    ok_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
+    SIGNAL_CONNECT(ok_bt, "clicked", capture_remote_ok_cb, remote_w);
+    gtk_tooltips_set_tip(tooltips, ok_bt,
+                         "Accept remote host parameters and lookup "
+                         "remote interfaces.", NULL);
+
+    cancel_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
+    gtk_tooltips_set_tip(tooltips, cancel_bt,
+                         "Cancel and exit dialog.", NULL);
+    window_set_cancel_button(remote_w, cancel_bt, window_cancel_button_cb);
+
+    gtk_widget_grab_default(ok_bt);
+
+    SIGNAL_CONNECT(remote_w, "delete_event", window_delete_event_cb, NULL);
+    SIGNAL_CONNECT(remote_w, "destroy", capture_remote_destroy_cb, NULL);
+
+    OBJECT_SET_DATA(remote_w, E_REMOTE_HOST_TE_KEY, host_te);
+    OBJECT_SET_DATA(remote_w, E_REMOTE_PORT_TE_KEY, port_te);
+    OBJECT_SET_DATA(remote_w, E_REMOTE_AUTH_NULL_KEY, auth_null_rb);
+    OBJECT_SET_DATA(remote_w, E_REMOTE_AUTH_PASSWD_KEY, auth_passwd_rb);
+    OBJECT_SET_DATA(remote_w, E_REMOTE_USERNAME_LB_KEY, user_lb);
+    OBJECT_SET_DATA(remote_w, E_REMOTE_USERNAME_TE_KEY, user_te);
+    OBJECT_SET_DATA(remote_w, E_REMOTE_PASSWD_LB_KEY, passwd_lb);
+    OBJECT_SET_DATA(remote_w, E_REMOTE_PASSWD_TE_KEY, passwd_te);
+
+    if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auth_passwd_rb), TRUE);
+    else
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auth_null_rb), TRUE);
+    capture_remote_adjust_sensitivity(NULL, remote_w);
+
+    gtk_widget_show_all(remote_w);
+    window_present(remote_w);
+}
+#endif
+
 /* show capture prepare (options) dialog */
 void
 capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
@@ -591,6 +931,16 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   GtkWidget     *advanced_hb, *advanced_bt;
 #endif
 #endif
+#ifdef HAVE_PCAP_REMOTE
+  GtkWidget     *iftype_om, *nocap_rpcap_cb, *datatx_udp_cb;
+#ifdef HAVE_PCAP_SETSAMPLING
+  GtkWidget     *sampling_fr, *sampling_vb, *sampling_tb, *sampling_lb,
+                *samp_none_rb, *samp_count_rb, *samp_timer_rb,
+                *samp_count_sb, *samp_timer_sb;
+  GtkAdjustment *samp_count_adj, *samp_timer_adj;
+  GSList        *samp_group;
+#endif
+#endif
 #if GTK_MAJOR_VERSION < 2
   GtkAccelGroup *accel_group;
 #endif
@@ -631,7 +981,19 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   }
 #endif
 
+#ifdef HAVE_PCAP_REMOTE
+  if (capture_opts->src_type == CAPTURE_IFREMOTE)
+      if_list = get_remote_interface_list(capture_opts->remote_host,
+                    capture_opts->remote_port,
+                    capture_opts->auth_type,
+                    capture_opts->auth_username,
+                    capture_opts->auth_password,
+                    &err, &err_str);
+  else
+      if_list = get_interface_list(&err, &err_str);
+#else
   if_list = capture_interface_list(&err, &err_str);
+#endif
   if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
     g_free(err_str);
@@ -690,6 +1052,11 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   if_lb = gtk_label_new("Interface:");
   gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6);
 
+#ifdef HAVE_PCAP_REMOTE
+  iftype_om = iftype_option_menu_new(capture_opts->src_type);
+  gtk_box_pack_start(GTK_BOX(if_hb), iftype_om, FALSE, FALSE, 0);
+#endif
+
   if_cb = gtk_combo_new();
   combo_list = build_capture_combo_list(if_list, TRUE);
   if (combo_list != NULL)
@@ -806,6 +1173,21 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
     "See the FAQ for some more details of capturing packets from a switched network.", NULL);
   gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb);
 
+#ifdef HAVE_PCAP_REMOTE
+  /* RPCAP-related flags */
+  nocap_rpcap_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
+      "Do not capture RPCAP own traffic", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(nocap_rpcap_cb),
+          capture_opts->nocap_rpcap);
+  gtk_container_add(GTK_CONTAINER(capture_vb), nocap_rpcap_cb);
+
+  datatx_udp_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
+      "Use UDP for RPCAP data transfer", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(datatx_udp_cb),
+          capture_opts->datatx_udp);
+  gtk_container_add(GTK_CONTAINER(capture_vb), datatx_udp_cb);
+#endif
+
   /* Capture length row */
   snap_hb = gtk_hbox_new(FALSE, 3);
   gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
@@ -1145,6 +1527,77 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   gtk_adjustment_set_value(stop_duration_adj, (gfloat) value);
   row++;
 
+#ifdef HAVE_PCAP_SETSAMPLING
+  /* Sampling options */
+  sampling_fr = gtk_frame_new("Sampling Options");
+  gtk_container_add(GTK_CONTAINER(right_vb), sampling_fr);
+
+  sampling_vb = gtk_vbox_new(FALSE, 0);
+  gtk_container_border_width(GTK_CONTAINER(sampling_vb), 5);
+  gtk_container_add(GTK_CONTAINER(sampling_fr), sampling_vb);
+
+  sampling_tb = gtk_table_new(3, 3, FALSE);
+  gtk_table_set_row_spacings(GTK_TABLE(sampling_tb), 1);
+  gtk_table_set_col_spacings(GTK_TABLE(sampling_tb), 3);
+  gtk_box_pack_start(GTK_BOX(sampling_vb), sampling_tb, FALSE, FALSE, 0);
+
+  /* "No sampling" row */
+  samp_none_rb = gtk_radio_button_new_with_label(NULL, "None");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_none_rb),
+                     (capture_opts->sampling_method == CAPTURE_SAMP_NONE));
+  SIGNAL_CONNECT(samp_none_rb, "toggled",
+                 capture_prep_adjust_sensitivity, cap_open_w);
+  gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_none_rb, 0, 1, 0, 1);
+
+  /* "Sampling by counter" row */
+#if GTK_MAJOR_VERSION >= 2
+  samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_none_rb));
+#else
+  samp_group = gtk_radio_button_group(GTK_RADIO_BUTTON(samp_none_rb));
+#endif
+  samp_count_rb = gtk_radio_button_new_with_label(samp_group, "1 of");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_none_rb),
+                     (capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT));
+  SIGNAL_CONNECT(samp_count_rb, "toggled",
+                 capture_prep_adjust_sensitivity, cap_open_w);
+  gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_count_rb, 0, 1, 1, 2);
+
+  samp_count_adj = (GtkAdjustment *) gtk_adjustment_new(
+                        (gfloat)capture_opts->sampling_param,
+                        1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
+  samp_count_sb = gtk_spin_button_new(samp_count_adj, 0, 0);
+  gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_count_sb), TRUE);
+  gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_count_sb, 1, 2, 1, 2);
+
+  sampling_lb = gtk_label_new("packets");
+  gtk_misc_set_alignment(GTK_MISC(sampling_lb), 0, 0.5);
+  gtk_table_attach_defaults(GTK_TABLE(sampling_tb), sampling_lb, 2, 3, 1, 2);
+
+  /* "Sampling by timer" row */
+#if GTK_MAJOR_VERSION >= 2
+  samp_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(samp_count_rb));
+#else
+  samp_group = gtk_radio_button_group(GTK_RADIO_BUTTON(samp_count_rb));
+#endif
+  samp_timer_rb = gtk_radio_button_new_with_label(samp_group, "1 every");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(samp_none_rb),
+                     (capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER));
+  SIGNAL_CONNECT(samp_timer_rb, "toggled",
+                 capture_prep_adjust_sensitivity, cap_open_w);
+  gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_timer_rb, 0, 1, 2, 3);
+
+  samp_timer_adj = (GtkAdjustment *) gtk_adjustment_new(
+                        (gfloat)capture_opts->sampling_param,
+                        1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
+  samp_timer_sb = gtk_spin_button_new(samp_timer_adj, 0, 0);
+  gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(samp_timer_sb), TRUE);
+  gtk_table_attach_defaults(GTK_TABLE(sampling_tb), samp_timer_sb, 1, 2, 2, 3);
+
+  sampling_lb = gtk_label_new("milliseconds");
+  gtk_misc_set_alignment(GTK_MISC(sampling_lb), 0, 0.5);
+  gtk_table_attach_defaults(GTK_TABLE(sampling_tb), sampling_lb, 2, 3, 2, 3);
+#endif
+
   /* Display-related options frame */
   display_fr = gtk_frame_new("Display Options");
   gtk_container_add(GTK_CONTAINER(right_vb), display_fr);
@@ -1236,6 +1689,12 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
 
   /* Attach pointers to needed widgets to the capture prefs window/object */
   OBJECT_SET_DATA(cap_open_w, E_CAP_IFACE_KEY, if_cb);
+#ifdef HAVE_PCAP_REMOTE
+  OBJECT_SET_DATA(cap_open_w, E_CAP_IFTYPE_OM_KEY, iftype_om);
+  OBJECT_SET_DATA(cap_open_w, E_CAP_REMOTE_DIALOG_PTR_KEY, NULL);
+  OBJECT_SET_DATA(cap_open_w, E_CAP_NOCAP_RPCAP_CB_KEY, nocap_rpcap_cb);
+  OBJECT_SET_DATA(cap_open_w, E_CAP_DATATX_UDP_CB_KEY, datatx_udp_cb);
+#endif
   OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_CB_KEY, snap_cb);
   OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_SB_KEY, snap_sb);
   OBJECT_SET_DATA(cap_open_w, E_CAP_LT_OM_KEY, linktype_om);
@@ -1273,6 +1732,13 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
   OBJECT_SET_DATA(cap_open_w, E_CAP_M_RESOLVE_KEY,  m_resolv_cb);
   OBJECT_SET_DATA(cap_open_w, E_CAP_N_RESOLVE_KEY,  n_resolv_cb);
   OBJECT_SET_DATA(cap_open_w, E_CAP_T_RESOLVE_KEY,  t_resolv_cb);
+#ifdef HAVE_PCAP_SETSAMPLING
+  OBJECT_SET_DATA(cap_open_w, E_CAP_SAMP_NONE_RB_KEY, samp_none_rb);
+  OBJECT_SET_DATA(cap_open_w, E_CAP_SAMP_COUNT_RB_KEY, samp_count_rb);
+  OBJECT_SET_DATA(cap_open_w, E_CAP_SAMP_COUNT_SB_KEY, samp_count_sb);
+  OBJECT_SET_DATA(cap_open_w, E_CAP_SAMP_TIMER_RB_KEY, samp_timer_rb);
+  OBJECT_SET_DATA(cap_open_w, E_CAP_SAMP_TIMER_SB_KEY, samp_timer_sb);
+#endif
 
   /* Set the sensitivity of various widgets as per the settings of other
      widgets. */
@@ -1441,6 +1907,33 @@ select_link_type_cb(GtkWidget *w, gpointer data)
   }
  }
 
+#ifdef HAVE_PCAP_REMOTE
+/* user selected an interface type (local/remote), convert to internal value) */
+static void
+select_if_type_cb(GtkWidget *w, gpointer data)
+{
+    int new_iftype = GPOINTER_TO_INT(data);
+    GtkWidget *iftype_om = OBJECT_GET_DATA(w, E_CAP_IFTYPE_OM_KEY);
+    int old_iftype = GPOINTER_TO_INT(OBJECT_GET_DATA(iftype_om,
+                                            E_CAP_OM_IFTYPE_VALUE_KEY));
+
+    if (old_iftype != new_iftype)
+    {
+        OBJECT_SET_DATA(iftype_om, E_CAP_OM_IFTYPE_VALUE_KEY,
+                        GINT_TO_POINTER(new_iftype));
+    }
+    if (new_iftype == CAPTURE_IFREMOTE)
+    {
+        capture_remote_cb(iftype_om, NULL);
+    }
+    else if (new_iftype != old_iftype)
+    {
+        capture_opts->src_type = CAPTURE_IFLOCAL;
+        update_interface_list();
+    }
+}
+#endif
+
 /* user pressed "File" button */
 static void
 capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te)
@@ -1462,6 +1955,13 @@ capture_dlg_prep(gpointer parent_w) {
             *file_duration_cb, *file_duration_sb, *file_duration_om,
             *stop_files_cb, *stop_files_sb,
             *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
+#ifdef HAVE_PCAP_REMOTE
+  GtkWidget *iftype_om, *datatx_udp_cb, *nocap_rpcap_cb;
+#endif
+#ifdef HAVE_PCAP_SETSAMPLING
+  GtkWidget *samp_none_rb, *samp_count_rb, *samp_timer_rb,
+            *samp_count_sb, *samp_timer_sb;
+#endif
 #ifdef _WIN32
   GtkWidget *buffer_size_sb;
 #endif
@@ -1475,6 +1975,11 @@ capture_dlg_prep(gpointer parent_w) {
   gint32 tmp;
 
   if_cb     = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
+#ifdef HAVE_PCAP_REMOTE
+  iftype_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFTYPE_OM_KEY);
+  datatx_udp_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DATATX_UDP_CB_KEY);
+  nocap_rpcap_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_NOCAP_RPCAP_CB_KEY);
+#endif
   snap_cb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
   snap_sb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
   linktype_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_LT_OM_KEY);
@@ -1510,6 +2015,13 @@ capture_dlg_prep(gpointer parent_w) {
   m_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_M_RESOLVE_KEY);
   n_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_N_RESOLVE_KEY);
   t_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_T_RESOLVE_KEY);
+#ifdef HAVE_PCAP_SETSAMPLING
+  samp_none_rb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_NONE_RB_KEY);
+  samp_count_rb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_COUNT_RB_KEY);
+  samp_timer_rb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_TIMER_RB_KEY);
+  samp_count_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_COUNT_SB_KEY);
+  samp_timer_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_TIMER_SB_KEY);
+#endif
 
   entry_text =
     g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
@@ -1533,6 +2045,31 @@ capture_dlg_prep(gpointer parent_w) {
   /*  capture_opts->linktype =
       GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY)); */
 
+#ifdef HAVE_PCAP_REMOTE
+  capture_opts->src_type = (capture_source)
+      GPOINTER_TO_INT(OBJECT_GET_DATA(iftype_om, E_CAP_OM_IFTYPE_VALUE_KEY));
+  capture_opts->datatx_udp =
+      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(datatx_udp_cb));
+  capture_opts->nocap_rpcap =
+      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(nocap_rpcap_cb));
+#endif
+#ifdef HAVE_PCAP_SETSAMPLING
+   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_none_rb)))
+       capture_opts->sampling_method = CAPTURE_SAMP_NONE;
+   else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_count_rb)))
+   {
+       capture_opts->sampling_method = CAPTURE_SAMP_BY_COUNT;
+       capture_opts->sampling_param = gtk_spin_button_get_value_as_int(
+                                        GTK_SPIN_BUTTON(samp_count_sb));
+   }
+   else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_timer_rb)))
+   {
+       capture_opts->sampling_method = CAPTURE_SAMP_BY_TIMER;
+       capture_opts->sampling_param = gtk_spin_button_get_value_as_int(
+                                        GTK_SPIN_BUTTON(samp_timer_sb));
+   }
+#endif
+
 #ifdef _WIN32
   capture_opts->buffer_size =
     gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_sb));
@@ -1703,6 +2240,9 @@ static void
 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
 {
   GtkWidget *fs;
+#ifdef HAVE_PCAP_REMOTE
+  GtkWidget *remote_w;
+#endif
 
   /* Is there a file selection dialog associated with this
      Capture Options dialog? */
@@ -1720,6 +2260,12 @@ capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
   /* update airpcap toolbar */
   airpcap_set_toolbar_stop_capture(airpcap_if_active);
 #endif
+
+#ifdef HAVE_PCAP_REMOTE
+  remote_w = OBJECT_GET_DATA(win, E_CAP_REMOTE_DIALOG_PTR_KEY);
+  if (remote_w != NULL)
+      window_destroy(remote_w);
+#endif
 }
 
 /* user changed the interface entry */
@@ -1751,6 +2297,10 @@ capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
             *stop_filesize_cb, *stop_filesize_sb, *stop_filesize_om,
             *stop_duration_cb, *stop_duration_sb, *stop_duration_om,
             *stop_files_cb, *stop_files_sb, *stop_files_lb;
+#ifdef HAVE_PCAP_SETSAMPLING
+  GtkWidget *samp_count_rb, *samp_timer_rb,
+            *samp_count_sb, *samp_timer_sb;
+#endif
 
 
   if_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
@@ -1781,6 +2331,12 @@ capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
   stop_files_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_CB_KEY);
   stop_files_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_SB_KEY);
   stop_files_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_STOP_FILES_LB_KEY);
+#ifdef HAVE_PCAP_SETSAMPLING
+  samp_count_rb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_COUNT_RB_KEY);
+  samp_timer_rb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_TIMER_RB_KEY);
+  samp_count_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_COUNT_SB_KEY);
+  samp_timer_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SAMP_TIMER_SB_KEY);
+#endif
 
   /* The snapshot length spinbox is sensitive if the "Limit each packet
      to" checkbox is on. */
@@ -1895,6 +2451,13 @@ capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
   gtk_widget_set_sensitive(GTK_WIDGET(stop_duration_om),
       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stop_duration_cb)));
+
+#ifdef HAVE_PCAP_SETSAMPLING
+   gtk_widget_set_sensitive(GTK_WIDGET(samp_count_sb),
+      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_count_rb)));
+   gtk_widget_set_sensitive(GTK_WIDGET(samp_timer_sb),
+      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(samp_timer_rb)));
+#endif
 }
 
 #endif /* HAVE_LIBPCAP */