Convert "4 space tabs" to spaces; Minor reformatting.
[obnox/wireshark/wip.git] / capture_ifinfo.c
index 53e024749f27ab11a2639b7a2d870412af844bb9..be57f02ebd69fae85802a89aefb56a19bdf69d1b 100644 (file)
@@ -44,7 +44,7 @@
 #endif
 
 #ifdef NEED_INET_V6DEFS_H
-# include "inet_v6defs.h"
+# include "wsutil/inet_v6defs.h"
 #endif
 
 #include <glib.h>
 
 #include "capture_ifinfo.h"
 
+#ifdef HAVE_PCAP_REMOTE
+static GList *remote_interface_list = NULL;
+
+static void append_remote_list(GList *iflist)
+{
+    GSList *list;
+    GList *rlist;
+    if_addr_t *if_addr, *temp_addr;
+    if_info_t *if_info, *temp;
+
+    for (rlist = g_list_nth(remote_interface_list, 0); rlist != NULL; rlist = g_list_next(rlist)) {
+        if_info = (if_info_t *)rlist->data;
+        temp = g_malloc0(sizeof(if_info_t));
+        temp->name = g_strdup(if_info->name);
+        temp->description = g_strdup(if_info->description);
+        for (list = g_slist_nth(if_info->addrs, 0); list != NULL; list = g_slist_next(list)) {
+            temp_addr = g_malloc0(sizeof(if_addr_t));
+            if_addr = (if_addr_t *)list->data;
+            if (if_addr) {
+                temp_addr->ifat_type = if_addr->ifat_type;
+                if (temp_addr->ifat_type == IF_AT_IPv4) {
+                    temp_addr->addr.ip4_addr = if_addr->addr.ip4_addr;
+                } else {
+                    memcpy(temp_addr->addr.ip6_addr, if_addr->addr.ip6_addr, sizeof(if_addr->addr));
+                }
+            } else {
+                g_free(temp_addr);
+                temp_addr = NULL;
+            }
+            if (temp_addr) {
+                temp->addrs = g_slist_append(temp->addrs, temp_addr);
+            }
+        }
+        temp->loopback = if_info->loopback;
+        iflist = g_list_append(iflist, temp);
+   }
+}
+#endif
+
 /**
  * Fetch the interface list from a child process (dumpcap).
  *
@@ -70,7 +109,7 @@ capture_interface_list(int *err, char **err_str)
     int        ret;
     GList     *if_list = NULL;
     int        i, j;
-    gchar     *msg;
+    gchar     *data, *primary_msg, *secondary_msg;
     gchar    **raw_list, **if_parts, **addr_parts;
     gchar     *name;
     if_info_t *if_info;
@@ -79,25 +118,26 @@ capture_interface_list(int *err, char **err_str)
     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ...");
 
     /* Try to get our interface list */
-    ret = sync_interface_list_open(&msg);
+    ret = sync_interface_list_open(&data, &primary_msg, &secondary_msg);
     if (ret != 0) {
         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!");
         if (err_str) {
-            *err_str = msg;
+            *err_str = primary_msg;
         } else {
-            g_free(msg);
+            g_free(primary_msg);
         }
-        *err = CANT_RUN_DUMPCAP;
+        g_free(secondary_msg);
+        *err = CANT_GET_INTERFACE_LIST;
         return NULL;
     }
 
     /* Split our lines */
 #ifdef _WIN32
-    raw_list = g_strsplit(msg, "\r\n", 0);
+    raw_list = g_strsplit(data, "\r\n", 0);
 #else
-    raw_list = g_strsplit(msg, "\n", 0);
+    raw_list = g_strsplit(data, "\n", 0);
 #endif
-    g_free(msg);
+    g_free(data);
 
     for (i = 0; raw_list[i] != NULL; i++) {
         if_parts = g_strsplit(raw_list[i], "\t", 4);
@@ -150,43 +190,90 @@ capture_interface_list(int *err, char **err_str)
         if (err_str)
             *err_str = g_strdup("No interfaces found");
     }
+#ifdef HAVE_PCAP_REMOTE
+    if (remote_interface_list && g_list_length(remote_interface_list) > 0) {
+        append_remote_list(if_list);
+    }
+#endif
     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(const gchar *ifname, char **err_str)
