Witness: working witness.cnf
[metze/wireshark/wip.git] / capture-pcap-util-unix.c
index ad563995ea08cd057d31b1956dc4ed8b6371cbc5..2e476ab82b67312b4971937dbf74ad0af96c7ffa 100644 (file)
@@ -3,8 +3,8 @@
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include <glib.h>
 
 #ifdef HAVE_LIBPCAP
 
+#ifdef HAVE_PCAP_FINDALLDEVS
+
+#include <pcap.h>
+
+#else /* HAVE_PCAP_FINDALLDEVS */
+
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -47,8 +51,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <pcap.h>
-
 /*
  * Keep Digital UNIX happy when including <net/if.h>.
  */
@@ -60,25 +62,70 @@ struct rtentry;
 # include <sys/sockio.h>
 #endif
 
+#include "capture-pcap-util.h"
+
+#endif  /* HAVE_PCAP_FINDALLDEVS */
+
+#include "capture_ifinfo.h"
 #include "capture-pcap-util.h"
 #include "capture-pcap-util-int.h"
 
-#ifndef HAVE_PCAP_FINDALLDEVS
+#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
+
+#ifdef HAVE_PCAP_FINDALLDEVS
+GList *
+get_interface_list(int *err, char **err_str)
+{
+       return get_interface_list_findalldevs(err, err_str);
+}
+#else /* HAVE_PCAP_FINDALLDEVS */
 struct search_user_data {
        char    *name;
        if_info_t *if_info;
 };
 
 static void
-search_for_if_cb(gpointer data, gpointer user_data);
-#endif
+search_for_if_cb(gpointer data, gpointer user_data)
+{
+       struct search_user_data *search_user_data = user_data;
+       if_info_t *if_info = data;
+
+       if (strcmp(if_info->name, search_user_data->name) == 0)
+               search_user_data->if_info = if_info;
+}
 
 GList *
-get_interface_list(int *err, char *err_str)
+get_interface_list(int *err, char **err_str)
 {
-#ifdef HAVE_PCAP_FINDALLDEVS
-       return get_interface_list_findalldevs(err, err_str);
-#else
        GList  *il = NULL;
        gint    nonloopback_pos = 0;
        struct  ifreq *ifr, *last;
@@ -90,11 +137,16 @@ get_interface_list(int *err, char *err_str)
        int len, lastlen;
        char *buf;
        if_info_t *if_info;
+       char errbuf[PCAP_ERRBUF_SIZE];
+       gboolean loopback;
 
        if (sock < 0) {
                *err = CANT_GET_INTERFACE_LIST;
-               g_snprintf(err_str, PCAP_ERRBUF_SIZE, "Error opening socket: %s",
-                   strerror(errno));
+               if (err_str != NULL) {
+                       *err_str = g_strdup_printf(
+                           "Can't get list of interfaces: error opening socket: %s",
+                           g_strerror(errno));
+               }
                return NULL;
        }
 
@@ -111,15 +163,19 @@ get_interface_list(int *err, char *err_str)
                memset (buf, 0, len);
                if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
                        if (errno != EINVAL || lastlen != 0) {
-                               g_snprintf(err_str, PCAP_ERRBUF_SIZE,
-                                       "SIOCGIFCONF ioctl error getting list of interfaces: %s",
-                                       strerror(errno));
+                               if (err_str != NULL) {
+                                       *err_str = g_strdup_printf(
+                                           "Can't get list of interfaces: SIOCGIFCONF ioctl error: %s",
+                                           g_strerror(errno));
+                               }
                                goto fail;
                        }
                } else {
-                       if ((unsigned) ifc.ifc_len < sizeof(struct ifreq)) {
-                               g_snprintf(err_str, PCAP_ERRBUF_SIZE,
-                                       "SIOCGIFCONF ioctl gave too small return buffer");
+                       if ((unsigned int) ifc.ifc_len < sizeof(struct ifreq)) {
+                               if (err_str != NULL) {
+                                       *err_str = g_strdup(
+                                           "Can't get list of interfaces: SIOCGIFCONF ioctl gave too small return buffer");
+                               }
                                goto fail;
                        }
                        if (ifc.ifc_len == lastlen)
@@ -160,14 +216,16 @@ get_interface_list(int *err, char *err_str)
                 * Get the interface flags.
                 */
                memset(&ifrflags, 0, sizeof ifrflags);
-               strncpy(ifrflags.ifr_name, ifr->ifr_name,
+               g_strlcpy(ifrflags.ifr_name, ifr->ifr_name,
                    sizeof ifrflags.ifr_name);
                if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
                        if (errno == ENXIO)
                                goto next;
-                       g_snprintf(err_str, PCAP_ERRBUF_SIZE,
-                               "SIOCGIFFLAGS error getting flags for interface %s: %s",
-                           ifr->ifr_name, strerror(errno));
+                       if (err_str != NULL) {
+                               *err_str = g_strdup_printf(
+                                   "Can't get list of interfaces: SIOCGIFFLAGS error getting flags for interface %s: %s",
+                                   ifr->ifr_name, g_strerror(errno));
+                       }
                        goto fail;
                }
 
@@ -184,7 +242,7 @@ get_interface_list(int *err, char *err_str)
                 * supplied is too large, rather than just truncating it.
                 */
                pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
-                   err_str);
+                   errbuf);
                if (pch == NULL)
                        goto next;
                pcap_close(pch);
