Remove the "-I" flag from dumpcap, and add a "-M" flag used to specify
authorgerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 20 Jul 2007 21:43:07 +0000 (21:43 +0000)
committergerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 20 Jul 2007 21:43:07 +0000 (21:43 +0000)
that "-D" and "-L" should produce machine-readable output.  Use this to
move an indirect get_pcap_linktype() call from the GUI to dumpcap.

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

capture.c
capture.h
capture_opts.c
capture_opts.h
capture_sync.c
capture_sync.h
doc/dumpcap.pod
dumpcap.c
gtk/capture_dlg.c
gtk/main.c
tshark.c

index d18b1d81cb843a1ff7429dc56bc1c29155e48c5e..a09daed2a8f05792ed9a6c45ca61c2c52bb7c5ce 100644 (file)
--- a/capture.c
+++ b/capture.c
@@ -682,5 +682,62 @@ capture_interface_list(int *err, char **err_str)
     return if_list;
 }
 
+/* XXX - We parse simple text output to get our interface list.  Should
+ * we use "real" data serialization instead, e.g. via XML? */
+GList *
+capture_pcap_linktype_list(gchar *ifname, char **err_str)
+{
+    GList     *linktype_list = NULL;
+    int        err, i;
+    gchar     *msg;
+    gchar    **raw_list, **lt_parts;
+    data_link_info_t *data_link_info;
+
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ...");
+
+    /* Try to get our interface list */
+    err = sync_linktype_list_open(ifname, &msg);
+    if (err != 0) {
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!");
+        if (err_str) {
+            *err_str = msg;
+        } else {
+            g_free(msg);
+        }
+        return NULL;
+    }
+
+    /* Split our lines */
+    raw_list = g_strsplit(msg, "\n", 0);
+    g_free(msg);
+
+    for (i = 0; raw_list[i] != NULL; i++) {
+        /* ...and what if the interface name has a tab in it, Mr. Clever Programmer? */
+        lt_parts = g_strsplit(raw_list[i], "\t", 3);
+        if (lt_parts[0] == NULL || lt_parts[1] == NULL || lt_parts[2] == NULL) {
+            g_strfreev(lt_parts);
+            continue;
+        }
+
+        data_link_info = g_malloc(sizeof (data_link_info_t));
+        data_link_info->dlt = (int) strtol(lt_parts[0], NULL, 10);
+        data_link_info->name = g_strdup(lt_parts[1]);
+        if (strcmp(lt_parts[2], "(not supported)") != NULL)
+            data_link_info->description = g_strdup(lt_parts[2]);
+        else
+            data_link_info->description = NULL;
+
+        linktype_list = g_list_append(linktype_list, data_link_info);
+    }
+    g_strfreev(raw_list);
+
+    /* Check to see if we built a list */
+    if (linktype_list == NULL) {
+        if (err_str)
+            *err_str = NULL;
+    }
+    return linktype_list;
+}
+
 
 #endif /* HAVE_LIBPCAP */
index f94883c561b7c4903fcea33307c229f065faa02c..9ced0542a8247a54844124124277f8c528c990c7 100644 (file)
--- a/capture.h
+++ b/capture.h
@@ -86,5 +86,10 @@ extern void capture_input_closed(capture_options *capture_opts);
  */
 extern GList *capture_interface_list(int *err, char **err_str);
 
+/**
+ * Fetch the linktype list for the specified interface from a child process.
+ */
+extern GList *capture_pcap_linktype_list(char *devname, char **err_str);
+
 
 #endif /* capture.h */
index 4472292c632be38b35d6cfcca6bde9e40e0f5b34..15ed92bb4a45c5b6d7a271316d4973dce161aa11 100644 (file)
 #include <netinet/in.h>
 #endif
 
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>         /* needed to define AF_ values on UNIX */
 #endif
@@ -410,10 +414,14 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
     return 0;
 }
 
