diff options
Diffstat (limited to 'src/helpers.c')
| -rw-r--r-- | src/helpers.c | 76 | 
1 files changed, 76 insertions, 0 deletions
diff --git a/src/helpers.c b/src/helpers.c new file mode 100644 index 0000000..3e4e6c8 --- /dev/null +++ b/src/helpers.c @@ -0,0 +1,76 @@ +/* + * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation (or any later at your option). + * + * This code has been sponsored by Vyatta Inc. <http://www.vyatta.com> + */ + +#include "helper.h" + +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dlfcn.h> + +static LIST_HEAD(helper_list); + +void helper_register(struct ctd_helper *helper) +{ +	list_add(&helper->head, &helper_list); +} + +static struct ctd_helper * +__helper_find(const char *helper_name, uint8_t l4proto) +{ +	struct ctd_helper *cur, *helper = NULL; + +	list_for_each_entry(cur, &helper_list, head) { +		if (strncmp(cur->name, helper_name, CTD_HELPER_NAME_LEN) != 0) +			continue; + +		if (cur->l4proto != l4proto) +			continue; + +		helper = cur; +		break; +	} +	return helper; +} + +struct ctd_helper * +helper_find(const char *libdir_path, +	    const char *helper_name, uint8_t l4proto, int flag) +{ +	char path[PATH_MAX]; +	struct ctd_helper *helper; +	struct stat sb; + +	helper = __helper_find(helper_name, l4proto); +	if (helper != NULL) +		return helper; + +	snprintf(path, sizeof(path), "%s/ct_helper_%s.so", +		libdir_path, helper_name); + +	if (stat(path, &sb) != 0) { +		if (errno == ENOENT) +			return NULL; +		fprintf(stderr, "%s: %s\n", path, +			strerror(errno)); +		return NULL; +	} + +	if (dlopen(path, flag) == NULL) { +		fprintf(stderr, "%s: %s\n", path, dlerror()); +		return NULL; +	} + +	return __helper_find(helper_name, l4proto); +}  | 