@@ -196,14 +254,13 @@ get_interface_list(int *err, char *err_str)
                 * don't want a loopback interface to be the default capture
                 * device unless there are no non-loopback devices.
                 */
-               if_info = if_info_new(ifr->ifr_name, NULL);
+               loopback = ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
+                   strncmp(ifr->ifr_name, "lo", 2) == 0);
+               if_info = if_info_new(ifr->ifr_name, NULL, loopback);
                if_info_add_address(if_info, &ifr->ifr_addr);
-               if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
-                   strncmp(ifr->ifr_name, "lo", 2) == 0) {
-                       if_info->loopback = TRUE;
+               if (loopback)
                        il = g_list_append(il, if_info);
-               } else {
-                       if_info->loopback = FALSE;
+               else {
                        il = g_list_insert(il, if_info, nonloopback_pos);
                        /*
                         * Insert the next non-loopback interface after this
@@ -230,13 +287,13 @@ get_interface_list(int *err, char *err_str)
         * Try opening it and, if that succeeds, add it to the end of
         * the list of interfaces.
         */
-       pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, err_str);
+       pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, errbuf);
        if (pch != NULL) {
                /*
                 * It worked; we can use the "any" device.
                 */
                if_info = if_info_new("any",
-                   "Pseudo-device that captures on all interfaces");
+                   "Pseudo-device that captures on all interfaces", FALSE);
                il = g_list_insert(il, if_info, -1);
                pcap_close(pch);
        }
@@ -250,6 +307,8 @@ get_interface_list(int *err, char *err_str)
                 * No interfaces found.
                 */
                *err = NO_INTERFACES_FOUND;
+               if (err_str != NULL)
+                       *err_str = NULL;
        }
        return il;
 
@@ -260,18 +319,6 @@ fail:
        close(sock);
        *err = CANT_GET_INTERFACE_LIST;
        return NULL;
-#endif /* HAVE_PCAP_FINDALLDEVS */
-}
-
-#ifndef HAVE_PCAP_FINDALLDEVS
-static void
-search_for_if_cb(gpointer data, gpointer user_data)
-{
-       struct search_user_data *search_user_data = user_data;
-       if_info_t *if_info = data;
-
-       if (strcmp(if_info->name, search_user_data->name) == 0)
-               search_user_data->if_info = if_info;
 }
 #endif /* HAVE_PCAP_FINDALLDEVS */
 
@@ -291,13 +338,27 @@ cant_get_if_list_error_message(const char *err_str)
 void
 get_compiled_pcap_version(GString *str)
 {
-#ifdef HAVE_PCAP_VERSION
-       extern char pcap_version[];
-
-       g_string_sprintfa(str, "with libpcap %s", pcap_version);
-#else
-       g_string_append(str, "with libpcap (version unknown)");
-#endif
+       /*
+        * NOTE: in *some* flavors of UN*X, the data from a shared
+        * library might be linked into executable images that are
+        * linked with that shared library, in which case you could
+        * look at pcap_version[] to get the version with which
+        * the program was compiled.
+        *
+        * In other flavors of UN*X, that doesn't happen, so
+        * pcap_version[] gives you the version the program is
+        * running with, not the version it was built with, and,
+        * in at least some of them, if the length of a data item
+        * referred to by the executable - such as the pcap_version[]
+        * string - isn't the same in the version of the library
+        * with which the program was built and the version with
+        * which it was run, the run-time linker will complain,
+        * which is Not Good.
+        *
+        * So, for now, we just give up on reporting the version
+        * of libpcap with which we were compiled.
+        */
+       g_string_append(str, "with libpcap");
 }
 
 /*
@@ -306,13 +367,12 @@ get_compiled_pcap_version(GString *str)
 void
 get_runtime_pcap_version(GString *str)
 {
-       g_string_sprintfa(str, "with ");
+       g_string_append_printf(str, "with ");
 #ifdef HAVE_PCAP_LIB_VERSION
-       g_string_sprintfa(str, pcap_lib_version());
+       g_string_append(str, pcap_lib_version());
 #else
        g_string_append(str, "libpcap (version unknown)");
 #endif
-       g_string_append(str, " ");
 }
 
 #else /* HAVE_LIBPCAP */