aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/README.extcap6
-rwxr-xr-xdoc/extcap_example.py1
-rw-r--r--extcap.c100
-rw-r--r--extcap.h10
-rw-r--r--extcap_parser.c60
-rw-r--r--extcap_parser.h7
-rw-r--r--ui/qt/about_dialog.cpp26
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):
diff --git a/extcap.c b/extcap.c
index 6bb079ae1e..2d0d85fefb 100644
--- a/extcap.c
+++ b/extcap.c
@@ -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);
}
diff --git a/extcap.h b/extcap.h
index fa334c59c6..74fc0b3b6d 100644
--- a/extcap.h
+++ b/extcap.h
@@ -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;
}