extcap: Lazily load our interface list.
Add extcap_ensure_all_interfaces_loaded, which calls extcap_load_interface_list if our interface list is empty. Call it in each of our public functions that require a valid interface list. Clean up the extcap API documentation and note which routines initialize the interface list. In tshark, don't unconditionally call extcap_register_preferences and instead rely on lazy loading. Change-Id: I8493ae5f4d703b0fd767246557d17723bcf207c6 Ping-Bug: 15295 Reviewed-on: https://code.wireshark.org/review/37750 Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
45378647d7
commit
9c53ac0187
63
extcap.c
63
extcap.c
|
@ -73,7 +73,7 @@ static GHashTable *_toolbars = NULL;
|
|||
* values. These ensure that preferences can survive extcap if garbage
|
||||
* collection, and does not lead to dangling pointers in the prefs subsystem.
|
||||
*/
|
||||
static GHashTable *extcap_prefs_dynamic_vals = NULL;
|
||||
static GHashTable *_extcap_prefs_dynamic_vals = NULL;
|
||||
|
||||
typedef struct _extcap_callback_info_t
|
||||
{
|
||||
|
@ -127,6 +127,12 @@ typedef struct extcap_run_extcaps_info {
|
|||
|
||||
static void extcap_load_interface_list(void);
|
||||
|
||||
/* Used for lazily loading our interfaces. */
|
||||
static void extcap_ensure_all_interfaces_loaded(void) {
|
||||
if ( !_loaded_interfaces || g_hash_table_size(_loaded_interfaces) == 0 )
|
||||
extcap_load_interface_list();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
thread_pool_push(thread_pool_t *pool, gpointer data, GError **error)
|
||||
{
|
||||
|
@ -152,8 +158,7 @@ extcap_loaded_interfaces(void)
|
|||
if (prefs.capture_no_extcap)
|
||||
return NULL;
|
||||
|
||||
if ( !_loaded_interfaces || g_hash_table_size(_loaded_interfaces) == 0 )
|
||||
extcap_load_interface_list();
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
return _loaded_interfaces;
|
||||
}
|
||||
|
@ -179,6 +184,8 @@ compare_tools(gconstpointer a, gconstpointer b)
|
|||
void
|
||||
extcap_get_descriptions(plugin_description_callback callback, void *callback_data)
|
||||
{
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
GHashTable * tools = extcap_loaded_interfaces();
|
||||
GPtrArray *tools_array = g_ptr_array_new();
|
||||
|
||||
|
@ -594,6 +601,9 @@ extcap_get_if_dlts(const gchar *ifname, char **err_str)
|
|||
*err_str = NULL;
|
||||
}
|
||||
|
||||
/* Update the extcap interfaces and get a list of their if_infos */
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
extcap_interface *interface = extcap_find_interface_for_ifname(ifname);
|
||||
if (interface)
|
||||
{
|
||||
|
@ -655,6 +665,8 @@ if_info_compare(gconstpointer a, gconstpointer b)
|
|||
gchar *
|
||||
extcap_get_help_for_ifname(const char *ifname)
|
||||
{
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
extcap_interface *interface = extcap_find_interface_for_ifname(ifname);
|
||||
return interface != NULL ? interface->help : NULL;
|
||||
}
|
||||
|
@ -670,8 +682,7 @@ append_extcap_interface_list(GList *list, char **err_str _U_)
|
|||
return list;
|
||||
|
||||
/* Update the extcap interfaces and get a list of their if_infos */
|
||||
if ( !_loaded_interfaces || g_hash_table_size(_loaded_interfaces) == 0 )
|
||||
extcap_load_interface_list();
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
ifutilkeys_head = g_hash_table_get_keys(_loaded_interfaces);
|
||||
ifutilkeys = ifutilkeys_head;
|
||||
|
@ -727,7 +738,7 @@ void extcap_register_preferences(void)
|
|||
}
|
||||
|
||||
// Will load information about extcaps and their supported config.
|
||||
extcap_load_interface_list();
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -736,8 +747,8 @@ void extcap_register_preferences(void)
|
|||
*/
|
||||
void extcap_cleanup(void)
|
||||
{
|
||||
if (extcap_prefs_dynamic_vals)
|
||||
g_hash_table_destroy(extcap_prefs_dynamic_vals);
|
||||
if (_extcap_prefs_dynamic_vals)
|
||||
g_hash_table_destroy(_extcap_prefs_dynamic_vals);
|
||||
|
||||
if (_loaded_interfaces)
|
||||
g_hash_table_destroy(_loaded_interfaces);
|
||||
|
@ -759,19 +770,19 @@ void extcap_cleanup(void)
|
|||
static gchar **extcap_prefs_dynamic_valptr(const char *name, char **pref_name)
|
||||
{
|
||||
gchar **valp;
|
||||
if (!extcap_prefs_dynamic_vals)
|
||||
if (!_extcap_prefs_dynamic_vals)
|
||||
{
|
||||
/* Initialize table only as needed, most preferences are not dynamic */
|
||||
extcap_prefs_dynamic_vals = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
_extcap_prefs_dynamic_vals = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
g_free, g_free);
|
||||
}
|
||||
if (!g_hash_table_lookup_extended(extcap_prefs_dynamic_vals, name,
|
||||
if (!g_hash_table_lookup_extended(_extcap_prefs_dynamic_vals, name,
|
||||
(gpointer *)pref_name, (gpointer *)&valp))
|
||||
{
|
||||
/* New dynamic pref, allocate, initialize and store. */
|
||||
valp = g_new0(gchar *, 1);
|
||||
*pref_name = g_strdup(name);
|
||||
g_hash_table_insert(extcap_prefs_dynamic_vals, *pref_name, valp);
|
||||
g_hash_table_insert(_extcap_prefs_dynamic_vals, *pref_name, valp);
|
||||
}
|
||||
return valp;
|
||||
}
|
||||
|
@ -803,6 +814,8 @@ extcap_pref_for_argument(const gchar *ifname, struct _extcap_arg *arg)
|
|||
{
|
||||
struct preference *pref = NULL;
|
||||
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
GRegex *regex_name = g_regex_new("[-]+", G_REGEX_RAW, (GRegexMatchFlags) 0, NULL);
|
||||
GRegex *regex_ifname = g_regex_new("(?![a-zA-Z0-9_]).", G_REGEX_RAW, (GRegexMatchFlags) 0, NULL);
|
||||
if (regex_name && regex_ifname)
|
||||
|
@ -886,7 +899,7 @@ static gboolean cb_preference(extcap_callback_info_t cb_info)
|
|||
/* Been here before, restore stored value */
|
||||
if (arg->pref_valptr == NULL)
|
||||
{
|
||||
arg->pref_valptr = (gchar**)g_hash_table_lookup(extcap_prefs_dynamic_vals, pref_ifname);
|
||||
arg->pref_valptr = (gchar**)g_hash_table_lookup(_extcap_prefs_dynamic_vals, pref_ifname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -921,6 +934,8 @@ extcap_get_if_configuration(const char *ifname)
|
|||
GList * arguments = NULL;
|
||||
GList *ret = NULL;
|
||||
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
extcap_interface *interface = extcap_find_interface_for_ifname(ifname);
|
||||
if (interface)
|
||||
{
|
||||
|
@ -965,6 +980,8 @@ extcap_get_if_configuration_values(const char * ifname, const char * argname, GH
|
|||
GList * args = NULL;
|
||||
GList *ret = NULL;
|
||||
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
extcap_interface *interface = extcap_find_interface_for_ifname(ifname);
|
||||
if (interface)
|
||||
{
|
||||
|
@ -999,21 +1016,15 @@ extcap_get_if_configuration_values(const char * ifname, const char * argname, GH
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* If is_required is FALSE: returns TRUE if the extcap interface has
|
||||
* configurable options.
|
||||
* If is_required is TRUE: returns TRUE when the extcap interface has
|
||||
* configurable options that required modification. (For example, when an
|
||||
* argument is required but empty.)
|
||||
*/
|
||||
gboolean
|
||||
extcap_has_configuration(const char *ifname, gboolean is_required)
|
||||
{
|
||||
GList *arguments = 0;
|
||||
GList *walker = 0, * item = 0;
|
||||
|
||||
gboolean found = FALSE;
|
||||
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
arguments = extcap_get_if_configuration(ifname);
|
||||
walker = g_list_first(arguments);
|
||||
|
||||
|
@ -1106,6 +1117,8 @@ extcap_verify_capture_filter(const char *ifname, const char *filter, gchar **err
|
|||
GList * arguments = NULL;
|
||||
extcap_filter_status status = EXTCAP_FILTER_UNKNOWN;
|
||||
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
extcap_interface *interface = extcap_find_interface_for_ifname(ifname);
|
||||
if (interface)
|
||||
{
|
||||
|
@ -1132,6 +1145,8 @@ extcap_has_toolbar(const char *ifname)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
GList *toolbar_list = g_hash_table_get_values (_toolbars);
|
||||
for (GList *walker = toolbar_list; walker; walker = walker->next)
|
||||
{
|
||||
|
@ -1586,6 +1601,8 @@ extcap_init_interfaces(capture_options *capture_opts)
|
|||
interface_options *interface_opts;
|
||||
ws_pipe_t *pipedata;
|
||||
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
for (i = 0; i < capture_opts->ifaces->len; i++)
|
||||
{
|
||||
GPtrArray *args = NULL;
|
||||
|
@ -1730,6 +1747,8 @@ extcap_ensure_interface(const gchar * toolname, gboolean create_if_nonexist)
|
|||
extcap_info *
|
||||
extcap_get_tool_by_ifname(const gchar *ifname)
|
||||
{
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
if ( ifname && _tool_for_ifname )
|
||||
{
|
||||
gchar * toolname = (gchar *)g_hash_table_lookup(_tool_for_ifname, ifname);
|
||||
|
@ -1743,6 +1762,8 @@ extcap_get_tool_by_ifname(const gchar *ifname)
|
|||
extcap_info *
|
||||
extcap_get_tool_info(const gchar * toolname)
|
||||
{
|
||||
extcap_ensure_all_interfaces_loaded();
|
||||
|
||||
return extcap_ensure_interface(toolname, FALSE);
|
||||
}
|
||||
|
||||
|
|
116
extcap.h
116
extcap.h
|
@ -67,57 +67,104 @@ struct _extcap_arg;
|
|||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Registers preferences for all interfaces */
|
||||
/**
|
||||
* Registers preferences for all interfaces.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
*/
|
||||
void
|
||||
extcap_register_preferences(void);
|
||||
|
||||
/* try to get if capabilities from extcap */
|
||||
/**
|
||||
* Fetches the interface capabilities for the named extcap interface.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname The interface name.
|
||||
* @param err_str Set to NULL on success, error description on failure.
|
||||
* @return The interface capabilities on success, NULL on failure.
|
||||
*/
|
||||
if_capabilities_t *
|
||||
extcap_get_if_dlts(const gchar * ifname, char ** err_str);
|
||||
|
||||
/* append a list of all extcap capture interfaces to the specified list */
|
||||
/**
|
||||
* Append a list of all extcap capture interfaces to the specified list.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param list An existing GList of if_info_t.
|
||||
* @param err_str Set to NULL on success, error description on failure.
|
||||
* @return An updated list on success, an unchanged list on failure.
|
||||
*/
|
||||
GList *
|
||||
append_extcap_interface_list(GList *list, char **err_str);
|
||||
|
||||
/**
|
||||
* Retrieves information about an extcap executable.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param toolname The extcap name.
|
||||
* @return The extcap information on success, NULL on failure.
|
||||
*/
|
||||
extcap_info *
|
||||
extcap_get_tool_info(const gchar * toolname);
|
||||
|
||||
/**
|
||||
* Retrieves information about an extcap interface.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname The extcap interface name.
|
||||
* @return The extcap information on success, NULL on failure.
|
||||
*/
|
||||
extcap_info *
|
||||
extcap_get_tool_by_ifname(const gchar *ifname);
|
||||
|
||||
/* return the help page or NULL for the given ifname */
|
||||
/**
|
||||
* Retrieves help information for an extcap interface.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname The extcap interface name.
|
||||
* @return A help string on success or NULL on failure.
|
||||
*/
|
||||
gchar *
|
||||
extcap_get_help_for_ifname(const char *ifname);
|
||||
|
||||
/* remove all loaded interfaces */
|
||||
/**
|
||||
* Remove all loaded extcap interfaces.
|
||||
*/
|
||||
void
|
||||
extcap_clear_interfaces(void);
|
||||
|
||||
/* get information about all available extcap executables */
|
||||
/**
|
||||
* Retrieves information about all available extcap executables.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param callback The description callback routine.
|
||||
* @param callback_data Data to be passed to the callback routine.
|
||||
*/
|
||||
void
|
||||
extcap_get_descriptions(plugin_description_callback callback, void *callback_data);
|
||||
|
||||
/* print information about all available extcap executables */
|
||||
/**
|
||||
* Print information about all available extcap executables.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
*/
|
||||
void
|
||||
extcap_dump_all(void);
|
||||
|
||||
/* returns the configuration for the given interface name, or an
|
||||
* empty list, if no configuration has been found
|
||||
* @param ifname the interface name
|
||||
/**
|
||||
* Returns the configuration for the given interface name, or an
|
||||
* empty list, if no configuration has been found.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname The interface name.
|
||||
*/
|
||||
GList *
|
||||
extcap_get_if_configuration(const char * ifname);
|
||||
|
||||
/* returns the configuration values for the given argument, or an
|
||||
* empty list, if no values could been found
|
||||
* @param ifname the interface name
|
||||
* @param argname the name of the argument, for which the values should be retrieved
|
||||
/**
|
||||
* Returns the configuration values for the given argument, or an
|
||||
* empty list, if no values could been found.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname The interface name.
|
||||
* @param argname The name of the argument for which the values should be retrieved.
|
||||
*/
|
||||
GList *
|
||||
extcap_get_if_configuration_values(const char * ifname, const char * argname, GHashTable * arguments);
|
||||
|
||||
/**
|
||||
* Check if the capture filter for the given interface name is valid.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname Interface to check
|
||||
* @param filter Capture filter to check
|
||||
* @param err_str Error string returned if filter is invalid
|
||||
|
@ -135,23 +182,60 @@ extcap_verify_capture_filter(const char *ifname, const char *filter, gchar **err
|
|||
void
|
||||
extcap_free_if_configuration(GList *list, gboolean free_args);
|
||||
|
||||
/**
|
||||
* Checks to see if an interface has configurable options.
|
||||
* If is_required is FALSE: returns TRUE if the extcap interface has
|
||||
* configurable options.
|
||||
* If is_required is TRUE: returns TRUE when the extcap interface has
|
||||
* configurable options that required modification. (For example, when an
|
||||
* argument is required but empty.)
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname Interface to check.
|
||||
* @param is_required Required configuration flag.
|
||||
* @return
|
||||
*/
|
||||
gboolean
|
||||
extcap_has_configuration(const char * ifname, gboolean is_required);
|
||||
|
||||
/**
|
||||
* Checks to see if the interface has an associated toolbar.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname Interface to check.
|
||||
* @return TRUE if the interface has a toolbar, FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
extcap_has_toolbar(const char *ifname);
|
||||
|
||||
/**
|
||||
* Initializes each extcap interface with the supplied capture options.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param capture_opts Capture options.
|
||||
* @return TRUE on success, FALSE on failure.
|
||||
*/
|
||||
gboolean
|
||||
extcap_init_interfaces(capture_options * capture_opts);
|
||||
|
||||
/* Clean up all if related stuff */
|
||||
/**
|
||||
* Clean up all if related stuff.
|
||||
* @param capture_opts Capture options.
|
||||
* @param errormsg Set to NULL on success, error description on failure.
|
||||
*/
|
||||
void
|
||||
extcap_if_cleanup(capture_options * capture_opts, gchar ** errormsg);
|
||||
|
||||
/**
|
||||
* Fetch an extcap preference for a given argument.
|
||||
* Initializes the extcap interface list if that hasn't already been done.
|
||||
* @param ifname The interface to check.
|
||||
* @param arg The command line argument to check.
|
||||
* @return The associated preference on success, NULL on failure.
|
||||
*/
|
||||
struct preference *
|
||||
extcap_pref_for_argument(const gchar *ifname, struct _extcap_arg * arg);
|
||||
|
||||
/* Clean up global extcap stuff on program exit */
|
||||
/**
|
||||
* Clean up global extcap stuff on program exit.
|
||||
*/
|
||||
void extcap_cleanup(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
2
tshark.c
2
tshark.c
|
@ -940,7 +940,6 @@ main(int argc, char *argv[])
|
|||
#ifdef HAVE_PLUGINS
|
||||
register_all_plugin_tap_listeners();
|
||||
#endif
|
||||
extcap_register_preferences();
|
||||
/* Register all tap listeners. */
|
||||
for (tap_reg_t *t = tap_reg_listener; t->cb_func != NULL; t++) {
|
||||
t->cb_func();
|
||||
|
@ -968,6 +967,7 @@ main(int argc, char *argv[])
|
|||
if (strcmp(argv[2], "column-formats") == 0)
|
||||
column_dump_column_formats();
|
||||
else if (strcmp(argv[2], "currentprefs") == 0) {
|
||||
extcap_register_preferences();
|
||||
epan_load_settings();
|
||||
write_prefs(NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue