/*
- * m_ipt.c iptables based targets
+ * m_ipt.c iptables based targets
* utilities mostly ripped from iptables <duh, its the linux way>
*
* This program is free software; you can distribute it and/or
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Authors: J Hadi Salim (hadi@cyberus.ca)
- *
- * TODO: bad bad hardcoding IPT_LIB_DIR and PROC_SYS_MODPROBE
- *
-*/
+ * Authors: J Hadi Salim (hadi@cyberus.ca)
+ */
#include <syslog.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <linux/if.h>
#include <iptables.h>
+#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include "utils.h"
#include "tc_util.h"
#include <fcntl.h>
#include <sys/wait.h>
-const char *pname = "tc-ipt";
-const char *tname = "mangle";
-const char *pversion = "0.1";
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef IPT_LIB_DIR
-#define IPT_LIB_DIR "/usr/local/lib/iptables"
-#endif
-
-#ifndef PROC_SYS_MODPROBE
-#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
-#endif
+static const char *pname = "tc-ipt";
+static const char *tname = "mangle";
+static const char *pversion = "0.1";
static const char *ipthooks[] = {
"NF_IP_PRE_ROUTING",
static unsigned int global_option_offset = 0;
#define OPTION_OFFSET 256
+char *lib_dir;
void
register_target(struct iptables_target *me)
}
+void
+xtables_register_target(struct iptables_target *me)
+{
+ me->next = t_list;
+ t_list = me;
+}
+
void
exit_tryhelp(int status)
{
return buf;
}
-int string_to_number_ll(const char *s, unsigned long long min,
+int string_to_number_ll(const char *s, unsigned long long min,
unsigned long long max,
unsigned long long *ret)
{
}
static struct iptables_target *
-get_target_name(char *name)
+get_target_name(const char *name)
{
void *handle;
char *error;
char *new_name, *lname;
struct iptables_target *m;
-
- char path[sizeof (IPT_LIB_DIR) + sizeof ("/libipt_.so") + strlen(name)];
+ char path[strlen(lib_dir) + sizeof ("/libipt_.so") + strlen(name)];
new_name = malloc(strlen(name) + 1);
lname = malloc(strlen(name) + 1);
}
}
- sprintf(path, IPT_LIB_DIR "/libipt_%s.so", new_name);
+ /* try libxt_xx first */
+ sprintf(path, "%s/libxt_%s.so", lib_dir, new_name);
handle = dlopen(path, RTLD_LAZY);
if (!handle) {
- sprintf(path, IPT_LIB_DIR "/libipt_%s.so", lname);
+ /* try libipt_xx next */
+ sprintf(path, "%s/libipt_%s.so", lib_dir, new_name);
handle = dlopen(path, RTLD_LAZY);
+
+ if (!handle) {
+ sprintf(path, "%s/libxt_%s.so", lib_dir , lname);
+ handle = dlopen(path, RTLD_LAZY);
+ }
+
+ if (!handle) {
+ sprintf(path, "%s/libipt_%s.so", lib_dir , lname);
+ handle = dlopen(path, RTLD_LAZY);
+ }
+ /* ok, lets give up .. */
if (!handle) {
fputs(dlerror(), stderr);
printf("\n");
+ free(new_name);
return NULL;
}
}
fputs(error, stderr);
fprintf(stderr, "\n");
dlclose(handle);
+ free(new_name);
return NULL;
}
}
}
}
+ free(new_name);
return m;
}
name[IPT_FUNCTION_MAXNAMELEN - 1] = revision;
}
-/*
+/*
* we may need to check for version mismatch
*/
int
return -1;
}
-static int parse_ipt(struct action_util *a,int *argc_p,
+static int parse_ipt(struct action_util *a,int *argc_p,
char ***argv_p, int tca_id, struct nlmsghdr *n)
{
struct iptables_target *m = NULL;
__u32 hook = 0, index = 0;
res = 0;
+ lib_dir = getenv("IPTABLES_LIB_DIR");
+ if (!lib_dir)
+ lib_dir = IPT_LIB_DIR;
+
{
int i;
for (i = 0; i < rargc; i++) {
argv += optind;
*argc_p = rargc - iargc;
*argv_p = argv;
-
- optind = 1;
+
+ optind = 0;
free_opts(opts);
+ /* Clear flags if target will be used again */
+ m->tflags=0;
+ m->used=0;
+ /* Free allocated memory */
+ if (m->t)
+ free(m->t);
+
return 0;
if (arg == NULL)
return -1;
+ lib_dir = getenv("IPTABLES_LIB_DIR");
+ if (!lib_dir)
+ lib_dir = IPT_LIB_DIR;
+
parse_rtattr_nested(tb, TCA_IPT_MAX, arg);
if (tb[TCA_IPT_TABLE] == NULL) {
struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]);
print_tm(f,tm);
}
- }
+ }
fprintf(f, " \n");
}