For TShark and Wireshark, get the list of link-layer types for an
authorGuy Harris <guy@alum.mit.edu>
Fri, 7 May 2010 08:06:25 +0000 (08:06 -0000)
committerGuy Harris <guy@alum.mit.edu>
Fri, 7 May 2010 08:06:25 +0000 (08:06 -0000)
interface by running dumpcap, so that if you need privileges to open an
interface, and dumpcap has those privileges, neither TShark nor
Wireshark need them.

svn path=/trunk/; revision=32710

capture-pcap-util.c
capture-pcap-util.h
capture_opts.c
capture_opts.h
dumpcap.c
gtk/main.c
tshark.c

index ef2588042e1549f863c55d4bbc323bd3396f6136..1c7815fa4e519ee7603a53b1973a977296cd6f24 100644 (file)
@@ -438,111 +438,6 @@ pcap_datalink_val_to_description(int dlt)
 
 #endif /* !defined(HAVE_PCAP_DATALINK_VAL_TO_NAME) || !defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION) */
 
-/*
- * Get the data-link types available for a libpcap device.
- */
-static data_link_info_t *
-create_data_link_info(int dlt)
-{
-       data_link_info_t *data_link_info;
-       const char *text;
-
-       data_link_info = (data_link_info_t *)g_malloc(sizeof (data_link_info_t));
-       data_link_info->dlt = dlt;
-       text = pcap_datalink_val_to_name(dlt);
-       if (text != NULL)
-               data_link_info->name = g_strdup(text);
-       else
-               data_link_info->name = g_strdup_printf("DLT %d", dlt);
-       text = pcap_datalink_val_to_description(dlt);
-       if (text != NULL)
-               data_link_info->description = g_strdup(text);
-       else
-               data_link_info->description = NULL;
-       return data_link_info;
-}
-
-GList *
-get_pcap_linktype_list(const char *devname, char **err_str)
-{
-       GList *linktype_list = NULL;
-       pcap_t *pch;
-       int deflt;
-       char errbuf[PCAP_ERRBUF_SIZE];
-#ifdef HAVE_PCAP_LIST_DATALINKS
-       int *linktypes;
-       int i, nlt;
-#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);
-               return NULL;
-       }
-       deflt = get_pcap_linktype(pch, devname);
-#ifdef HAVE_PCAP_LIST_DATALINKS
-       nlt = pcap_list_datalinks(pch, &linktypes);
-       if (nlt == 0 || linktypes == NULL) {
-               pcap_close(pch);
-               if (err_str != NULL)
-                       *err_str = NULL;        /* an empty list doesn't mean an error */
-               return NULL;
-       }
-       for (i = 0; i < nlt; i++) {
-               data_link_info = create_data_link_info(linktypes[i]);
-
-               /*
-                * XXX - for 802.11, make the most detailed 802.11
-                * version the default, rather than the one the
-                * device has as the default?
-                */
-               if (linktypes[i] == deflt)
-                       linktype_list = g_list_prepend(linktype_list,
-                           data_link_info);
-               else
-                       linktype_list = g_list_append(linktype_list,
-                           data_link_info);
-       }
-#ifdef HAVE_PCAP_FREE_DATALINKS
-       pcap_free_datalinks(linktypes);
-#else
-       /*
-        * In Windows, there's no guarantee that if you have a library
-        * built with one version of the MSVC++ run-time library, and
-        * it returns a pointer to allocated data, you can free that
-        * data from a program linked with another version of the
-        * MSVC++ run-time library.
-        *
-        * This is not an issue on UN*X.
-        *
-        * See the mail threads starting at
-        *
-        *      http://www.winpcap.org/pipermail/winpcap-users/2006-September/001421.html
-        *
-        * and
-        *
-        *      http://www.winpcap.org/pipermail/winpcap-users/2008-May/002498.html
-        */
-#ifndef _WIN32
-#define xx_free free  /* hack so checkAPIs doesn't complain */
-       xx_free(linktypes);
-#endif /* _WIN32 */
-#endif /* HAVE_PCAP_FREE_DATALINKS */
-#else /* HAVE_PCAP_LIST_DATALINKS */
-       data_link_info = create_data_link_info(deflt);
-       linktype_list = g_list_append(linktype_list, data_link_info);
-#endif /* HAVE_PCAP_LIST_DATALINKS */
-
-       pcap_close(pch);
-       return linktype_list;
-}
-
 static void
 free_linktype_cb(gpointer data, gpointer user_data _U_)
 {
index c1fe38f147d2f47dc886b48acc5044b27120a51f..035da2f69bc3954b11bb959d9140564ed5dd5cf4 100644 (file)
@@ -49,8 +49,6 @@ GList *get_remote_interface_list(const char *hostname, const char *port,
                                  const char *passwd, int *err, char **err_str);
 #endif
 
-GList *get_pcap_linktype_list(const char *devname, char **err_str);
-
 /* get/set the link type of an interface */
 /* (only used in capture_loop.c / capture-pcap-util.c) */
 int get_pcap_linktype(pcap_t *pch, const char *devname);
index 60bccf06de5893292e95db82c72926e8e7580f61..67d4237a80d0080eebcb96d8ceed07ad68b96b13 100644 (file)
@@ -571,56 +571,23 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
     return 0;
 }
 
