if( (r = fwd_xt_init_rule(h)) != NULL )
{
fwd_xt_get_target(r, chain2);
- fwd_xt_exec_rule(r, chain1);
+ fwd_xt_append_rule(r, chain1);
}
}
{
fwd_xt_parse_match(r, m, "--state", "INVALID");
fwd_xt_get_target(r, "DROP");
- fwd_xt_exec_rule(r, chain);
+ fwd_xt_append_rule(r, chain);
}
}
}
{
fwd_xt_parse_match(r, m, "--state", "RELATED,ESTABLISHED");
fwd_xt_get_target(r, "ACCEPT");
- fwd_xt_exec_rule(r, chain);
+ fwd_xt_append_rule(r, chain);
}
}
}
{
fwd_xt_parse_in(r, &n, 0);
fwd_xt_get_target(r, "ACCEPT");
- fwd_xt_exec_rule(r, "INPUT");
+ fwd_xt_append_rule(r, "INPUT");
}
if( (r = fwd_xt_init_rule(h)) != NULL )
{
fwd_xt_parse_out(r, &n, 0);
fwd_xt_get_target(r, "ACCEPT");
- fwd_xt_exec_rule(r, "OUTPUT");
+ fwd_xt_append_rule(r, "OUTPUT");
}
}
/* -j RETURN; -A syn_flood */
fwd_xt_get_target(r, "RETURN");
- fwd_xt_exec_rule(r, "syn_flood");
+ fwd_xt_append_rule(r, "syn_flood");
}
/* drop rule */
{
/* -j DROP; -A syn_flood */
fwd_xt_get_target(r, "DROP");
- fwd_xt_exec_rule(r, "syn_flood");
+ fwd_xt_append_rule(r, "syn_flood");
}
/* jump to syn_flood rule */
/* -j syn_flood; -A INPUT */
fwd_xt_get_target(r, "syn_flood");
- fwd_xt_exec_rule(r, "INPUT");
+ fwd_xt_append_rule(r, "INPUT");
}
}
}
/* -A handle_reject */
- fwd_xt_exec_rule(r, "handle_reject");
+ fwd_xt_append_rule(r, "handle_reject");
}
/* common reject rule */
}
/* -A handle_reject */
- fwd_xt_exec_rule(r, "handle_reject");
+ fwd_xt_append_rule(r, "handle_reject");
}
}
/* common drop rule */
if( (r = fwd_xt_init_rule(h)) != NULL )
{
- /* -j DROP; -A handle_reject */
+ /* -j DROP; -A handle_drop */
fwd_xt_get_target(r, "DROP");
- fwd_xt_exec_rule(r, "handle_reject");
+ fwd_xt_append_rule(r, "handle_drop");
}
}
{
/* -j ACCEPT; -A handle_accept */
fwd_xt_get_target(r, "ACCEPT");
- fwd_xt_exec_rule(r, "handle_accept");
+ fwd_xt_append_rule(r, "handle_accept");
}
}
}
}
+/* parse comment string and look for match */
+static int fwd_r_cmp(const char *what, const char *cmt, const char *cmp)
+{
+ char *match;
+
+ if( (match = strstr(cmt, what)) == NULL )
+ return 0;
+
+ match += strlen(what);
+
+ if( strncmp(match, cmp, strlen(cmp)) != 0 )
+ return 0;
+
+ if( (match[strlen(cmp)] != ' ') && (match[strlen(cmp)] != '\0') )
+ return 0;
+
+ return 1;
+}
+
static void fwd_ipt_defaults_create(struct fwd_data *d)
{
fwd_xt_parse_out(x, n, 0); /* -o ... */
fwd_xt_get_target(x, "MASQUERADE"); /* -j MASQUERADE */
fwd_r_add_comment(x, "masq", z, NULL, n); /* -m comment ... */
- fwd_xt_exec_rule(x, "zonemasq"); /* -A zonemasq */
+ fwd_xt_append_rule(x, "zonemasq"); /* -A zonemasq */
}
}
fwd_r_add_comment(x, "mssfix", z, NULL, n);
/* -A mssfix */
- fwd_xt_exec_rule(x, "mssfix");
+ fwd_xt_append_rule(x, "mssfix");
}
}
fwd_xt_parse_out(x, n2, 0); /* -o ... */
fwd_r_add_policytarget(x, z->forward); /* -j handle_... */
fwd_r_add_comment(x, "zone", z, n, n2); /* -m comment ... */
- fwd_xt_exec_rule(x, "zones"); /* -A zones */
+ fwd_xt_append_rule(x, "zones"); /* -A zones */
}
}
}
fwd_xt_parse_out(x, n2, 0); /* -o ... */
fwd_r_add_policytarget(x, FWD_P_ACCEPT); /* -j handle_... */
fwd_r_add_comment(x, "forward", z, n, n2); /* -m comment ... */
- fwd_xt_exec_rule(x, "forwardings"); /* -A forwardings */
+ fwd_xt_append_rule(x, "forwardings"); /* -A forwardings */
}
}
}
fwd_r_add_srcmac(x, r->src_mac); /* -m mac --mac-source ... */
fwd_r_add_dnattarget(x, r->dest_ip, r->dest_port); /* -j DNAT ... */
fwd_r_add_comment(x, "redir", z, n, NULL); /* -m comment ... */
- fwd_xt_exec_rule(x, "redirects"); /* -A redirects */
+ fwd_xt_append_rule(x, "redirects"); /* -A redirects */
}
/* Forward */
fwd_r_add_dport(x, r->dest_port); /* --dport ... */
fwd_r_add_policytarget(x, FWD_P_ACCEPT); /* -j handle_accept */
fwd_r_add_comment(x, "redir", z, n, NULL); /* -m comment ... */
- fwd_xt_exec_rule(x, "redirects"); /* -A redirects */
+ fwd_xt_append_rule(x, "redirects"); /* -A redirects */
}
/* Add loopback rule if neither src_ip nor src_mac are defined */
fwd_r_add_dport(x, r->src_dport); /* --dport ... */
fwd_xt_get_target(x, "MASQUERADE"); /* -j MASQUERADE */
fwd_r_add_comment(x, "redir", z, n, NULL); /* -m comment ... */
- fwd_xt_exec_rule(x, "loopback"); /* -A loopback */
+ fwd_xt_append_rule(x, "loopback"); /* -A loopback */
}
}
}
fwd_r_add_dport(x, c->dest_port); /* --dport ... */
fwd_r_add_policytarget(x, c->target); /* -j handle_... */
fwd_r_add_comment(x, "rule", z, n, n2); /* -m comment ... */
- fwd_xt_exec_rule(x, "rules"); /* -A rules */
+ fwd_xt_append_rule(x, "rules"); /* -A rules */
}
}
}
fwd_r_add_dport(x, c->dest_port); /* --dport ... */
fwd_r_add_policytarget(x, c->target); /* -j handle_... */
fwd_r_add_comment(x, "rule", z, n, NULL); /* -m comment ... */
- fwd_xt_exec_rule(x, "rules"); /* -A rules */
+ fwd_xt_append_rule(x, "rules"); /* -A rules */
+ }
+ }
+ }
+
+ if( !iptc_commit(h_nat) )
+ fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno));
+
+ if( !iptc_commit(h_filter) )
+ fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno));
+
+ iptc_free(h_nat);
+ iptc_free(h_filter);
+}
+
+
+static void fwd_ipt_delif_table(struct iptc_handle *h, const char *net)
+{
+ struct xt_entry_match *m;
+ struct ipt_entry *e;
+ const char *chain, *comment;
+ size_t off = 0, num = 0;
+
+ /* iterate chains */
+ for( chain = iptc_first_chain(h); chain;
+ chain = iptc_next_chain(h)
+ ) {
+ /* iterate rules */
+ for( e = iptc_first_rule(chain, h), num = 0; e;
+ e = iptc_next_rule(e, h), num++
+ ) {
+ repeat_rule:
+
+ /* skip entries w/o matches */
+ if( ! e->target_offset )
+ continue;
+
+ /* iterate matches */
+ for( off = sizeof(struct ipt_entry);
+ off < e->target_offset;
+ off += m->u.match_size
+ ) {
+ m = (void *)e + off;
+
+ /* yay */
+ if( ! strcmp(m->u.user.name, "comment") )
+ {
+ /* better use struct_xt_comment_info but well... */
+ comment = (void *)m + sizeof(struct xt_entry_match);
+
+ if( fwd_r_cmp("src:", comment, net) )
+ {
+ e = iptc_next_rule(e, h);
+ iptc_delete_num_entry(chain, num, h);
+
+ if( e != NULL )
+ goto repeat_rule;
+ else
+ break;
+ }
+ }
}
}
}
+}
+
+void fwd_ipt_delif(struct fwd_handle *h, const char *net)
+{
+ struct iptc_handle *h_filter, *h_nat;
+
+ if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) )
+ fwd_fatal("Unable to obtain libiptc handle");
+
+
+ printf("\n\n#\n# delif(%s)\n#\n", net);
+
+ /* delete network related rules */
+ fwd_ipt_delif_table(h_nat, net);
+ fwd_ipt_delif_table(h_filter, net);
+
+
+ if( !iptc_commit(h_nat) )
+ fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno));
+
+ if( !iptc_commit(h_filter) )
+ fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno));
+
+ iptc_free(h_nat);
+ iptc_free(h_filter);
+}
+
+
+static void fwd_ipt_clear_ruleset_table(struct iptc_handle *h)
+{
+ const char *chain;
+
+ /* pass 1: flush all chains */
+ for( chain = iptc_first_chain(h); chain;
+ chain = iptc_next_chain(h)
+ ) {
+ iptc_flush_entries(chain, h);
+ }
+
+ /* pass 2: remove user defined chains */
+ for( chain = iptc_first_chain(h); chain;
+ chain = iptc_next_chain(h)
+ ) {
+ if( ! iptc_builtin(chain, h) )
+ iptc_delete_chain(chain, h);
+ }
+}
+
+void fwd_ipt_clear_ruleset(struct fwd_handle *h)
+{
+ struct iptc_handle *h_filter, *h_nat;
+
+ if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) )
+ fwd_fatal("Unable to obtain libiptc handle");
+
+ /* flush tables */
+ fwd_ipt_clear_ruleset_table(h_nat);
+ fwd_ipt_clear_ruleset_table(h_filter);
+
+ /* revert policies */
+ fwd_r_set_policy(h_filter, "INPUT", "ACCEPT");
+ fwd_r_set_policy(h_filter, "OUTPUT", "ACCEPT");
+ fwd_r_set_policy(h_filter, "FORWARD", "ACCEPT");
+
if( !iptc_commit(h_nat) )
fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno));