Modification of version resource.
[obnox/wireshark/wip.git] / capture-wpcap.c
index 85dbf849aba7447ee2b748f63999292c9307f95b..7b1ecb3429c1fbfd3ac269d1f8fa1fad7870efb9 100644 (file)
@@ -1,12 +1,12 @@
 /* capture-wpcap.c
  * WinPcap-specific interfaces for capturing.  We load WinPcap at run
- * time, so that we only need one Ethereal binary and one Tethereal binary
+ * time, so that we only need one Wireshark binary and one TShark binary
  * for Windows, regardless of whether WinPcap is installed or not.
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 2001 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
 #include <glib.h>
 #include <gmodule.h>
 
-#include "pcap-util.h"
-#include "pcap-util-int.h"
+#include "capture-pcap-util.h"
+#include "capture-pcap-util-int.h"
 
 /* XXX - yes, I know, I should move cppmagic.h to a generic location. */
 #include "tools/lemon/cppmagic.h"
 
+
+#define MAX_WIN_IF_NAME_LEN 511
+
+
 gboolean has_wpcap = FALSE;
 
 #ifdef HAVE_LIBPCAP
 
+/*
+ * XXX - should we require at least WinPcap 3.1 both for building an
+ * for using Wireshark?
+ */
+
 static char*   (*p_pcap_lookupdev) (char *);
 static void    (*p_pcap_close) (pcap_t *);
 static int     (*p_pcap_stats) (pcap_t *, struct pcap_stat *);
@@ -76,8 +85,12 @@ static int (*p_pcap_datalink_name_to_val) (const char *);
 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
 static const char *(*p_pcap_datalink_val_to_name) (int);
 #endif
+#ifdef HAVE_PCAP_BREAKLOOP
+static void    (*p_pcap_breakloop) (pcap_t *);
+#endif
 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);
 
 typedef struct {
        const char      *name;
@@ -105,7 +118,7 @@ load_wpcap(void)
                SYM(pcap_lookupnet, FALSE),
                SYM(pcap_open_live, FALSE),
                SYM(pcap_loop, FALSE),
-               SYM(pcap_freecode, FALSE),
+               SYM(pcap_freecode, TRUE),
 #ifdef HAVE_PCAP_FINDALLDEVS
                SYM(pcap_findalldevs, TRUE),
                SYM(pcap_freealldevs, TRUE),
@@ -115,9 +128,18 @@ load_wpcap(void)
 #endif
 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
                SYM(pcap_datalink_val_to_name, TRUE),
+#endif
+#ifdef HAVE_PCAP_BREAKLOOP
+               /*
+                * We don't try to work around the lack of this at
+                * run time; it's present in WinPcap 3.1, which is
+                * the version we build with and ship with.
+                */
+               SYM(pcap_breakloop, FALSE),
 #endif
                SYM(pcap_lib_version, TRUE),
                SYM(pcap_setbuff, TRUE),
+               SYM(pcap_next_ex, TRUE),
                { NULL, NULL, FALSE }
        };
 
@@ -250,7 +272,9 @@ void
 pcap_freecode(struct bpf_program *a)
 {
        g_assert(has_wpcap);
-       p_pcap_freecode(a);
+    if(p_pcap_freecode) {
+           p_pcap_freecode(a);
+    }
 }
 
 #ifdef HAVE_PCAP_FINDALLDEVS
@@ -351,6 +375,9 @@ static struct dlt_choice dlt_choices[] = {
 #ifdef DLT_LINUX_IRDA
        DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
 #endif
+#ifdef DLT_LINUX_LAPD
+       DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
+#endif
 #ifdef DLT_LANE8023
        DLT_CHOICE(DLT_LANE8023, "Linux 802.3 LANE"),
 #endif
@@ -411,6 +438,13 @@ pcap_datalink_val_to_name(int dlt)
 }
 #endif
 
+#ifdef HAVE_PCAP_BREAKLOOP
+void pcap_breakloop(pcap_t *a)
+{
+       p_pcap_breakloop(a);
+}
+#endif
+
 /* setbuff is win32 specific! */
 int pcap_setbuff(pcap_t *a, int b)
 {
@@ -418,12 +452,20 @@ int pcap_setbuff(pcap_t *a, int b)
        return p_pcap_setbuff(a, b);
 }
 