-/*
- * If you change the output format of this function, you MUST update
- * capture_sync.c:sync_linktype_list_open() accordingly!
- */
-int
-capture_opts_list_link_layer_types(capture_options *capture_opts, gboolean machine_readable)
+void
+capture_opts_print_link_layer_types(GList *lt_list)
 {
-    gchar *err_str;
-    const gchar *desc_str;
-    GList *lt_list, *lt_entry;
+    GList *lt_entry;
     data_link_info_t *data_link_info;
 
-    /* Get the list of link-layer types for the capture device. */
-    lt_list = get_pcap_linktype_list(capture_opts->iface, &err_str);
-    if (lt_list == NULL) {
-      if (err_str != NULL) {
-        cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
-         "Please check to make sure you have sufficient permissions, and that\n"
-         "you have the proper interface or pipe specified.\n", capture_opts->iface, err_str);
-        g_free(err_str);
-      } else
-        cmdarg_err("The capture device \"%s\" has no data link types.", capture_opts->iface);
-      return 2;
-    }
-    if (machine_readable) {    /* tab-separated values to stdout */
-        for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
-          data_link_info = (data_link_info_t *)lt_entry->data;
-          if (data_link_info->description != NULL)
-              desc_str = data_link_info->description;
-          else
-              desc_str = "(not supported)";
-          printf("%d\t%s\t%s\n", data_link_info->dlt, data_link_info->name,
-              desc_str);
-        }
-    } else {
-        cmdarg_err_cont("Data link types (use option -y to set):");
-        for (lt_entry = lt_list; lt_entry != NULL;
-             lt_entry = g_list_next(lt_entry)) {
-          data_link_info = (data_link_info_t *)lt_entry->data;
-          cmdarg_err_cont("  %s", data_link_info->name);
-          if (data_link_info->description != NULL)
+    cmdarg_err_cont("Data link types (use option -y to set):");
+    for (lt_entry = lt_list; lt_entry != NULL;
+         lt_entry = g_list_next(lt_entry)) {
+        data_link_info = (data_link_info_t *)lt_entry->data;
+        cmdarg_err_cont("  %s", data_link_info->name);
+        if (data_link_info->description != NULL)
             cmdarg_err_cont(" (%s)", data_link_info->description);
-          else
+        else
             cmdarg_err_cont(" (not supported)");
-          putchar('\n');
-        }
+        putchar('\n');
     }
-    free_pcap_linktype_list(lt_list);
-
-    return 0;
 }
 
 /* Return an ASCII-formatted list of interfaces. */
index d4bacb4f1994bed92d0c21dfa88fcd913debc8a9..3b1b869398596a63abd713d52197fbd5dafa5e09 100644 (file)
@@ -175,9 +175,9 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
 extern void
 capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_options *capture_opts);
 
-/* list link layer types */
-extern int
-capture_opts_list_link_layer_types(capture_options *capture_opts, gboolean machine_readable);
+/* print list of link layer types */
+extern void
+capture_opts_print_link_layer_types(GList *lt_list);
 
 /* list interfaces */
 extern int
