summaryrefslogtreecommitdiffhomepage
path: root/contrib
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2009-12-17 01:07:44 +0000
committerJo-Philipp Wich <jow@openwrt.org>2009-12-17 01:07:44 +0000
commit9903178ee7f107dc04a4ecf48eccde12353622f4 (patch)
tree482e2373e8f21cf03457f42f53c66517a9fd472d /contrib
parent5abef1380ef5c4271aa1d26339306dccf04c9ab2 (diff)
contrib/fwd: implement fwd_ipt_delif() and fwd_ipt_clear_ruleset()
Diffstat (limited to 'contrib')
-rw-r--r--contrib/fwd/src/fwd.c8
-rw-r--r--contrib/fwd/src/fwd_rules.c145
-rw-r--r--contrib/fwd/src/fwd_rules.h19
3 files changed, 155 insertions, 17 deletions
diff --git a/contrib/fwd/src/fwd.c b/contrib/fwd/src/fwd.c
index 9d925bc00..903834b10 100644
--- a/contrib/fwd/src/fwd.c
+++ b/contrib/fwd/src/fwd.c
@@ -27,7 +27,6 @@
int main(int argc, const char *argv[])
{
struct fwd_handle *h;
- struct iptc_handle *ipt;
if( getuid() > 0 )
fwd_fatal("Need root permissions!");
@@ -49,6 +48,13 @@ int main(int argc, const char *argv[])
fwd_ipt_addif(h, "lan");
fwd_ipt_addif(h, "wan");
+ sleep(1);
+
+ fwd_ipt_delif(h, "wan");
+ fwd_ipt_delif(h, "lan");
+
+ fwd_ipt_clear_ruleset(h);
+
close(h->rtnl_socket);
fwd_free_config(h->conf);
fwd_free_addrs(h->addrs);
diff --git a/contrib/fwd/src/fwd_rules.c b/contrib/fwd/src/fwd_rules.c
index e6604911a..141ce8565 100644
--- a/contrib/fwd/src/fwd_rules.c
+++ b/contrib/fwd/src/fwd_rules.c
@@ -397,6 +397,27 @@ static void fwd_r_add_dnattarget(
}
}
+/* parse comment string and look for match */
+static int fwd_r_cmp(const char *what, const char *cmt, const char *cmp)
+{
+ char *match;
+
+ printf("CMP: %s %s %s\n", what, cmt, cmp);
+
+ 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)
{
@@ -775,3 +796,127 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net)
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));
+
+ if( !iptc_commit(h_filter) )
+ fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno));
+
+ iptc_free(h_nat);
+ iptc_free(h_filter);
+}
+
diff --git a/contrib/fwd/src/fwd_rules.h b/contrib/fwd/src/fwd_rules.h
index 7074622e3..f3492c580 100644
--- a/contrib/fwd/src/fwd_rules.h
+++ b/contrib/fwd/src/fwd_rules.h
@@ -21,24 +21,11 @@
#include "fwd.h"
-#define IPT "iptables"
-
-struct fwd_ipt_rulebuf {
- char *buf;
- size_t len;
-};
-
-
-#define fwd_ipt_add_format fwd_ipt_rule_append
-
-#define fwd_ipt_exec_format(t, ...) do { \
- struct fwd_ipt_rulebuf *r = fwd_ipt_init(t); \
- fwd_ipt_add_format(r, __VA_ARGS__); \
- fwd_ipt_exec(r); \
-} while(0)
-
void fwd_ipt_build_ruleset(struct fwd_handle *h);
+void fwd_ipt_clear_ruleset(struct fwd_handle *h);
+
void fwd_ipt_addif(struct fwd_handle *h, const char *net);
+void fwd_ipt_delif(struct fwd_handle *h, const char *net);
#endif