+/* pcap_next_ex is available since libpcap 0.8 / WinPcap 3.0! */
+/* (if you get a declaration warning here, try to update to at least WinPcap 3.1b4 develpack) */
+int pcap_next_ex (pcap_t *a, struct pcap_pkthdr **b, const u_char **c)
+{
+       g_assert(has_wpcap);
+       return p_pcap_next_ex(a, b, c);
+}
+
 /*
  * This will use "pcap_findalldevs()" if we have it, otherwise it'll
  * fall back on "pcap_lookupdev()".
  */
 GList *
-get_interface_list(int *err, char *err_str)
+get_interface_list(int *err, char **err_str)
 {
        GList  *il = NULL;
        wchar_t *names;
@@ -431,6 +473,7 @@ get_interface_list(int *err, char *err_str)
        char ascii_name[MAX_WIN_IF_NAME_LEN + 1];
        char ascii_desc[MAX_WIN_IF_NAME_LEN + 1];
        int i, j;
+       char errbuf[PCAP_ERRBUF_SIZE];
 
 #ifdef HAVE_PCAP_FINDALLDEVS
        if (p_pcap_findalldevs != NULL)
@@ -442,7 +485,7 @@ get_interface_list(int *err, char *err_str)
         * PacketGetAdapterNames.  According to the documentation
         * I could find:
         *
-        *      http://winpcap.polito.it/docs/man/html/Packet32_8c.html#a43
+        *      http://www.winpcap.org/docs/man/html/Packet32_8c.html#a43
         *
         * this means that:
         *
@@ -480,7 +523,7 @@ get_interface_list(int *err, char *err_str)
         * description of the Nth adapter.
         */
 
-       names = (wchar_t *)pcap_lookupdev(err_str);
+       names = (wchar_t *)pcap_lookupdev(errbuf);
        i = 0;
 
        if (names) {
@@ -567,6 +610,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;
@@ -588,7 +633,7 @@ cant_get_if_list_error_message(const char *err_str)
            strstr(err_str, "The operation completed successfully") != NULL) {
                return g_strdup_printf("Can't get list of interfaces: %s\n"
 "This might be a problem with WinPcap 3.0; you should try updating to\n"
-"a later version of WinPcap - see the WinPcap site at winpcap.polito.it",
+"a later version of WinPcap - see the WinPcap site at www.winpcap.org",
                    err_str);
        }
        return g_strdup_printf("Can't get list of interfaces: %s", err_str);
@@ -616,27 +661,48 @@ get_runtime_pcap_version(GString *str)
         * what version we have.
         */
        GModule *handle;                /* handle returned by dlopen */
-       gchar *packetVer = NULL;
+       static gchar *packetVer;
+       gchar *blankp;
 
        if (has_wpcap) {
-               /* An alternative method of obtaining the version number */
-               if ((handle = g_module_open("Packet.dll", 0)) != NULL) {
-                       if (g_module_symbol(handle, "PacketLibraryVersion",
-                           (gpointer*)&packetVer) == FALSE)
-                               packetVer = NULL;
-                       g_module_close(handle);
-               }
-
                g_string_sprintfa(str, "with ");
                if (p_pcap_lib_version != NULL)
                        g_string_sprintfa(str, p_pcap_lib_version());
-               else if (packetVer != NULL)
+               else {
+                       /*
+                        * An alternative method of obtaining the version
+                        * number, by using the PacketLibraryVersion
+                        * string from packet.dll.
+                        *
+                        * Unfortunately, in WinPcap 3.0, it returns
+                        * "3.0 alpha3", even in the final version of
+                        * WinPcap 3.0, so if there's a blank in the
+                        * string, we strip it and everything after
+                        * it from the string, so we don't misleadingly
+                        * report that 3.0 alpha3 is being used when
+                        * the final version is being used.
+                        */
+                       if (packetVer == NULL) {
+                               packetVer = "version unknown";
+                               handle = g_module_open("Packet.dll", 0);
+                               if (handle != NULL) {
+                                       if (g_module_symbol(handle,
+                                           "PacketLibraryVersion",
+                                           (gpointer*)&packetVer)) {
+                                               packetVer = g_strdup(packetVer);
+                                               blankp = strchr(packetVer, ' ');
+                                               if (blankp != NULL)
+                                                       *blankp = '\0';
+                                       } else {
+                                               packetVer = "version unknown";
+                                       }
+                                       g_module_close(handle);
+                               }
+                       }
                        g_string_sprintfa(str, "WinPcap (%s)", packetVer);
-               else
-                       g_string_append(str, "WinPcap (version unknown)");
+               }
        } else
                g_string_append(str, "without WinPcap");
-       g_string_append(str, " ");
 }
 
 #else /* HAVE_LIBPCAP */