index d06f151292fe44611f749c79608ef75a4832a428..944e5606e19a6003b4c305dfc846181c27cf440a 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -449,6 +449,135 @@ capture_interface_list(int *err, char **err_str)
   return get_interface_list(err, err_str);
 }
 
+/*
+ * Get the data-link types available for a libpcap device.
+ */
+static data_link_info_t *
+create_data_link_info(int dlt)
+{
+    data_link_info_t *data_link_info;
+    const char *text;
+
+    data_link_info = (data_link_info_t *)g_malloc(sizeof (data_link_info_t));
+    data_link_info->dlt = dlt;
+    text = pcap_datalink_val_to_name(dlt);
+    if (text != NULL)
+        data_link_info->name = g_strdup(text);
+    else
+        data_link_info->name = g_strdup_printf("DLT %d", dlt);
+    text = pcap_datalink_val_to_description(dlt);
+    if (text != NULL)
+        data_link_info->description = g_strdup(text);
+    else
+        data_link_info->description = NULL;
+    return data_link_info;
+}
+
+static GList *
+get_pcap_linktype_list(const char *devname, char **err_str)
+{
+    GList *linktype_list = NULL;
+    pcap_t *pch;
+    int deflt;
+    char errbuf[PCAP_ERRBUF_SIZE];
+#ifdef HAVE_PCAP_LIST_DATALINKS
+    int *linktypes;
+    int i, nlt;
+#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);
+            return NULL;
+    }
+    deflt = get_pcap_linktype(pch, devname);
+#ifdef HAVE_PCAP_LIST_DATALINKS
+    nlt = pcap_list_datalinks(pch, &linktypes);
+    if (nlt == 0 || linktypes == NULL) {
+        pcap_close(pch);
+        if (err_str != NULL)
+            *err_str = NULL; /* an empty list doesn't mean an error */
+        return NULL;
+    }
+    for (i = 0; i < nlt; i++) {
+        data_link_info = create_data_link_info(linktypes[i]);
+
+        /*
+         * XXX - for 802.11, make the most detailed 802.11
+         * version the default, rather than the one the
+         * device has as the default?
+         */
+        if (linktypes[i] == deflt)
+            linktype_list = g_list_prepend(linktype_list, data_link_info);
+        else
+            linktype_list = g_list_append(linktype_list, data_link_info);
+    }
+#ifdef HAVE_PCAP_FREE_DATALINKS
+    pcap_free_datalinks(linktypes);
+#else
+    /*
+     * In Windows, there's no guarantee that if you have a library
+     * built with one version of the MSVC++ run-time library, and
+     * it returns a pointer to allocated data, you can free that
+     * data from a program linked with another version of the
+     * MSVC++ run-time library.
+     *
+     * This is not an issue on UN*X.
+     *
+     * See the mail threads starting at
+     *
+     *    http://www.winpcap.org/pipermail/winpcap-users/2006-September/001421.html
+     *
+     * and
+     *
+     *    http://www.winpcap.org/pipermail/winpcap-users/2008-May/002498.html
+     */
+#ifndef _WIN32
+#define xx_free free  /* hack so checkAPIs doesn't complain */
+    xx_free(linktypes);
+#endif /* _WIN32 */
+#endif /* HAVE_PCAP_FREE_DATALINKS */
+#else /* HAVE_PCAP_LIST_DATALINKS */
+
+    data_link_info = create_data_link_info(deflt);
+    linktype_list = g_list_append(linktype_list, data_link_info);
+#endif /* HAVE_PCAP_LIST_DATALINKS */
+
+    pcap_close(pch);
+
+    if (err_str != NULL)
+        *err_str = NULL;
+    return linktype_list;
+}
+
+/*
+ * If you change the machine-readable output format of this function,
+ * you MUST update capture_sync.c:sync_linktype_list_open() accordingly!
+ */
+static void
+print_machine_readable_link_layer_types(GList *lt_list)
+{
+    GList *lt_entry;
+    data_link_info_t *data_link_info;
+    const gchar *desc_str;
+
+    for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
+      data_link_info = (data_link_info_t *)lt_entry->data;
+      if (data_link_info->description != NULL)
+        desc_str = data_link_info->description;
+      else
+        desc_str = "(not supported)";
+      printf("%d\t%s\t%s\n", data_link_info->dlt, data_link_info->name,
+             desc_str);
+    }
+}
+
 typedef struct {
     char *name;
     pcap_t *pch;
@@ -3123,8 +3252,27 @@ main(int argc, char *argv[])
     status = capture_opts_list_interfaces(machine_readable);
     exit_main(status);
   } else if (list_link_layer_types) {
-    status = capture_opts_list_link_layer_types(&global_capture_opts, machine_readable);
-    exit_main(status);
+    /* Get the list of link-layer types for the capture device. */
+    GList *lt_list;
+    gchar *err_str;
+
+    lt_list = get_pcap_linktype_list(global_capture_opts.iface, &err_str);
+    if (lt_list == NULL) {
+      if (err_str != NULL) {
+        cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
+         "Please check to make sure you have sufficient permissions, and that\n"
+         "you have the proper interface or pipe specified.\n", global_capture_opts.iface, err_str);
+        g_free(err_str);
+      } else
+        cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+      exit_main(2);
+    }
+    if (machine_readable)      /* tab-separated values to stdout */
+      print_machine_readable_link_layer_types(lt_list);
+    else
+      capture_opts_print_link_layer_types(lt_list);
+    free_pcap_linktype_list(lt_list);
+    exit_main(0);
   } else if (print_statistics) {
     status = print_statistics_loop(machine_readable);
     exit_main(status);
index 528970606b91aee8519a4af1ad80188a62990580..83046dd19a2c89c4f4fa15fe91f9c62532c214a3 100644 (file)
 
 #ifdef HAVE_LIBPCAP
 #include "../capture-pcap-util.h"
+#include "../capture_ifinfo.h"
 #include "../capture.h"
 #include "../capture_sync.h"
 #endif
@@ -2703,8 +2704,24 @@ main(int argc, char *argv[])
   }
 
   if (list_link_layer_types) {
-    status = capture_opts_list_link_layer_types(&global_capture_opts, FALSE);
-    exit(status);
+    /* Get the list of link-layer types for the capture device. */
+    GList *lt_list;
+    gchar *err_str;
+
+    lt_list = capture_pcap_linktype_list(global_capture_opts.iface, &err_str);
+    if (lt_list == NULL) {
+      if (err_str != NULL) {
+        cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
+         "Please check to make sure you have sufficient permissions, and that\n"
+         "you have the proper interface or pipe specified.\n", global_capture_opts.iface, err_str);
+        g_free(err_str);
+      } else
+        cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+      exit(2);
+    }
+    capture_opts_print_link_layer_types(lt_list);
+    free_pcap_linktype_list(lt_list);
+    exit(0);
   }
 
   capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
