};
/* Required by certain extensions like SNAT and DNAT */
-int kernel_version;
+int kernel_version = 0;
void
get_kernel_version(void)
sprintf(uts.release, "3.0.0");
sscanf(uts.release, "%d.%d.%d", &x, &y, &z);
- kernel_version = LINUX_VERSION(x, y, z);
+ kernel_version = 0x10000 * x + 0x100 * y + z;
+}
+
+#undef __ipt_module
+#define __ipt_module(x) libxt_##x##_init, libipt_##x##_init, libip6t_##x##_init,
+
+static void fw3_init_extensions(void)
+{
+ int i;
+ void (*initfuncs[])(void) = { FW3_IPT_MODULES };
+
+ for (i = 0; i < sizeof(initfuncs)/sizeof(initfuncs[0]); i++)
+ if (initfuncs[i])
+ initfuncs[i]();
}
struct fw3_ipt_handle *
xtables_matches = NULL;
xtables_targets = NULL;
- init_extensions();
- init_extensions4();
- init_extensions6();
+ fw3_init_extensions();
return h;
}
+static void
+debug(struct fw3_ipt_handle *h, const char *fmt, ...)
+{
+ va_list ap;
+
+ printf("%s -t %s ", (h->family == FW3_FAMILY_V6) ? "ip6tables" : "iptables",
+ fw3_flag_names[h->table]);
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
void
fw3_ipt_set_policy(struct fw3_ipt_handle *h, const char *chain,
enum fw3_flag policy)
{
if (fw3_pr_debug)
- printf("-P %s %s\n", chain, fw3_flag_names[policy]);
+ debug(h, "-P %s %s\n", chain, fw3_flag_names[policy]);
if (h->family == FW3_FAMILY_V6)
ip6tc_set_policy(chain, fw3_flag_names[policy], NULL, h->handle);
{
if (fw3_pr_debug)
{
- printf("-F %s\n", chain);
- printf("-X %s\n", chain);
+ debug(h, "-F %s\n", chain);
+ debug(h, "-X %s\n", chain);
}
if (h->family == FW3_FAMILY_V6)
if (*t && !strcmp(t, target))
{
if (fw3_pr_debug)
- printf("-D %s %u\n", chain, num + 1);
+ debug(h, "-D %s %u\n", chain, num + 1);
ip6tc_delete_num_entry(chain, num, h->handle);
found = true;
if (*t && !strcmp(t, target))
{
if (fw3_pr_debug)
- printf("-D %s %u\n", chain, num + 1);
+ debug(h, "-D %s %u\n", chain, num + 1);
iptc_delete_num_entry(chain, num, h->handle);
found = true;
}
void
+fw3_ipt_create_chain(struct fw3_ipt_handle *h, const char *fmt, ...)
+{
+ char buf[32];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
+ va_end(ap);
+
+ if (fw3_pr_debug)
+ debug(h, "-N %s\n", buf);
+
+ iptc_create_chain(buf, h->handle);
+}
+
+void
fw3_ipt_flush(struct fw3_ipt_handle *h)
{
const char *chain;
s = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
m->m = fw3_alloc(s);
- strcpy(m->m->u.user.name, m->real_name ? m->real_name : m->name);
+
+ fw3_xt_set_match_name(m);
+
m->m->u.user.revision = m->revision;
m->m->u.match_size = s;
/* free previous userspace data */
- if (m->udata_size)
- {
- free(m->udata);
- m->udata = fw3_alloc(m->udata_size);
- }
+ fw3_xt_free_match_udata(m);
if (m->init)
m->init(m->m);
/* merge option table */
g = (r->h->family == FW3_FAMILY_V6) ? &xtg6 : &xtg;
-
- if (m->x6_options)
- g->opts = xtables_options_xfrm(g->orig_opts, g->opts,
- m->x6_options, &m->option_offset);
-
- if (m->extra_opts)
- g->opts = xtables_merge_options(g->orig_opts, g->opts,
- m->extra_opts, &m->option_offset);
+ fw3_xt_merge_match_options(g, m);
}
static bool
s = XT_ALIGN(sizeof(struct xt_entry_target)) + t->size;
t->t = fw3_alloc(s);
- if (!t->real_name)
- strcpy(t->t->u.user.name, name);
- else
- strcpy(t->t->u.user.name, t->real_name);
+ fw3_xt_set_target_name(t, name);
t->t->u.user.revision = t->revision;
t->t->u.target_size = s;
- if (t->udata_size)
- {
- free(t->udata);
- t->udata = fw3_alloc(t->udata_size);
- }
+ /* free previous userspace data */
+ fw3_xt_free_target_udata(t);
if (t->init)
t->init(t->t);
/* merge option table */
g = (r->h->family == FW3_FAMILY_V6) ? &xtg6 : &xtg;
-
- if (t->x6_options)
- g->opts = xtables_options_xfrm(g->orig_opts, g->opts,
- t->x6_options, &t->option_offset);
- else
- g->opts = xtables_merge_options(g->orig_opts, g->opts,
- t->extra_opts, &t->option_offset);
+ fw3_xt_merge_target_options(g, t);
r->target = t;
struct xtables_match *m;
struct xtables_target *t;
- printf("-A %s", chain);
+ debug(r->h, "-A %s", chain);
if (r->h->family == FW3_FAMILY_V6)
rule_print6(&r->e6);
for (rm = r->matches; rm; rm = rm->next)
{
m = rm->match;
- printf(" -m %s", m->alias ? m->alias(m->m) : m->m->u.user.name);
+ printf(" -m %s", fw3_xt_get_match_name(m));
if (m->save)
m->save(&r->e.ip, m->m);
if (r->target)
{
t = r->target;
- printf(" -j %s", t->alias ? t->alias(t->t) : t->t->u.user.name);
+ printf(" -j %s", fw3_xt_get_target_name(t));
if (t->save)
t->save(&r->e.ip, t->t);
struct xtables_match *em;
/* is a target option */
- if (r->target && (r->target->parse || r->target->x6_parse) &&
+ if (r->target && fw3_xt_has_target_parse(r->target) &&
optc >= r->target->option_offset &&
optc < (r->target->option_offset + 256))
{
{
em = m->match;
- if (m->completed || (!em->parse && !em->x6_parse))
+ if (m->completed || !fw3_xt_has_match_parse(em))
continue;
if (optc < em->option_offset ||
if (!em)
{
fprintf(stderr, "fw3_ipt_rule_append(): Can't find match '%s'\n", optarg);
- return;
+ goto free;
}
init_match(r, em, true);
if (!et)
{
fprintf(stderr, "fw3_ipt_rule_append(): Can't find target '%s'\n", optarg);
- return;
+ goto free;
}
break;
free(e);
}
+free:
for (i = 1; i < r->argc; i++)
free(r->argv[i]);
xtables_rule_matches_free(&r->matches);
- free(r->target->t);
+ if (r->target)
+ free(r->target->t);
+
free(r);
/* reset all targets and matches */