-
-int capture_opts_list_link_layer_types(capture_options *capture_opts)
+/*
+ * 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)
 {
-    gchar *err_str;
+    gchar *err_str, *desc_str;
     GList *lt_list, *lt_entry;
     data_link_info_t *data_link_info;
 
@@ -429,16 +437,28 @@ int capture_opts_list_link_layer_types(capture_options *capture_opts)
         cmdarg_err("The capture device \"%s\" has no data link types.", capture_opts->iface);
       return 2;
     }
-    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 = 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
-        cmdarg_err_cont(" (not supported)");
-      putchar('\n');
+    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 = 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 = 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
+            cmdarg_err_cont(" (not supported)");
+          putchar('\n');
+        }
     }
     free_pcap_linktype_list(lt_list);
 
@@ -448,7 +468,7 @@ int capture_opts_list_link_layer_types(capture_options *capture_opts)
 /* Return an ASCII-formatted list of interfaces. */
 #define ADDRSTRLEN 46 /* Covers IPv4 & IPv6 */
 int
-capture_opts_list_interfaces(gboolean verbose)
+capture_opts_list_interfaces(gboolean machine_readable)
 {
     GList       *if_list;
     GList       *if_entry;
@@ -481,7 +501,7 @@ capture_opts_list_interfaces(gboolean verbose)
         if_info = if_entry->data;
         printf("%d. %s", i++, if_info->name);
 
-        if (!verbose) {
+        if (!machine_readable) {
             /* Add the description if it exists */
             if (if_info->description != NULL)
                 printf(" (%s)", if_info->description);
index 4cb76eb1a38097599554ace7779b029e86261271..df5a6ef9cb96d52128689695764ca21cc4222302 100644 (file)
@@ -114,11 +114,11 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
 
 /* list link layer types */
 extern int
-capture_opts_list_link_layer_types(capture_options *capture_opts);
+capture_opts_list_link_layer_types(capture_options *capture_opts, gboolean machine_readable);
 
 /* list interfaces */
 extern int
-capture_opts_list_interfaces(gboolean verbose);
+capture_opts_list_interfaces(gboolean machine_readable);
 
 /* trim the snaplen entry */
 extern void
index 4dac5a371add879b53cf77ed3ac7dc0646b9f766..02215ecde8ba0959bfeb6b4ee53bfa19bbbfb32f 100644 (file)
@@ -208,10 +208,35 @@ protect_arg (const gchar *argv)
 }
 #endif
 
+/* Initialize an argument list and add dumpcap to it. */
+static const char **
+init_pipe_args(int *argc) {
+    const char **argv;
+    const char *progfile_dir;
+    char *exename;
 
+    progfile_dir = get_progfile_dir();
+    if (progfile_dir == NULL) {
+      return NULL;
+    }
 
-#define ARGV_NUMBER_LEN 24
+    /* Allocate the string pointer array with enough space for the
+       terminating NULL pointer. */
+    *argc = 0;
+    argv = g_malloc(sizeof (char *));
+    *argv = NULL;
+
+    /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
+    exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
+
+    /* Make that the first argument in the argument list (argv[0]). */
+    argv = sync_pipe_add_arg(argv, argc, exename);
+
+    return argv;
+}
 
+
+#define ARGV_NUMBER_LEN 24
 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
 gboolean
 sync_pipe_start(capture_options *capture_opts) {
@@ -241,8 +266,6 @@ sync_pipe_start(capture_options *capture_opts) {
     enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
 #endif
     int sync_pipe_read_fd;
-    const char *progfile_dir;
-    char *exename;
     int argc;
     const char **argv;
 
@@ -252,25 +275,13 @@ sync_pipe_start(capture_options *capture_opts) {
 
     capture_opts->fork_child = -1;
 
-    progfile_dir = get_progfile_dir();
-    if (progfile_dir == NULL) {
-      /* We don't know where to find dumpcap. */
-      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
-      return FALSE;
+    argv = init_pipe_args(&argc);
+    if (!argv) {
+        /* We don't know where to find dumpcap. */
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
+        return FALSE;
     }
 
-    /* Allocate the string pointer array with enough space for the
-       terminating NULL pointer. */
-    argc = 0;
-    argv = g_malloc(sizeof (char *));
-    *argv = NULL;
-
-    /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
-    exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
-
-    /* Make that the first argument in the argument list (argv[0]). */
-    argv = sync_pipe_add_arg(argv, &argc, exename);
-
     argv = sync_pipe_add_arg(argv, &argc, "-i");
     argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
 
@@ -451,9 +462,9 @@ sync_pipe_start(capture_options *capture_opts) {
       eth_close(1);
       dup(sync_pipe[PIPE_WRITE]);
       eth_close(sync_pipe[PIPE_READ]);
-      execv(exename, (gpointer)argv);
+      execv(argv[0], (gpointer)argv);
       g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
-               exename, strerror(errno));
+               argv[0], strerror(errno));
       sync_pipe_errmsg_to_parent(errmsg, "");
 
       /* Exit with "_exit()", so that we don't close the connection
@@ -466,7 +477,7 @@ sync_pipe_start(capture_options *capture_opts) {
     sync_pipe_read_fd = sync_pipe[PIPE_READ];
 #endif
 
-    g_free(exename);
+    g_free(argv[0]);  /* exename */
 
     /* Parent process - read messages from the child process over the
        sync pipe. */
@@ -509,15 +520,15 @@ sync_pipe_start(capture_options *capture_opts) {
 }
 
 /*
- * Get an interface list using dumpcap.  On success, msg points to
+ * Run dumpcap with the supplied arguments.  On success, msg points to
  * a buffer containing the dumpcap output and returns 0.  On failure, msg
  * points to the error message returned by dumpcap, and returns dumpcap's
  * exit value.  In either case, msg must be freed with g_free().
  */
-/* XXX - This duplicates a lot of code in sync_pipe_start() and sync_interface_list_open() */
+/* XXX - This duplicates a lot of code in sync_pipe_start() */
 #define PIPE_BUF_SIZE 5120
-int
-sync_interface_list_open(gchar **msg) {
+static int
+sync_pipe_run_command(const char** argv, gchar **msg) {
 #ifdef _WIN32
     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
     HANDLE sync_pipe_write;                 /* pipe used to send messages from parent to child */
@@ -533,15 +544,11 @@ sync_interface_list_open(gchar **msg) {
 #endif
     int fork_child = -1, fork_child_status;
     int sync_pipe_read_fd = -1;
-    const char *progfile_dir;
-    char *exename;
-    int argc;
-    const char **argv;
     GString *msg_buf = NULL;
     gchar buf[PIPE_BUF_SIZE+1];
     int count;
 
-    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
 
     if (!msg) {
         /* We can't return anything */
@@ -551,36 +558,6 @@ sync_interface_list_open(gchar **msg) {
         return -1;
     }
 
-    progfile_dir = get_progfile_dir();
-    if (progfile_dir == NULL) {
-        /* We don't know where to find dumpcap. */
-        *msg = g_strdup("We don't know where to find dumpcap.");
-        return CANT_RUN_DUMPCAP;
-    }
-
-    /* Allocate the string pointer array with enough space for the
-       terminating NULL pointer. */
-    argc = 0;
-    argv = g_malloc(sizeof (char *));
-    *argv = NULL;
-
-    /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
-    exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
-
-    /* Make that the first argument in the argument list (argv[0]). */
-    argv = sync_pipe_add_arg(argv, &argc, exename);
-
-    /* Ask for the interface list */
-    argv = sync_pipe_add_arg(argv, &argc, "-I");
-    argv = sync_pipe_add_arg(argv, &argc, "l");
-
-
-    /* dumpcap should be running in capture child mode (hidden feature) */
-#ifndef DEBUG_CHILD
-    argv = sync_pipe_add_arg(argv, &argc, "-Z");
-#endif
-
-
 #ifdef _WIN32
     /* init SECURITY_ATTRIBUTES */
     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
@@ -654,16 +631,16 @@ sync_interface_list_open(gchar **msg) {
         eth_close(1);
         dup(sync_pipe[PIPE_WRITE]);
         eth_close(sync_pipe[PIPE_READ]);
-        execv(exename, (gpointer)argv);
+        execv(argv[0], (gpointer)argv);
         *msg = g_strdup_printf("Couldn't run %s in child process: %s",
-                exename, strerror(errno));
+                argv[0], strerror(errno));
         return CANT_RUN_DUMPCAP;
     }
 
     sync_pipe_read_fd = sync_pipe[PIPE_READ];
 #endif
 
-    g_free(exename);
+    g_free(argv[0]);  /* exename */
 
     /* Parent process - read messages from the child process over the
        sync pipe. */
@@ -745,6 +722,129 @@ sync_interface_list_open(gchar **msg) {
     return fork_child_status;
 }
 
+/*
+ * Get an interface list using dumpcap.  On success, msg points to
+ * a buffer containing the dumpcap output and returns 0.  On failure, msg
+ * points to the error message returned by dumpcap, and returns dumpcap's
+ * exit value.  In either case, msg must be freed with g_free().
+ */
+int
+sync_interface_list_open(gchar **msg) {
+    int argc;
+    const char **argv;
+
+    if (!msg) {
+        /* We can't return anything */
+#ifdef _WIN32
+        g_string_free(args, TRUE);
+#endif
+        return -1;
+    }
+
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
+
+    argv = init_pipe_args(&argc);
+
+    if (!argv) {
+        *msg = g_strdup_printf("We don't know where to find dumpcap.");
+        return CANT_RUN_DUMPCAP;
+    }
+
+    /* Ask for the interface list */
+    argv = sync_pipe_add_arg(argv, &argc, "-D");
+    argv = sync_pipe_add_arg(argv, &argc, "-M");
+
+    /* dumpcap should be running in capture child mode (hidden feature) */
+#ifndef DEBUG_CHILD
+    argv = sync_pipe_add_arg(argv, &argc, "-Z");
+#endif
+
+    return sync_pipe_run_command(argv, msg);
+}
+
+/*
+ * Get an linktype list using dumpcap.  On success, msg points to
+ * a buffer containing the dumpcap output and returns 0.  On failure, msg
+ * points to the error message returned by dumpcap, and returns dumpcap's
+ * exit value.  In either case, msg must be freed with g_free().
+ */
+int
+sync_linktype_list_open(gchar *ifname, gchar **msg) {
+    int argc;
+    const char **argv;
+
+    if (!msg) {
+        /* We can't return anything */
+#ifdef _WIN32
+        g_string_free(args, TRUE);
+#endif
+        return -1;
+    }
+
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
+
+    argv = init_pipe_args(&argc);
+
+    if (!argv) {
+        *msg = g_strdup_printf("We don't know where to find dumpcap.");
+        return CANT_RUN_DUMPCAP;
+    }
+
+    /* Ask for the linktype list */
+    argv = sync_pipe_add_arg(argv, &argc, "-i");
+    argv = sync_pipe_add_arg(argv, &argc, ifname);
+    argv = sync_pipe_add_arg(argv, &argc, "-L");
+    argv = sync_pipe_add_arg(argv, &argc, "-M");
+
+    /* dumpcap should be running in capture child mode (hidden feature) */
+#ifndef DEBUG_CHILD
+    argv = sync_pipe_add_arg(argv, &argc, "-Z");
+#endif
+
+    return sync_pipe_run_command(argv, msg);
+}
+
+/*
+ * Get interface stats using dumpcap.  On success, msg points to
+ * a buffer containing the dumpcap output and returns 0.  On failure, msg
+ * points to the error message returned by dumpcap, and returns dumpcap's
+ * exit value.  In either case, msg must be freed with g_free().
+ */
+int
+sync_interface_stats_open(gchar *ifname, gchar **msg) {
+    int argc;
+    const char **argv;
+
+    if (!msg) {
+        /* We can't return anything */
+#ifdef _WIN32
+        g_string_free(args, TRUE);
+#endif
+        return -1;
+    }
+
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
+
+    argv = init_pipe_args(&argc);
+
+    if (!argv) {
+        *msg = g_strdup_printf("We don't know where to find dumpcap.");
+        return CANT_RUN_DUMPCAP;
+    }
+
+    /* Ask for the linktype list */
+    argv = sync_pipe_add_arg(argv, &argc, "-i");
+    argv = sync_pipe_add_arg(argv, &argc, ifname);
+    argv = sync_pipe_add_arg(argv, &argc, "-S");
+    argv = sync_pipe_add_arg(argv, &argc, "-M");
+
+    /* dumpcap should be running in capture child mode (hidden feature) */
+#ifndef DEBUG_CHILD
+    argv = sync_pipe_add_arg(argv, &argc, "-Z");
+#endif
+
+    return sync_pipe_run_command(argv, msg);
+}
 
 /* read a number of bytes from a pipe */
 /* (blocks until enough bytes read or an error occurs) */
index 5e3cb7c9e5049dee522b8ad8f39906189f74b61d..e82027efc7c557bdee4c6ed33ed6da7602e7f200 100644 (file)
@@ -67,5 +67,8 @@ signal_pipe_check_running(void);
 extern int
 sync_interface_list_open(gchar **msg);
 
+/** Get a linktype list using dumpcap */
+extern int
+sync_linktype_list_open(gchar *ifname, gchar **msg);
 
 #endif /* capture_sync.h */
index 9e9ed8f3aee4130be497afca60c4ec2338ce28ba..78528030964b2d738b9d06649c1cc44a11e81a6a 100644 (file)
@@ -14,8 +14,8 @@ S<[ B<-D> ]>
 S<[ B<-f> E<lt>capture filterE<gt> ]>
 S<[ B<-h> ]>
 S<[ B<-i> E<lt>capture interfaceE<gt>|- ]> 
-S<[ B<-I> E<lt>l|sE<gt> ]>
 S<[ B<-L> ]>
+S<[ B<-M> ]>
 S<[ B<-p> ]>
 S<[ B<-s> E<lt>capture snaplenE<gt> ]>
 S<[ B<-v> ]>
@@ -156,19 +156,15 @@ standard libpcap format.
 Note: the Win32 version of B<Dumpcap> doesn't support capturing from
 pipes or stdin!
 
-=item -I
-
-If run with the B<l> argument, print a verbose, machine-readable interface
-list, similar to the B<-D> flag.
-
-If run with the B<s> argument, print statistics for each interface every
-second until the program terminates.
-
 =item -L
 
 List the data link types supported by the interface and exit. The reported
 link types can be used for the B<-y> option.
 
+=item -M
+
+When used with B<-D> and B<-L>, print verbose, machine-readable output.
+
 =item -p
 
 I<Don't> put the interface into promiscuous mode.  Note that the
index 9a540407c8bf6f5f8f8f99a843b8659a68f0eea3..2c054c492ad59d0eab0639ea04869f0c468ed257 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -115,7 +115,7 @@ print_usage(gboolean print_ver) {
   fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
   fprintf(output, "  -D                       print list of interfaces and exit\n");
   fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
-  fprintf(output, "  -I [l|s]                 print a detailed interface list (l) or interface statistics (s).\n");
+  fprintf(output, "  -M                       for -D and -L, produce machine-readable output\n");
   fprintf(output, "\n");
   fprintf(output, "Stop conditions:\n");
   fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
@@ -246,10 +246,12 @@ main(int argc, char *argv[])
   gboolean             stats_known;
   struct pcap_stat     stats;
   GLogLevelFlags       log_flags;
+  gboolean             list_interfaces = FALSE;
   gboolean             list_link_layer_types = FALSE;
+  gboolean             machine_readable = FALSE;
   int                  status;
 
-#define OPTSTRING_INIT "a:b:c:Df:hI:i:Lps:vw:y:Z"
+#define OPTSTRING_INIT "a:b:c:Df:hi:LMps:vw:y:Z"
 
 #ifdef _WIN32
 #define OPTSTRING_WIN32 "B:"
@@ -366,18 +368,14 @@ main(int argc, char *argv[])
 
       /*** all non capture option specific ***/
       case 'D':        /* Print a list of capture devices and exit */
-        status = capture_opts_list_interfaces(FALSE);
-        exit_main(status);
+        list_interfaces = TRUE;
         break;
-      /* XXX - We might want to use 'D' for this.  Do we use GNU
-       * getopt on every platform (which supports optional arguments)? */
-      /* XXX - Implement interface stats */
-      case 'I':
-        status = capture_opts_list_interfaces(TRUE);
-        exit_main(status);
       case 'L':        /* Print list of link-layer types and exit */
         list_link_layer_types = TRUE;
         break;
+      case 'M':        /* For -D and -L, print machine-readable output */
+        machine_readable = TRUE;
+        break;
       default:
       case '?':        /* Bad flag - print usage message */
         cmdarg_err("Invalid Option: %s", argv[optind-1]);
@@ -408,7 +406,10 @@ main(int argc, char *argv[])
     exit_main(1);
   }
 
-  if (list_link_layer_types) {
+  if (list_interfaces && list_link_layer_types) {
+    cmdarg_err("Only one of -D or -L may be supplied.");
+    exit_main(1);
+  } else if (list_link_layer_types) {
     /* We're supposed to list the link-layer types for an interface;
        did the user also specify a capture file to be read? */
     /* No - did they specify a ring buffer option? */
@@ -445,8 +446,11 @@ main(int argc, char *argv[])
   /* get_interface_descriptive_name() is not available! */
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Interface: %s\n", capture_opts->iface);
 
-  if (list_link_layer_types) {
-    status = capture_opts_list_link_layer_types(capture_opts);
+  if (list_interfaces) {
+    status = capture_opts_list_interfaces(machine_readable);
+    exit_main(status);
+  } else if (list_link_layer_types) {
+    status = capture_opts_list_link_layer_types(capture_opts, machine_readable);
     exit_main(status);
   }
 
index 54b95b07bd7bbcd60120c6e500088b111ee22bca..66fa5653849626a55ac3eb273d7929e868e7fab0 100644 (file)
@@ -249,7 +249,7 @@ set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
           * It's in the list.
           * Get the list of link-layer types for it.
           */
-         lt_list = get_pcap_linktype_list(if_name, NULL);
+         lt_list = capture_pcap_linktype_list(if_name, NULL);
 
          /* create string of list of IP addresses of this interface */
          for (; (curr_ip = g_slist_nth(if_info->ip_addr, ips)) != NULL; ips++) {
index 2853de64044acdb83745791ffcd0384f118fae45..b4589da1e75c80c0cab59c118429e0cd0518f97f 100644 (file)
@@ -2823,7 +2823,7 @@ main(int argc, char *argv[])
   }
 
   if (list_link_layer_types) {
-    status = capture_opts_list_link_layer_types(capture_opts);
+    status = capture_opts_list_link_layer_types(capture_opts, FALSE);
     exit(status);
   }
 
index ab1edaed3054efeed0b1c0dd870872a2a9d57899..60c3488d09fad1abdedbfa259d7bc5a0091f0347 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -1523,7 +1523,7 @@ 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(&capture_opts);
+        status = capture_opts_list_link_layer_types(&capture_opts, FALSE);
         exit(status);
     }