iscsi also has a system port (860) registered in addition to the more common
[obnox/wireshark/wip.git] / capture_opts.c
index 243b6919ce370c38c6a7de9fef0bbd7b80ccf488..23297b60eb7d7b083bc2e4b74a06d6d6f71d59d3 100644 (file)
 #include <unistd.h>
 #endif
 
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#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
-
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>           /* needed to define AF_ values on Windows */
-#endif
-
-#ifdef NEED_INET_V6DEFS_H
-# include "inet_v6defs.h"
-#endif
-
 #include <glib.h>
 
 #include <epan/packet.h>
 #include "capture_opts.h"
 #include "ringbuffer.h"
 #include "clopts_common.h"
+#include "console_io.h"
 #include "cmdarg_err.h"
 
+#include "capture_ifinfo.h"
 #include "capture-pcap-util.h"
 #include <wsutil/file_util.h>
 
@@ -96,13 +74,14 @@ capture_opts_init(capture_options *capture_opts, void *cf)
   capture_opts->sampling_param          = 0;
 #endif
 #endif
-#ifdef _WIN32
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
   capture_opts->buffer_size             = 1;                /* 1 MB */
 #endif
   capture_opts->has_snaplen             = FALSE;
   capture_opts->snaplen                 = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
                                                                    infinite, in effect */
   capture_opts->promisc_mode            = TRUE;             /* promiscuous mode is the default */
+  capture_opts->monitor_mode            = FALSE;
   capture_opts->linktype                = -1;               /* the default linktype */
   capture_opts->saving_to_file          = FALSE;
   capture_opts->save_file               = NULL;
@@ -172,7 +151,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
     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
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
     g_log(log_domain, log_level, "BufferSize         : %u (MB)", capture_opts->buffer_size);
 #endif
     g_log(log_domain, log_level, "SnapLen         (%u): %u", capture_opts->has_snaplen, capture_opts->snaplen);
@@ -403,7 +382,7 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
         cmdarg_err("There is no interface with that adapter index");
         return 1;
       }
-      if_list = get_interface_list(&err, &err_str);
+      if_list = capture_interface_list(&err, &err_str);
       if (if_list == NULL) {
         switch (err) {
 
@@ -418,7 +397,7 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
         }
         return 2;
       }
-      if_info = g_list_nth_data(if_list, adapter_index - 1);
+      if_info = (if_info_t *)g_list_nth_data(if_list, adapter_index - 1);
       if (if_info == NULL) {
         cmdarg_err("There is no interface with that adapter index");
         return 1;
@@ -463,7 +442,7 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
           return 1;
         }
         break;
-#ifdef _WIN32
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
     case 'B':        /* Buffer size */
         capture_opts->buffer_size = get_positive_int(optarg_str_p, "buffer size");
         break;
@@ -490,6 +469,11 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
             return status;
         }
         break;
+#ifdef HAVE_PCAP_CREATE
+    case 'I':        /* Capture in monitor mode */
+        capture_opts->monitor_mode = TRUE;
+        break;
+#endif
     case 'k':        /* Start capture immediately */
         *start_capture = TRUE;
         break;
@@ -562,148 +546,49 @@ 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_if_capabilities(if_capabilities_t *caps,
+                                   gboolean monitor_mode)
 {
-    gchar *err_str, *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 = 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');
-        }
+    if (caps->can_set_rfmon)
+        fprintf_stderr("Data link types when %sin monitor mode (use option -y to set):\n",
+                       monitor_mode ? "" : "not ");
+    else
+        fprintf_stderr("Data link types (use option -y to set):\n");
+    for (lt_entry = caps->data_link_types; lt_entry != NULL;
+         lt_entry = g_list_next(lt_entry)) {
+        data_link_info = (data_link_info_t *)lt_entry->data;
+        fprintf_stderr("  %s", data_link_info->name);
+        if (data_link_info->description != NULL)
+            fprintf_stderr(" (%s)", data_link_info->description);
+        else
+            fprintf_stderr(" (not supported)");
+        fprintf_stderr("\n");
     }
-    free_pcap_linktype_list(lt_list);
-
-    return 0;
 }
 
