summaryrefslogtreecommitdiff
path: root/src/helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/helpers.c')
-rw-r--r--src/helpers.c76
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);
+}