#include <unistd.h>
#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
#include <glib.h>
#include <log.h>
typedef gboolean (*extcap_cb_t)(const gchar *extcap, const gchar *ifname, gchar *output, void *data,
gchar **err_str);
-/* #define ARG_DEBUG */
-#if ARG_DEBUG
-static void extcap_debug_arguments ( extcap_arg *arg_iter );
-#endif
-
static gboolean
extcap_if_exists(const gchar *ifname)
{
}
+static void extcap_free_dlt(gpointer d, gpointer user_data _U_) {
+ if (d == NULL)
+ return;
+
+ g_free(((extcap_dlt *)d)->name);
+ g_free(((extcap_dlt *)d)->display);
+}
+
static gboolean dlt_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data,
char **err_str) {
- extcap_token_sentence *tokens;
- extcap_dlt *dlts, *dlt_iter, *next;
+ GList *dlts = NULL, *temp = NULL;
+
if_capabilities_t *caps;
GList *linktype_list = NULL;
data_link_info_t *data_link_info;
+ extcap_dlt * dlt_item;
- tokens = extcap_tokenize_sentences(output);
- extcap_parse_dlts(tokens, &dlts);
-
- extcap_free_tokenized_sentence_list(tokens);
+ dlts = extcap_parse_dlts(output);
+ temp = dlts;
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Extcap pipe %s ", extcap);
caps = (if_capabilities_t *) g_malloc(sizeof *caps);
caps->can_set_rfmon = FALSE;
- dlt_iter = dlts;
- while (dlt_iter != NULL ) {
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
- " DLT %d name=\"%s\" display=\"%s\" ", dlt_iter->number,
- dlt_iter->name, dlt_iter->display);
-
- data_link_info = g_new(data_link_info_t, 1);
- data_link_info->dlt = dlt_iter->number;
- data_link_info->name = g_strdup(dlt_iter->name);
- data_link_info->description = g_strdup(dlt_iter->display);
- linktype_list = g_list_append(linktype_list, data_link_info);
- dlt_iter = dlt_iter->next_dlt;
+ while (dlts) {
+ dlt_item = (extcap_dlt *)dlts->data;
+ if (dlt_item) {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
+ " DLT %d name=\"%s\" display=\"%s\" ", dlt_item->number,
+ dlt_item->name, dlt_item->display);
+
+ data_link_info = g_new(data_link_info_t, 1);
+ data_link_info->dlt = dlt_item->number;
+ data_link_info->name = g_strdup(dlt_item->name);
+ data_link_info->description = g_strdup(dlt_item->display);
+ linktype_list = g_list_append(linktype_list, data_link_info);
+ }
+
+ dlts = g_list_next(dlts);
}
/* Check to see if we built a list */
g_free(caps);
}
- dlt_iter = dlts;
- while (dlt_iter != NULL ) {
- next = dlt_iter->next_dlt;
- extcap_free_dlt(dlt_iter);
- dlt_iter = next;
- }
+ g_list_foreach(temp, extcap_free_dlt, NULL);
return FALSE;
}
return caps;
}
+static void extcap_free_interface(gpointer i, gpointer user_data _U_) {
+
+ extcap_interface * interface = (extcap_interface *)i;
+
+ if ( i == NULL )
+ return;
+
+ g_free(interface->call);
+ g_free(interface->display);
+ g_free(interface->version);
+}
+
static gboolean interfaces_cb(const gchar *extcap, const gchar *ifname _U_, gchar *output, void *data,
char **err_str _U_) {
GList **il = (GList **) data;
- extcap_token_sentence *tokens;
- extcap_interface *interfaces, *int_iter; /*, *next; */
- if_info_t *if_info;
-
- tokens = extcap_tokenize_sentences(output);
- extcap_parse_interfaces(tokens, &interfaces);
+ GList *interfaces = NULL, *walker = NULL;
+ extcap_interface *int_iter = NULL;
+ if_info_t *if_info = NULL;
- extcap_free_tokenized_sentence_list(tokens);
+ interfaces = extcap_parse_interfaces(output);
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Extcap pipe %s ", extcap);
- int_iter = interfaces;
- while (int_iter != NULL ) {
+ walker = interfaces;
+ while (walker != NULL ) {
+ int_iter = (extcap_interface *)walker->data;
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) );
- int_iter = int_iter->next_interface;
+ walker = g_list_next(walker);
continue;
}
* interfaces) are handled internally */
extcap_tool_add(extcap, int_iter);
- int_iter = int_iter->next_interface;
+ walker = g_list_next(walker);
}
- extcap_free_interface(interfaces);
+
+ g_list_foreach(interfaces, extcap_free_interface, NULL);
return TRUE;
}
extcap_pref_for_argument(const gchar *ifname, struct _extcap_arg * arg) {
struct preference * pref = NULL;
- GRegex * regex = g_regex_new ("[-]+", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
- if (regex) {
+ GRegex * regex_name = g_regex_new ("[-]+", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+ GRegex * regex_ifname = g_regex_new ("(?![a-zA-Z1-9_]).", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+ if (regex_name && regex_ifname) {
if ( prefs_find_module("extcap") ) {
- gchar * pref_name = g_regex_replace(regex, arg->call, strlen(arg->call), 0, "", (GRegexMatchFlags) 0, NULL );
- gchar * pref_ifname = g_strdup(g_strconcat(ifname, ".", pref_name, NULL));
+ gchar * pref_name = g_regex_replace(regex_name, arg->call, strlen(arg->call), 0, "", (GRegexMatchFlags) 0, NULL );
+ gchar * ifname_underscore = g_regex_replace(regex_ifname, ifname, strlen(ifname), 0, "_", (GRegexMatchFlags) 0, NULL );
+ gchar * ifname_lowercase = g_ascii_strdown(ifname_underscore, -1);
+ gchar * pref_ifname = g_strconcat(ifname_lowercase, ".", pref_name, NULL);
pref = prefs_find_preference(prefs_find_module("extcap"), pref_ifname);
g_free(pref_name);
+ g_free(ifname_underscore);
+ g_free(ifname_lowercase);
g_free(pref_ifname);
}
- g_regex_unref(regex);
+ }
+ if (regex_name) {
+ g_regex_unref(regex_name);
+ }
+ if (regex_ifname) {
+ g_regex_unref(regex_ifname);
}
return pref;
static gboolean search_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data,
char **err_str _U_) {
- extcap_token_sentence *tokens = NULL;
GList *arguments = NULL;
GList **il = (GList **) data;
module_t * dev_module = NULL;
- tokens = extcap_tokenize_sentences(output);
- arguments = extcap_parse_args(tokens);
-
- extcap_free_tokenized_sentence_list(tokens);
-
-#if ARG_DEBUG
- extcap_debug_arguments ( arguments );
-#endif
+ arguments = extcap_parse_args(output);
dev_module = prefs_find_module("extcap");
if ( dev_module ) {
GList * walker = arguments;
- GRegex * regex = g_regex_new ("[-]+", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
- if (regex) {
+ GRegex * regex_name = g_regex_new ("[-]+", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+ GRegex * regex_ifname = g_regex_new ("(?![a-zA-Z1-9_]).", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+ if (regex_name && regex_ifname) {
while ( walker != NULL ) {
extcap_arg * arg = (extcap_arg *)walker->data;
arg->device_name = g_strdup(ifname);
if ( arg->save ) {
struct preference * pref = NULL;
- gchar * pref_name = g_regex_replace(regex, arg->call, strlen(arg->call), 0, "", (GRegexMatchFlags) 0, NULL );
- gchar * pref_ifname = g_strdup(g_strconcat(ifname, ".", pref_name, NULL));
+ gchar * pref_name = g_regex_replace(regex_name, arg->call, strlen(arg->call), 0, "", (GRegexMatchFlags) 0, NULL );
+ gchar * ifname_underscore = g_regex_replace(regex_ifname, ifname, strlen(ifname), 0, "_", (GRegexMatchFlags) 0, NULL );
+ gchar * ifname_lowercase = g_ascii_strdown(ifname_underscore, -1);
+ gchar * pref_ifname = g_strconcat(ifname_lowercase, ".", pref_name, NULL);
if ( ( pref = prefs_find_preference(dev_module, pref_ifname) ) == NULL ) {
/* Set an initial value */
}
g_free(pref_name);
+ g_free(ifname_underscore);
+ g_free(ifname_lowercase);
g_free(pref_ifname);
}
walker = g_list_next(walker);
}
- g_regex_unref(regex);
+ }
+ if (regex_name) {
+ g_regex_unref(regex_name);
+ }
+ if (regex_ifname) {
+ g_regex_unref(regex_ifname);
}
}
{
if (userdata->extcap_stderr_rd > 0 && pipe_data_available(userdata->extcap_stderr_rd) )
{
- buffer = (gchar * )g_malloc0(sizeof(gchar) * STDERR_BUFFER_SIZE);
+ buffer = (gchar * )g_malloc0(sizeof(gchar) * STDERR_BUFFER_SIZE + 1);
#ifdef _WIN32
win32_readfrompipe((HANDLE)_get_osfhandle(userdata->extcap_stderr_rd), STDERR_BUFFER_SIZE, buffer);
#else
}
g_free(buffer);
}
- }
#ifndef _WIN32
- /* Final child watch may not have been called */
- if ( interface_opts.extcap_child_watch != 0 )
- {
- extcap_child_watch_cb(userdata->pid, 0, capture_opts);
- /* it will have changed in extcap_child_watch_cb */
- interface_opts = g_array_index(capture_opts->ifaces, interface_options,
- icnt);
- }
+ /* Final child watch may not have been called */
+ if ( interface_opts.extcap_child_watch != 0 )
+ {
+ extcap_child_watch_cb(userdata->pid, 0, capture_opts);
+ /* it will have changed in extcap_child_watch_cb */
+ interface_opts = g_array_index(capture_opts->ifaces, interface_options,
+ icnt);
+ }
#endif
- if ( userdata->extcap_stderr != NULL )
- overwrite_exitcode = TRUE;
+ if ( userdata->extcap_stderr != NULL )
+ overwrite_exitcode = TRUE;
- if ( overwrite_exitcode || userdata->exitcode != 0 )
- {
- if ( userdata->extcap_stderr != 0 )
+ if ( overwrite_exitcode || userdata->exitcode != 0 )
{
- if ( *errormsg == NULL )
- *errormsg = g_strdup_printf("Error by extcap pipe: %s", userdata->extcap_stderr);
- else
+ if ( userdata->extcap_stderr != 0 )
{
- gchar * temp = g_strconcat ( *errormsg, "\nError by extcap pipe: " ,userdata->extcap_stderr, NULL );
- g_free(*errormsg);
- *errormsg = temp;
+ if ( *errormsg == NULL )
+ *errormsg = g_strdup_printf("Error by extcap pipe: %s", userdata->extcap_stderr);
+ else
+ {
+ gchar * temp = g_strconcat ( *errormsg, "\nError by extcap pipe: " ,userdata->extcap_stderr, NULL );
+ g_free(*errormsg);
+ *errormsg = temp;
+ }
+ g_free (userdata->extcap_stderr );
}
- g_free (userdata->extcap_stderr );
- }
- userdata->extcap_stderr = NULL;
- userdata->exitcode = 0;
+ userdata->extcap_stderr = NULL;
+ userdata->exitcode = 0;
+ }
}
if (interface_opts.extcap_child_watch > 0)
{
guint i;
interface_options interface_opts;
- GError * error = 0;
extcap_userdata * userdata = NULL;
capture_options * capture_opts = (capture_options *)(user_data);
{
interface_opts.extcap_pid = INVALID_EXTCAP_PID;
userdata->exitcode = 0;
- if ( ! g_spawn_check_exit_status(status, &error) )
- userdata->exitcode = error->code;
+#ifndef _WIN32
+ if ( WIFEXITED(status) )
+ {
+ if ( WEXITSTATUS(status) != 0 )
+ userdata->exitcode = WEXITSTATUS(status);
+ }
+ else
+ userdata->exitcode = G_SPAWN_ERROR_FAILED;
+#else
+ if (status != 0)
+ userdata->exitcode = status;
+#endif
if ( status == 0 && userdata->extcap_stderr != NULL )
userdata->exitcode = 1;
}
GPtrArray * extcap_prepare_arguments(interface_options interface_opts)
{
GPtrArray *result = NULL;
-#if ARG_DEBUG
- gchar **tmp;
- int tmp_i;
-#endif
if (interface_opts.if_type == IF_EXTCAP )
{
add_arg(NULL);
#undef add_arg
-#if ARG_DEBUG
- /* Dump commandline parameters sent to extcap. */
- for (tmp = (gchar **)result->pdata, tmp_i = 0; *tmp && **tmp; ++tmp_i, ++tmp)
- {
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", tmp_i, *tmp);
- }
-#endif
-
}
return result;
return TRUE;
}
-#if ARG_DEBUG
-void extcap_debug_arguments ( extcap_arg *arg_iter )
-{
- extcap_value *v = NULL;
- GList *walker = NULL;
-
- printf("debug - parser dump\n");
- while (arg_iter != NULL) {
- printf("ARG %d call=%s display=\"%s\" type=", arg_iter->arg_num, arg_iter->call, arg_iter->display);
-
- switch (arg_iter->arg_type) {
- case EXTCAP_ARG_INTEGER:
- printf("int\n");
- break;
- case EXTCAP_ARG_UNSIGNED:
- printf("unsigned\n");
- break;
- case EXTCAP_ARG_LONG:
- printf("long\n");
- break;
- case EXTCAP_ARG_DOUBLE:
- printf("double\n");
- break;
- case EXTCAP_ARG_BOOLEAN:
- printf("boolean\n");
- break;
- case EXTCAP_ARG_MENU:
- printf("menu\n");
- break;
- case EXTCAP_ARG_RADIO:
- printf("radio\n");
- break;
- case EXTCAP_ARG_SELECTOR:
- printf("selctor\n");
- break;
- case EXTCAP_ARG_STRING:
- printf ( "string\n" );
- break;
- case EXTCAP_ARG_PASSWORD:
- printf ( "PASSWORD\n" );
- break;
- case EXTCAP_ARG_MULTICHECK:
- printf ( "unknown\n" );
- break;
- case EXTCAP_ARG_UNKNOWN:
- printf ( "unknown\n" );
- break;
- }
-
- if (arg_iter->range_start != NULL && arg_iter->range_end != NULL) {
- printf("\tRange: ");
- extcap_printf_complex(arg_iter->range_start);
- printf(" - ");
- extcap_printf_complex(arg_iter->range_end);
- printf("\n");
- }
-
- for ( walker = g_list_first ( arg_iter->value_list ); walker; walker = walker->next )
- {
- v = (extcap_value *)walker->data;
- if (v->is_default)
- printf("*");
- printf("\tcall=\"%p\" display=\"%p\"\n", v->call, v->display);
- printf("\tcall=\"%s\" display=\"%s\"\n", v->call, v->display);
- }
-
- arg_iter = arg_iter->next_arg;
- }
-}
-#endif
-
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*