+if_capabilities_t *
+capture_get_if_capabilities(const gchar *ifname, gboolean monitor_mode,
+                            char **err_str)
 {
-    GList     *linktype_list = NULL;
-    int        err, i;
-    gchar     *msg;
-    gchar    **raw_list, **lt_parts;
-    data_link_info_t *data_link_info;
+    if_capabilities_t *caps;
+    GList              *linktype_list = NULL;
+    int                 err, i;
+    gchar              *data, *primary_msg, *secondary_msg;
+    gchar             **raw_list, **lt_parts;
+    data_link_info_t   *data_link_info;
 
-    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Linktype List ...");
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities ...");
 
     /* Try to get our interface list */
-    err = sync_linktype_list_open(ifname, &msg);
+    err = sync_if_capabilities_open(ifname, monitor_mode, &data,
+                                    &primary_msg, &secondary_msg);
     if (err != 0) {
-        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Linktype List failed!");
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities failed!");
         if (err_str) {
-            *err_str = msg;
+            *err_str = primary_msg;
         } else {
-            g_free(msg);
+            g_free(primary_msg);
         }
+        g_free(secondary_msg);
         return NULL;
     }
 
     /* Split our lines */
 #ifdef _WIN32
-    raw_list = g_strsplit(msg, "\r\n", 0);
+    raw_list = g_strsplit(data, "\r\n", 0);
 #else
-    raw_list = g_strsplit(msg, "\n", 0);
+    raw_list = g_strsplit(data, "\n", 0);
 #endif
-    g_free(msg);
+    g_free(data);
 
-    for (i = 0; raw_list[i] != NULL; i++) {
+    /*
+     * First line is 0 if monitor mode isn't supported, 1 if it is.
+     */
+    if (raw_list[0] == NULL || *raw_list[0] == '\0') {
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities returned no information!");
+        if (err_str) {
+            *err_str = g_strdup("Dumpcap returned no interface capability information");
+        }
+        return NULL;
+    }
+
+    /*
+     * Allocate the interface capabilities structure.
+     */
+    caps = g_malloc(sizeof *caps);
+    switch (*raw_list[0]) {
+
+    case '0':
+        caps->can_set_rfmon = FALSE;
+        break;
+
+    case '1':
+        caps->can_set_rfmon = TRUE;
+        break;
+
+    default:
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface Capabilities returned bad information!");
+        if (err_str) {
+            *err_str = g_strdup_printf("Dumpcap returned \"%s\" for monitor-mode capability",
+                                       raw_list[0]);
+        }
+        g_free(caps);
+        return NULL;
+    }
+
+    /*
+     * The rest are link-layer types.
+     */
+    for (i = 1; 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) {
@@ -208,10 +295,45 @@ capture_pcap_linktype_list(const gchar *ifname, char **err_str)
 
     /* Check to see if we built a list */
     if (linktype_list == NULL) {
+        /* No. */
         if (err_str)
-            *err_str = NULL;
+            *err_str = g_strdup("Dumpcap returned no link-layer types");
+        g_free(caps);
+        return NULL;
     }
-    return linktype_list;
+    caps->data_link_types = linktype_list;
+    return caps;
 }
 
+#ifdef HAVE_PCAP_REMOTE
+void add_interface_to_remote_list(if_info_t *if_info)
+{
+    GSList *list;
+    if_addr_t *if_addr, *temp_addr;
+
+    if_info_t *temp = g_malloc0(sizeof(if_info_t));
+    temp->name = g_strdup(if_info->name);
+    temp->description = g_strdup(if_info->description);
+    for (list = g_slist_nth(if_info->addrs, 0); list != NULL; list = g_slist_next(list)) {
+        temp_addr = g_malloc0(sizeof(if_addr_t));
+        if_addr = (if_addr_t *)list->data;
+        if (if_addr) {
+            temp_addr->ifat_type = if_addr->ifat_type;
+            if (temp_addr->ifat_type == IF_AT_IPv4) {
+                temp_addr->addr.ip4_addr = if_addr->addr.ip4_addr;
+            } else {
+                memcpy(temp_addr->addr.ip6_addr, if_addr->addr.ip6_addr, sizeof(if_addr->addr));
+            }
+        } else {
+            g_free(temp_addr);
+            temp_addr = NULL;
+        }
+        if (temp_addr) {
+            temp->addrs = g_slist_append(temp->addrs, temp_addr);
+        }
+    }
+    temp->loopback = if_info->loopback;
+    remote_interface_list = g_list_append(remote_interface_list, temp);
+}
+#endif
 #endif /* HAVE_LIBPCAP */