index ffc2e2c1db450078624ca769d2168ac4fd470e75..33cbb103d147090f8d35e84d46a29fc6ec316463 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -89,6 +89,7 @@
 
 #ifdef HAVE_LIBPCAP
 #include "capture_ui_utils.h"
+#include "capture_ifinfo.h"
 #include "capture-pcap-util.h"
 #ifdef _WIN32
 #include "capture-wpcap.h"
@@ -1620,8 +1621,24 @@ main(int argc, char *argv[])
 
     /* if requested, list the link layer types and exit */
     if (list_link_layer_types) {
-        status = capture_opts_list_link_layer_types(&global_capture_opts, FALSE);
-        exit(status);
+        /* Get the list of link-layer types for the capture device. */
+        GList *lt_list;
+        gchar *err_str;
+
+        lt_list = capture_pcap_linktype_list(global_capture_opts.iface, &err_str);
+        if (lt_list == NULL) {
+            if (err_str != NULL) {
+                cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
+                 "Please check to make sure you have sufficient permissions, and that\n"
+                 "you have the proper interface or pipe specified.\n", global_capture_opts.iface, err_str);
+                g_free(err_str);
+            } else
+                cmdarg_err("The capture device \"%s\" has no data link types.", global_capture_opts.iface);
+            exit(2);
+        }
+        capture_opts_print_link_layer_types(lt_list);
+        free_pcap_linktype_list(lt_list);
+        exit(0);
     }
 
     if (print_packet_info) {