-/* Return an ASCII-formatted list of interfaces. */
-#define ADDRSTRLEN 46 /* Covers IPv4 & IPv6 */
-int
-capture_opts_list_interfaces(gboolean machine_readable)
+/* Print an ASCII-formatted list of interfaces. */
+void
+capture_opts_print_interfaces(GList *if_list)
 {
-    GList       *if_list;
+    int         i;
     GList       *if_entry;
     if_info_t   *if_info;
-    int         err;
-    gchar       *err_str;
-    int         i;
-    GSList      *ip_addr;
-    if_addr_t   *if_addr;
-    char        addr_str[ADDRSTRLEN];
-
-    if_list = get_interface_list(&err, &err_str);
-    if (if_list == NULL) {
-        switch (err) {
-        case CANT_GET_INTERFACE_LIST:
-            cmdarg_err("%s", err_str);
-            g_free(err_str);
-        break;
-
-        case NO_INTERFACES_FOUND:
-            cmdarg_err("There are no interfaces on which a capture can be done");
-        break;
-        }
-        return err;
-    }
 
     i = 1;  /* Interface id number */
     for (if_entry = g_list_first(if_list); if_entry != NULL;
-    if_entry = g_list_next(if_entry)) {
-        if_info = if_entry->data;
+         if_entry = g_list_next(if_entry)) {
+        if_info = (if_info_t *)if_entry->data;
         printf("%d. %s", i++, if_info->name);
 
-        if (!machine_readable) {
-            /* Add the description if it exists */
-            if (if_info->description != NULL)
-                printf(" (%s)", if_info->description);
-        } else {
-            /*
-             * Add the contents of the if_entry struct in a parseable format.
-             * Each if_entry element is tab-separated.  Addresses are comma-
-             * separated.
-             */
-            /* XXX - Make sure our description doesn't contain a tab */
-            if (if_info->description != NULL)
-                printf("\t%s\t", if_info->description);
-            else
-                printf("\t\t");
-
-            for(ip_addr = g_slist_nth(if_info->ip_addr, 0); ip_addr != NULL;
-                        ip_addr = g_slist_next(ip_addr)) {
-                if (ip_addr != g_slist_nth(if_info->ip_addr, 0))
-                    printf(",");
-
-                if_addr = ip_addr->data;
-                switch(if_addr->type) {
-                case AT_IPv4:
-                    if (inet_ntop(AF_INET, &if_addr->ip_addr.ip4_addr, addr_str,
-                                ADDRSTRLEN)) {
-                        printf("%s", addr_str);
-                    } else {
-                        printf("<unknown IPv4>");
-                    }
-                    break;
-                case AT_IPv6:
-                    if (inet_ntop(AF_INET6, &if_addr->ip_addr.ip6_addr,
-                                addr_str, ADDRSTRLEN)) {
-                        printf("%s", addr_str);
-                    } else {
-                        printf("<unknown IPv6>");
-                    }
-                    break;
-                default:
-                    printf("<type unknown %u>", if_addr->type);
-                }
-            }
-
-            if (if_info->loopback)
-                printf("\tloopback");
-            else
-                printf("\tnetwork");
-
-        }
-       printf("\n");
+        /* Print the description if it exists */
+        if (if_info->description != NULL)
+            printf(" (%s)", if_info->description);
+        printf("\n");
     }
-    free_interface_list(if_list);
-
-    return 0;
 }
 
 
@@ -748,7 +633,7 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt
           */
       } else {
         /* No - pick the first one from the list of interfaces. */
-        if_list = get_interface_list(&err, &err_str);
+        if_list = capture_interface_list(&err, &err_str);
         if (if_list == NULL) {
           switch (err) {
 
@@ -763,7 +648,7 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt
           }
           return FALSE;
         }
-        if_info = if_list->data;       /* first interface */
+        if_info = (if_info_t *)if_list->data;  /* first interface */
         capture_opts->iface = g_strdup(if_info->name);
        /*  We don't set iface_descr here because doing so requires
         *  capture_ui_utils.c which requires epan/prefs.c which is