diff options
-rw-r--r-- | doc/README.extcap | 6 | ||||
-rwxr-xr-x | doc/extcap_example.py | 1 | ||||
-rw-r--r-- | extcap.c | 100 | ||||
-rw-r--r-- | extcap.h | 10 | ||||
-rw-r--r-- | extcap_parser.c | 60 | ||||
-rw-r--r-- | extcap_parser.h | 7 | ||||
-rw-r--r-- | ui/qt/about_dialog.cpp | 26 |
7 files changed, 155 insertions, 55 deletions
diff --git a/doc/README.extcap b/doc/README.extcap index cb32683eed..50dc1a82f3 100644 --- a/doc/README.extcap +++ b/doc/README.extcap @@ -44,13 +44,17 @@ in the doc/extcap.4 generated man page (in the build dir). Example: $ extcapbin --extcap-interfaces +extcap {version=1.0} interface {value=example1}{display=Example interface 1 for extcap} interface {value=example2}{display=Example interface 2 for extcap} +The version for the extcap sentence (which may exist as often as wanted, but only the +last one will be used) will be used for displaying the version information of the extcap +interface in the about dialog of Wireshark (Qt only). + The value for each interface will be used in subsequent calls as the interface name IFACE. - STEP2: the extcap is queried for valid DLTs (Data Link Types) for all the interfaces returned by the step 1. diff --git a/doc/extcap_example.py b/doc/extcap_example.py index 13c079d0ec..39bb571075 100755 --- a/doc/extcap_example.py +++ b/doc/extcap_example.py @@ -90,6 +90,7 @@ def extcap_config(interface): def extcap_interfaces(): + print ("extcap {version=1.0}") print ("interface {value=example1}{display=Example interface usage for extcap}") def extcap_dlts(interface): @@ -62,6 +62,12 @@ static HANDLE pipe_h = NULL; */ static GHashTable *ifaces = NULL; +/* internal container, for all the extcap executables that have been found. + * will be resetted by every call to extcap_interface_list() and is being + * used for printing information about all extcap interfaces found + */ +static GHashTable *tools = NULL; + /* Callback definition for extcap_foreach */ typedef gboolean (*extcap_cb_t)(const gchar *extcap, gchar *output, void *data, gchar **err_str); @@ -117,15 +123,6 @@ extcap_if_executable(const char *ifname) } static void -extcap_if_reset(void) -{ - if (ifaces == NULL) - ifaces = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - - g_hash_table_remove_all(ifaces); -} - -static void extcap_if_add(gchar *ifname, gchar *extcap) { if ( g_hash_table_lookup(ifaces, ifname) == NULL ) @@ -136,6 +133,32 @@ extcap_if_add(gchar *ifname, gchar *extcap) } } +static void +extcap_tool_add(gchar *extcap, extcap_interface *tool) +{ + char * toolname = NULL; + extcap_info * extcap_tool = NULL; + + if ( extcap == NULL ) + return; + + toolname = g_path_get_basename(extcap); + extcap_tool = (extcap_info *)g_hash_table_lookup(tools, toolname); + + if ( tools != NULL && extcap_tool == NULL ) { + extcap_info * store = (extcap_info *)g_new0(extcap_info, 1); + store->version = g_strdup ( tool->version ); + store->full_path = extcap; + store->basename = g_strdup ( toolname ); + + g_hash_table_insert(tools, g_strdup(toolname), store); + } else { + g_free(extcap); + } + + g_free(toolname); +} + /* Note: args does not need to be NULL-terminated. */ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb, void *cb_data, char **err_str, const char * ifname _U_) { @@ -317,7 +340,7 @@ static gboolean interfaces_cb(const gchar *extcap, gchar *output, void *data, int_iter = interfaces; while (int_iter != NULL ) { - if ( extcap_if_exists(int_iter->call) ) + if ( int_iter->if_type == EXTCAP_SENTENCE_INTERFACE && extcap_if_exists(int_iter->call) ) { g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "Extcap interface \"%s\" is already provided by \"%s\" ", int_iter->call, (gchar *)extcap_if_executable(int_iter->call) ); @@ -325,19 +348,29 @@ static gboolean interfaces_cb(const gchar *extcap, gchar *output, void *data, continue; } - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " Interface [%s] \"%s\" ", - int_iter->call, int_iter->display); + if ( int_iter->if_type == EXTCAP_SENTENCE_INTERFACE ) + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " Interface [%s] \"%s\" ", + int_iter->call, int_iter->display); + else if ( int_iter->if_type == EXTCAP_SENTENCE_EXTCAP ) + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " Extcap [%s] ", int_iter->call); + + if ( int_iter->if_type == EXTCAP_SENTENCE_INTERFACE ) { + if_info = g_new0(if_info_t, 1); + if_info->name = g_strdup(int_iter->call); + if_info->friendly_name = g_strdup(int_iter->display); + + if_info->type = IF_EXTCAP; - if_info = g_new0(if_info_t, 1); - if_info->name = g_strdup(int_iter->call); - if_info->friendly_name = g_strdup(int_iter->display); + if_info->extcap = g_strdup(extcap); + *il = g_list_append(*il, if_info); - if_info->type = IF_EXTCAP; + extcap_if_add(g_strdup(int_iter->call), g_strdup(extcap) ); + } - if_info->extcap = g_strdup(extcap); - *il = g_list_append(*il, if_info); + /* Call for interfaces and tools alike. Multiple calls (because a tool has multiple + * interfaces) are handled internally */ + extcap_tool_add(g_strdup(extcap), int_iter); - extcap_if_add(g_strdup(int_iter->call), g_strdup(extcap) ); int_iter = int_iter->next_interface; } extcap_free_interface(interfaces); @@ -358,6 +391,23 @@ if_info_compare(gconstpointer a, gconstpointer b) return comp; } +GHashTable * +extcap_tools_list(void) { + if ( tools == NULL || g_hash_table_size(tools) == 0 ) + extcap_interface_list(NULL); + + return tools; +} + +static void +extcap_free_info (gpointer data) { + extcap_info * info = (extcap_info *)data; + + g_free (info->basename); + g_free (info->full_path); + g_free (info->version); +} + GList * extcap_interface_list(char **err_str) { gchar *argv; @@ -369,7 +419,15 @@ extcap_interface_list(char **err_str) { /* ifaces is used as cache, do not destroy its contents when * returning or no extcap interfaces can be queried for options */ - extcap_if_reset(); + if (ifaces == NULL) + ifaces = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + else + g_hash_table_remove_all(ifaces); + + if (tools == NULL) + tools = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, extcap_free_info); + else + g_hash_table_remove_all(tools); argv = g_strdup(EXTCAP_ARGUMENT_LIST_INTERFACES); @@ -393,7 +451,7 @@ static void extcap_free_if_configuration(GList *list) sl = g_list_first((GList *)elem->data); g_list_foreach(sl, (GFunc)g_free, NULL); g_list_free(sl); - } + } } g_list_free(list); } @@ -49,6 +49,12 @@ #define EXTCAP_ARGUMENT_CAPTURE_FILTER "--extcap-capture-filter" #define EXTCAP_ARGUMENT_RUN_PIPE "--fifo" +typedef struct _extcap_info { + gchar * basename; + gchar * full_path; + gchar * version; +} extcap_info; + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -61,6 +67,10 @@ extcap_get_if_dlts(const gchar * ifname, char ** err_str); GList * extcap_interface_list(char **err_str); +/* get a list of all available extcap tools */ +GHashTable * +extcap_tools_list(void); + /* returns the configuration for the given interface name, or an * empty list, if no configuration has been found */ GList * diff --git a/extcap_parser.c b/extcap_parser.c index ac75b50ab3..000dd6307c 100644 --- a/extcap_parser.c +++ b/extcap_parser.c @@ -282,7 +282,7 @@ extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) { rs->param_list = NULL; /* Regex for catching just the allowed values for sentences */ - if ( ( regex = g_regex_new ( "^[\\t| ]*(arg|value|interface|dlt)(?=[\\t| ]+\\{)", + if ( ( regex = g_regex_new ( "^[\\t| ]*(arg|value|interface|extcap|dlt)(?=[\\t| ]+\\{)", (GRegexCompileFlags) G_REGEX_CASELESS, (GRegexMatchFlags) 0, NULL ) ) != NULL ) { g_regex_match ( regex, s, (GRegexMatchFlags) 0, &match_info ); @@ -347,6 +347,8 @@ extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) { tv->param_type = EXTCAP_PARAM_REQUIRED; } else if (g_ascii_strcasecmp(tv->arg, "validation") == 0) { tv->param_type = EXTCAP_PARAM_VALIDATION; + } else if (g_ascii_strcasecmp(tv->arg, "version") == 0) { + tv->param_type = EXTCAP_PARAM_VERSION; } else { tv->param_type = EXTCAP_PARAM_UNKNOWN; } @@ -408,11 +410,8 @@ void extcap_free_value(extcap_value *v) { if (v == NULL) return; - if (v->call != NULL) - g_free(v->call); - - if (v->display != NULL) - g_free(v->display); + g_free(v->call); + g_free(v->display); g_free(v); } @@ -420,7 +419,8 @@ void extcap_free_value(extcap_value *v) { extcap_interface *extcap_new_interface(void) { extcap_interface *r = g_new(extcap_interface, 1); - r->call = r->display = NULL; + r->call = r->display = r->version = NULL; + r->if_type = EXTCAP_SENTENCE_UNKNOWN; r->next_interface = NULL; return r; @@ -456,11 +456,8 @@ void extcap_free_dlt(extcap_dlt *d) { if (d == NULL) return; - if (d->name != NULL) - g_free(d->name); - - if (d->display != NULL) - g_free(d->display); + g_free(d->name); + g_free(d->display); } extcap_arg *extcap_new_arg(void) { @@ -493,20 +490,11 @@ void extcap_free_arg(extcap_arg *a) { if (a == NULL) return; - if (a->call != NULL) - g_free(a->call); - - if (a->display != NULL) - g_free(a->display); - - if (a->tooltip != NULL) - g_free(a->tooltip); - - if (a->fileextension != NULL) - g_free(a->fileextension); - - if (a->regexp != NULL) - g_free(a->regexp); + g_free(a->call); + g_free(a->display); + g_free(a->tooltip); + g_free(a->fileextension); + g_free(a->regexp); if (a->range_start != NULL) extcap_free_complex(a->range_start); @@ -780,7 +768,8 @@ int extcap_parse_interface_sentence(extcap_token_sentence *s, if (g_ascii_strcasecmp(s->sentence, "interface") == 0) { sent = EXTCAP_SENTENCE_INTERFACE; - /* printf("INTERFACE sentence\n"); */ + } else if (g_ascii_strcasecmp(s->sentence, "extcap") == 0) { + sent = EXTCAP_SENTENCE_EXTCAP; } if (sent == EXTCAP_SENTENCE_UNKNOWN) @@ -788,21 +777,30 @@ int extcap_parse_interface_sentence(extcap_token_sentence *s, *ri = extcap_new_interface(); + (*ri)->if_type = sent; + if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_VALUE)) - == NULL) { + == NULL && sent == EXTCAP_SENTENCE_INTERFACE) { printf("No value in INTERFACE sentence\n"); extcap_free_interface(*ri); return -1; } - (*ri)->call = g_strdup(v->value); + if ( v != NULL ) + (*ri)->call = g_strdup(v->value); if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DISPLAY)) - == NULL) { + == NULL && sent == EXTCAP_SENTENCE_INTERFACE) { printf("No display in INTERFACE sentence\n"); extcap_free_interface(*ri); return -1; } - (*ri)->display = g_strdup(v->value); + if ( v != NULL ) + (*ri)->display = g_strdup(v->value); + + if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_VERSION)) + != NULL) { + (*ri)->version = g_strdup(v->value); + } return 1; } diff --git a/extcap_parser.h b/extcap_parser.h index 158838c16f..d10c5cd8cc 100644 --- a/extcap_parser.h +++ b/extcap_parser.h @@ -30,7 +30,7 @@ typedef enum { EXTCAP_SENTENCE_UNKNOWN, EXTCAP_SENTENCE_ARG, EXTCAP_SENTENCE_VALUE, - EXTCAP_SENTENCE_FLAG, + EXTCAP_SENTENCE_EXTCAP, EXTCAP_SENTENCE_INTERFACE, EXTCAP_SENTENCE_DLT } extcap_sentence_type; @@ -70,7 +70,8 @@ typedef enum { EXTCAP_PARAM_FILE_EXTENSION, EXTCAP_PARAM_PARENT, EXTCAP_PARAM_REQUIRED, - EXTCAP_PARAM_VALIDATION + EXTCAP_PARAM_VALIDATION, + EXTCAP_PARAM_VERSION } extcap_param_type; /* Values for a given sentence; values are all stored as a call @@ -132,7 +133,9 @@ typedef struct _extcap_if { typedef struct _extcap_interface { gchar *call; gchar *display; + gchar *version; + extcap_sentence_type if_type; struct _extcap_interface *next_interface; } extcap_interface; diff --git a/ui/qt/about_dialog.cpp b/ui/qt/about_dialog.cpp index c0899a0723..83bbdf8004 100644 --- a/ui/qt/about_dialog.cpp +++ b/ui/qt/about_dialog.cpp @@ -53,6 +53,10 @@ #include "wsutil/copyright_info.h" #include "wsutil/ws_version_info.h" +#ifdef HAVE_EXTCAP +#include "extcap.h" +#endif + #include "qt_ui_utils.h" #include <QFontMetrics> @@ -114,6 +118,28 @@ const QString AboutDialog::plugins_scan() .arg(plugin_row[2]) // Type .arg(short_file); } + + GHashTable * tools = extcap_tools_list(); + if ( tools != NULL && g_hash_table_size(tools) > 0 ) + { + QString short_file; + GList * walker = g_list_first(g_hash_table_get_keys(tools)); + while ( walker ) + { + extcap_info * tool = (extcap_info *)g_hash_table_lookup(tools, walker->data); + if ( tool != NULL ) + { + short_file = fontMetrics().elidedText(tool->full_path, Qt::ElideMiddle, one_em*22); + plugin_table += QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td></tr>\n") + .arg(tool->basename) // Name + .arg(tool->version) // Version + .arg("extcap") // Type + .arg(short_file); + } + walker = g_list_next(walker); + } + } + return plugin_table; } |