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.
def extcap_interfaces():
+ print ("extcap {version=1.0}")
print ("interface {value=example1}{display=Example interface usage for extcap}")
def extcap_dlts(interface):
*/
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);
return (gchar *)NULL;
}
-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)
{
}
}
+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_) {
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) );
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);
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;
/* 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);
sl = g_list_first((GList *)elem->data);
g_list_foreach(sl, (GFunc)g_free, NULL);
g_list_free(sl);
- }
+ }
}
g_list_free(list);
}
#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 */
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 *
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 );
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;
}
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);
}
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;
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) {
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);
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)
*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;
}
EXTCAP_SENTENCE_UNKNOWN,
EXTCAP_SENTENCE_ARG,
EXTCAP_SENTENCE_VALUE,
- EXTCAP_SENTENCE_FLAG,
+ EXTCAP_SENTENCE_EXTCAP,
EXTCAP_SENTENCE_INTERFACE,
EXTCAP_SENTENCE_DLT
} extcap_sentence_type;
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
typedef struct _extcap_interface {
gchar *call;
gchar *display;
+ gchar *version;
+ extcap_sentence_type if_type;
struct _extcap_interface *next_interface;
} extcap_interface;
#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>
.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;
}