extcap: Minor improvements
authorRoland Knall <rknall@gmail.com>
Fri, 3 Mar 2017 21:04:18 +0000 (22:04 +0100)
committerRoland Knall <rknall@gmail.com>
Sat, 4 Mar 2017 07:32:25 +0000 (07:32 +0000)
Add method for searching for tools by ifname and minor improvements
in the interface callback to save time and space

Change-Id: I0073c96fbee846cc5ff6304823fa14564ff36c22
Reviewed-on: https://code.wireshark.org/review/20376
Petri-Dish: Roland Knall <rknall@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Roland Knall <rknall@gmail.com>
extcap.c
extcap.h
extcap_parser.c

index 086ab285a50d57b20a0eb6098c83908b7f202037..3d731451232d680845f870f7bd66d265271fa341 100644 (file)
--- a/extcap.c
+++ b/extcap.c
@@ -1338,7 +1338,7 @@ extcap_free_interface_info(gpointer data _U_)
 }
 
 static extcap_info *
-extcap_ensure_interface(const gchar * toolname)
+extcap_ensure_interface(const gchar * toolname, gboolean create_if_nonexist)
 {
     extcap_info * element = 0;
 
@@ -1348,7 +1348,8 @@ extcap_ensure_interface(const gchar * toolname)
     if ( ! _loaded_interfaces )
         _loaded_interfaces = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, extcap_free_interface);
 
-    if ( ( element = (extcap_info *) g_hash_table_lookup(_loaded_interfaces, toolname ) ) == NULL )
+    element = (extcap_info *) g_hash_table_lookup(_loaded_interfaces, toolname );
+    if ( ! element && create_if_nonexist )
     {
         g_hash_table_insert(_loaded_interfaces, g_strdup(toolname), g_new0(extcap_info, 1));
         element = (extcap_info *) g_hash_table_lookup(_loaded_interfaces, toolname );
@@ -1357,6 +1358,25 @@ extcap_ensure_interface(const gchar * toolname)
     return element;
 }
 
+extcap_info *
+extcap_get_tool_by_ifname(const gchar *ifname)
+{
+    if ( ifname && _tool_for_ifname )
+    {
+        gchar * toolname = (gchar *)g_hash_table_lookup(_tool_for_ifname, ifname);
+        if ( toolname )
+            return extcap_ensure_interface(toolname, FALSE);
+    }
+
+    return NULL;
+}
+
+extcap_info *
+extcap_get_tool_info(const gchar * toolname)
+{
+    return extcap_ensure_interface(toolname, FALSE);
+}
+
 static void remove_extcap_entry(gpointer entry, gpointer data _U_)
 {
     extcap_interface *int_iter = (extcap_interface*)entry;
@@ -1367,31 +1387,42 @@ static void remove_extcap_entry(gpointer entry, gpointer data _U_)
 
 static gboolean cb_load_interfaces(extcap_callback_info_t cb_info)
 {
-    GList *interfaces = NULL, *walker = NULL;
-    extcap_interface *int_iter = NULL;
-    gchar *toolname = g_path_get_basename(cb_info.extcap);
+    GList * interfaces = NULL, * walker = NULL;
+    extcap_interface * int_iter = NULL;
+    extcap_info * element = NULL;
+    gchar * toolname = g_path_get_basename(cb_info.extcap);
 
     GList * interface_keys = g_hash_table_get_keys(_loaded_interfaces);
 
+    /* Load interfaces from utility */
     interfaces = extcap_parse_interfaces(cb_info.output);
 
     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Loading interface list for %s ", cb_info.extcap);
 
+    /* Seems, that there where no interfaces to be loaded */
+    if ( ! interfaces || g_list_length(interfaces) == 0 )
+    {
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Cannot load interfaces for %s", cb_info.extcap );
+        /* Some utilities, androiddump for example, may actually don't present any interfaces, even
+         * if the utility itself is present. In such a case, we return here, but do not return
+         * FALSE, or otherwise further loading of other utilities will be stopped */
+        return TRUE;
+    }
+
+    /* Load or create the storage element for the tool */
+    element = extcap_ensure_interface(toolname, TRUE);
+    if ( element == NULL )
+    {
+        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, "Cannot store interface %s, maybe duplicate?", cb_info.extcap );
+        return FALSE;
+    }
+
     walker = interfaces;
     gchar* help = NULL;
     while (walker != NULL)
     {
         int_iter = (extcap_interface *)walker->data;
 
-        extcap_info * element = extcap_ensure_interface(toolname);
-
-        if ( element == NULL )
-        {
-            g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_ERROR, "Cannot store interface %s", cb_info.extcap);
-            walker = g_list_next(walker);
-            continue;
-        }
-
         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Interface found %s\n", int_iter->call);
 
         /* Help is not necessarily stored with the interface, but rather with the version string.
@@ -1406,6 +1437,7 @@ static gboolean cb_load_interfaces(extcap_callback_info_t cb_info)
                 element->version = g_strdup(int_iter->version);
                 element->basename = g_strdup(toolname);
                 element->full_path = g_strdup(cb_info.extcap);
+                element->help = g_strdup(int_iter->help);
             }
 
             help = int_iter->help;
index 9f398d1b5c8d4ab6e26104f02ff93e579f754667..7c7a82baaf14f9298a9c8be5b6db7549cddc5d82 100644 (file)
--- a/extcap.h
+++ b/extcap.h
@@ -55,6 +55,7 @@ typedef struct _extcap_info {
     gchar * basename;
     gchar * full_path;
     gchar * version;
+    gchar * help;
 
     GList * interfaces;
 } extcap_info;
@@ -81,6 +82,12 @@ extcap_get_if_dlts(const gchar * ifname, char ** err_str);
 GList *
 append_extcap_interface_list(GList *list, char **err_str);
 
+extcap_info *
+extcap_get_tool_info(const gchar * toolname);
+
+extcap_info *
+extcap_get_tool_by_ifname(const gchar *ifname);
+
 /* return the help page or NULL for the given ifname */
 gchar *
 extcap_get_help_for_ifname(const char *ifname);
index 3fac966e8a5769ff229dabfd332357ec28d6c325..78c48dd94fb46fee70555e0f47b0dbe522920bb4 100644 (file)
@@ -615,8 +615,15 @@ GList *extcap_parse_interfaces(gchar *output) {
         extcap_interface *ri = NULL;
         extcap_token_sentence *if_sentence = (extcap_token_sentence *) walker->data;
 
-        if (if_sentence != NULL && (ri = extcap_parse_interface_sentence(if_sentence)) != NULL)
-            result = g_list_append(result, ri);
+        if (if_sentence) {
+            if ((g_ascii_strcasecmp(if_sentence->sentence, "interface") == 0) ||
+                (g_ascii_strcasecmp(if_sentence->sentence, "extcap") == 0))
+            {
+                if ((ri = extcap_parse_interface_sentence(if_sentence))) {
+                    result = g_list_append(result, ri);
+                }
+            }
+        }
 
         walker = g_list_next(walker);
     }