diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2009-12-16 02:02:45 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2009-12-16 02:02:45 +0000 |
commit | 0f791a7fb6a67cf30d91775e4ae768679e14d610 (patch) | |
tree | c655fc3b31bdc44bb6a8c4bcfb90df3ce1c86496 /contrib/fwd/src/fwd_rules.c | |
parent | a833e120b7f8a835f07e6d9bb5c37df149580468 (diff) |
contrib/fwd: rewrite rule generate to use xtables api
Diffstat (limited to 'contrib/fwd/src/fwd_rules.c')
-rw-r--r-- | contrib/fwd/src/fwd_rules.c | 569 |
1 files changed, 288 insertions, 281 deletions
diff --git a/contrib/fwd/src/fwd_rules.c b/contrib/fwd/src/fwd_rules.c index c3d4ebbe53..e6604911a7 100644 --- a/contrib/fwd/src/fwd_rules.c +++ b/contrib/fwd/src/fwd_rules.c @@ -22,199 +22,6 @@ #include "fwd_rules.h" #include "fwd_xtables.h" -static void -fwd_ipt_rule_append(struct fwd_ipt_rulebuf *r, const char *fmt, ...) -{ - int len = 0; - char buf[256]; buf[0] = 0; - - va_list ap; - va_start(ap, fmt); - len = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - if( len > 0 ) - { - r->buf = realloc(r->buf, r->len + len + 1); - memcpy(&r->buf[r->len], buf, len); - r->buf[r->len + len] = 0; - r->len += len; - } -} - -static struct fwd_ipt_rulebuf * fwd_ipt_init(const char *table) -{ - struct fwd_ipt_rulebuf *r; - - if( (r = fwd_alloc_ptr(struct fwd_ipt_rulebuf)) != NULL ) - { - fwd_ipt_rule_append(r, IPT " -t %s", table); - return r; - } - - return NULL; -} - -static void fwd_ipt_add_srcport( - struct fwd_ipt_rulebuf *r, struct fwd_portrange *p -) { - if( p != NULL ) - { - if( p->min < p->max ) - fwd_ipt_rule_append(r, " --sport %u:%u", p->min, p->max); - else - fwd_ipt_rule_append(r, " --sport %u", p->min); - } -} - -static void fwd_ipt_add_destport( - struct fwd_ipt_rulebuf *r, struct fwd_portrange *p -) { - if( p != NULL ) - { - if( p->min < p->max ) - fwd_ipt_rule_append(r, " --dport %u:%u", p->min, p->max); - else - fwd_ipt_rule_append(r, " --dport %u", p->min); - } -} - -static void fwd_ipt_add_proto( - struct fwd_ipt_rulebuf *r, struct fwd_proto *p -) { - if( p != NULL ) - { - switch( p->type ) - { - case FWD_PR_TCPUDP: - fwd_ipt_rule_append(r, " -p tcp -p udp"); - break; - - case FWD_PR_TCP: - fwd_ipt_rule_append(r, " -p tcp"); - break; - - case FWD_PR_UDP: - fwd_ipt_rule_append(r, " -p udp"); - break; - - case FWD_PR_ICMP: - fwd_ipt_rule_append(r, " -p icmp"); - break; - - case FWD_PR_ALL: - fwd_ipt_rule_append(r, " -p all"); - break; - - case FWD_PR_CUSTOM: - fwd_ipt_rule_append(r, " -p %u", p->proto); - break; - } - } -} - -static void fwd_ipt_add_srcaddr( - struct fwd_ipt_rulebuf *r, struct fwd_cidr *c -) { - if( c != NULL ) - { - if( c->prefix < 32 ) - fwd_ipt_rule_append(r, " -s %s/%u", - inet_ntoa(c->addr), c->prefix); - else - fwd_ipt_rule_append(r, " -s %s", inet_ntoa(c->addr)); - } -} - -static void fwd_ipt_add_destaddr( - struct fwd_ipt_rulebuf *r, struct fwd_cidr *c -) { - if( c != NULL ) - { - if( c->prefix < 32 ) - fwd_ipt_rule_append(r, " -d %s/%u", - inet_ntoa(c->addr), c->prefix); - else - fwd_ipt_rule_append(r, " -d %s", inet_ntoa(c->addr)); - } -} - -static void fwd_ipt_add_srcmac( - struct fwd_ipt_rulebuf *r, struct fwd_mac *m -) { - if( m != NULL ) - { - fwd_ipt_rule_append(r, - " -m mac --mac-source %02x:%02x:%02x:%02x:%02x:%02x", - m->mac[0], m->mac[1], m->mac[2], - m->mac[3], m->mac[4], m->mac[5]); - } -} - -static void fwd_ipt_add_icmptype( - struct fwd_ipt_rulebuf *r, struct fwd_icmptype *i -) { - if( i != NULL ) - { - if( i->name ) - fwd_ipt_rule_append(r, " --icmp-type %s", i->name); - else if( i->code > -1 ) - fwd_ipt_rule_append(r, " --icmp-type %u/%u", i->type, i->code); - else - fwd_ipt_rule_append(r, " --icmp-type %u", i->type); - } -} - -static void fwd_ipt_add_dnat_target( - struct fwd_ipt_rulebuf *r, struct fwd_cidr *c, struct fwd_portrange *p -) { - if( c != NULL ) - { - fwd_ipt_rule_append(r, " -j DNAT --to-destination %s", - inet_ntoa(c->addr)); - - if( (p != NULL) && (p->min < p->max) ) - fwd_ipt_rule_append(r, ":%u-%u", p->min, p->max); - else if( p != NULL ) - fwd_ipt_rule_append(r, ":%u", p->min); - } -} - -static void fwd_ipt_add_policy_target( - struct fwd_ipt_rulebuf *r, enum fwd_policy p -) { - fwd_ipt_rule_append(r, " -j %s", - (p == FWD_P_ACCEPT) - ? "handle_accept" - : (p == FWD_P_REJECT) - ? "handle_reject" - : "handle_drop" - ); -} - -static void fwd_ipt_add_comment( - struct fwd_ipt_rulebuf *r, const char *t, struct fwd_zone *z, - struct fwd_network_list *n, struct fwd_network_list *n2 -) { - if( (n != NULL) && (n2 != NULL) ) - fwd_ipt_add_format(r, " -m comment --comment '%s:%s src:%s dest:%s'", - t, z->name, n->name, n2->name); - else if( (n == NULL) && (n2 != NULL) ) - fwd_ipt_add_format(r, " -m comment --comment '%s:%s dest:%s'", - t, z->name, n2->name); - else - fwd_ipt_add_format(r, " -m comment --comment '%s:%s src:%s'", - t, z->name, n->name); -} - -static void fwd_ipt_exec(struct fwd_ipt_rulebuf *r) -{ - if( r->len ) - printf("%s\n", r->buf); - - fwd_free_ptr(r->buf); - fwd_free_ptr(r); -} /* -P <chain> <policy> */ static void fwd_r_set_policy( @@ -252,7 +59,7 @@ static void fwd_r_drop_invalid(struct iptc_handle *h, const char *chain) { if( (m = fwd_xt_get_match(r, "state")) != NULL ) { - fwd_xt_parse_match(r, m, "--state", "INVALID", 0); + fwd_xt_parse_match(r, m, "--state", "INVALID"); fwd_xt_get_target(r, "DROP"); fwd_xt_exec_rule(r, chain); } @@ -269,7 +76,7 @@ static void fwd_r_accept_related(struct iptc_handle *h, const char *chain) { if( (m = fwd_xt_get_match(r, "state")) != NULL ) { - fwd_xt_parse_match(r, m, "--state", "RELATED,ESTABLISHED", 0); + fwd_xt_parse_match(r, m, "--state", "RELATED,ESTABLISHED"); fwd_xt_get_target(r, "ACCEPT"); fwd_xt_exec_rule(r, chain); } @@ -320,17 +127,17 @@ static void fwd_r_add_synflood(struct iptc_handle *h, struct fwd_defaults *def) /* -m tcp --syn */ if( (m = fwd_xt_get_match(r, "tcp")) != NULL ) { - fwd_xt_parse_match(r, m, "--syn", NULL, 0); + fwd_xt_parse_match(r, m, "--syn"); } /* -m limit --limit x/second --limit-burst y */ if( (m = fwd_xt_get_match(r, "limit")) != NULL ) { sprintf(buf, "%i/second", def->syn_rate); - fwd_xt_parse_match(r, m, "--limit", buf, 0); + fwd_xt_parse_match(r, m, "--limit", buf); sprintf(buf, "%i", def->syn_burst); - fwd_xt_parse_match(r, m, "--limit-burst", buf, 0); + fwd_xt_parse_match(r, m, "--limit-burst", buf); } /* -j RETURN; -A syn_flood */ @@ -356,7 +163,7 @@ static void fwd_r_add_synflood(struct iptc_handle *h, struct fwd_defaults *def) /* -m tcp --syn */ if( (m = fwd_xt_get_match(r, "tcp")) != NULL ) { - fwd_xt_parse_match(r, m, "--syn", NULL, 0); + fwd_xt_parse_match(r, m, "--syn"); } /* -j syn_flood; -A INPUT */ @@ -385,7 +192,7 @@ static void fwd_r_handle_reject(struct iptc_handle *h) /* -j REJECT --reject-with tcp-reset */ if( (t = fwd_xt_get_target(r, "REJECT")) != NULL ) { - fwd_xt_parse_target(r, t, "--reject-with", "tcp-reset", 0); + fwd_xt_parse_target(r, t, "--reject-with", "tcp-reset"); } /* -A handle_reject */ @@ -399,7 +206,7 @@ static void fwd_r_handle_reject(struct iptc_handle *h) if( (t = fwd_xt_get_target(r, "REJECT")) != NULL ) { fwd_xt_parse_target(r, t, "--reject-with", - "icmp-port-unreachable", 0); + "icmp-port-unreachable"); } /* -A handle_reject */ @@ -441,6 +248,155 @@ static void fwd_r_handle_accept(struct iptc_handle *h) } } +/* add comment match */ +static void fwd_r_add_comment( + struct fwd_xt_rule *r, const char *t, struct fwd_zone *z, + struct fwd_network_list *n, struct fwd_network_list *n2 +) { + struct xtables_match *m; + char buf[256]; + + if( (m = fwd_xt_get_match(r, "comment")) != NULL ) + { + if( (n != NULL) && (n2 != NULL) ) + snprintf(buf, sizeof(buf), "%s:%s src:%s dest:%s", + t, z->name, n->name, n2->name); + else if( (n == NULL) && (n2 != NULL) ) + snprintf(buf, sizeof(buf), "%s:%s dest:%s", t, z->name, n2->name); + else + snprintf(buf, sizeof(buf), "%s:%s src:%s", t, z->name, n->name); + + fwd_xt_parse_match(r, m, "--comment", buf); + } +} + +/* add --sport (if applicable) */ +static void fwd_r_add_sport( + struct fwd_xt_rule *r, struct fwd_portrange *p +) { + int proto = r->entry->ip.proto; + char buf[12]; + struct xtables_match *m; + + /* have portrange and proto is tcp or udp ... */ + if( (p != NULL) && ((proto == 6) || (proto == 17)) ) + { + /* get match ... */ + if( (m = fwd_xt_get_match(r, (proto == 6) ? "tcp" : "udp")) != NULL ) + { + snprintf(buf, sizeof(buf), "%u:%u", p->min, p->max); + fwd_xt_parse_match(r, m, "--sport", buf); + } + } +} + +/* add --dport (if applicable) */ +static void fwd_r_add_dport( + struct fwd_xt_rule *r, struct fwd_portrange *p +) { + int proto = r->entry->ip.proto; + char buf[12]; + struct xtables_match *m; + + /* have portrange and proto is tcp or udp ... */ + if( (p != NULL) && ((proto == 6) || (proto == 17)) ) + { + /* get match ... */ + if( (m = fwd_xt_get_match(r, (proto == 6) ? "tcp" : "udp")) != NULL ) + { + snprintf(buf, sizeof(buf), "%u:%u", p->min, p->max); + fwd_xt_parse_match(r, m, "--dport", buf); + } + } +} + +/* add --icmp-type (of applicable) */ +static void fwd_r_add_icmptype( + struct fwd_xt_rule *r, struct fwd_icmptype *i +) { + int proto = r->entry->ip.proto; + struct xtables_match *m; + char buf[32]; + + /* have icmp-type and proto is icmp ... */ + if( (i != NULL) && (proto == 1) ) + { + /* get match ... */ + if( (m = fwd_xt_get_match(r, "icmp")) != NULL ) + { + if( i->name[0] ) + snprintf(buf, sizeof(buf), "%s", i->name); + else + snprintf(buf, sizeof(buf), "%u/%u", i->type, i->code); + + fwd_xt_parse_match(r, m, "--icmp-type", buf); + } + } +} + +/* add -m mac --mac-source ... */ +static void fwd_r_add_srcmac( + struct fwd_xt_rule *r, struct fwd_mac *mac +) { + struct xtables_match *m; + char buf[18]; + + if( mac != NULL ) + { + if( (m = fwd_xt_get_match(r, "mac")) != NULL ) + { + snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", + mac->mac[0], mac->mac[1], mac->mac[2], + mac->mac[3], mac->mac[4], mac->mac[5]); + + fwd_xt_parse_match(r, m, "--mac-source", buf); + } + } +} + +/* add policy target */ +static void fwd_r_add_policytarget( + struct fwd_xt_rule *r, enum fwd_policy pol +) { + switch(pol) + { + case FWD_P_ACCEPT: + fwd_xt_get_target(r, "handle_accept"); + break; + + case FWD_P_REJECT: + fwd_xt_get_target(r, "handle_reject"); + break; + + case FWD_P_DROP: + case FWD_P_UNSPEC: + fwd_xt_get_target(r, "handle_drop"); + break; + } +} + +/* add dnat target */ +static void fwd_r_add_dnattarget( + struct fwd_xt_rule *r, struct fwd_cidr *c, struct fwd_portrange *p +) { + struct xtables_target *t; + char buf[32]; + + if( c != NULL ) + { + if( (t = fwd_xt_get_target(r, "DNAT")) != NULL ) + { + if( p != NULL ) + snprintf(buf, sizeof(buf), "%s:%u-%u", + inet_ntoa(c->addr), p->min, p->max); + else + snprintf(buf, sizeof(buf), "%s", inet_ntoa(c->addr)); + + fwd_xt_parse_target(r, t, "--to-destination", buf); + } + } +} + static void fwd_ipt_defaults_create(struct fwd_data *d) { @@ -494,9 +450,10 @@ static void fwd_ipt_defaults_create(struct fwd_data *d) fwd_r_jump_chain(h_filter, "FORWARD", "forwardings"); fwd_r_new_chain(h_nat, "zonemasq"); fwd_r_new_chain(h_nat, "redirects"); + fwd_r_new_chain(h_nat, "loopback"); fwd_r_jump_chain(h_nat, "POSTROUTING", "zonemasq"); fwd_r_jump_chain(h_nat, "PREROUTING", "redirects"); - fwd_r_jump_chain(h_nat, "POSTROUTING", "redirects"); + fwd_r_jump_chain(h_nat, "POSTROUTING", "loopback"); /* standard drop, accept, reject chain */ fwd_r_handle_drop(h_filter); @@ -589,12 +546,22 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net) { struct fwd_data *e; struct fwd_zone *z; - struct fwd_ipt_rulebuf *b; struct fwd_rule *c; struct fwd_redirect *r; struct fwd_forwarding *f; struct fwd_addr_list *a, *a2; struct fwd_network_list *n, *n2; + struct fwd_proto p; + + struct fwd_xt_rule *x; + struct xtables_match *m; + struct xtables_target *t; + + 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"); + if( !(z = fwd_lookup_zone(h, net)) ) return; @@ -612,10 +579,13 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net) { printf("\n# Net %s (%s) - masq\n", n->name, n->ifname); - b = fwd_ipt_init("nat"); - fwd_ipt_add_format(b, " -A zonemasq -o %s -j MASQUERADE", n->ifname); - fwd_ipt_add_comment(b, "masq", z, NULL, n); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_nat)) != NULL ) + { + 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 */ + } } /* Build MSS fix rule */ @@ -623,12 +593,26 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net) { printf("\n# Net %s (%s) - mtu_fix\n", n->name, n->ifname); - b = fwd_ipt_init("filter"); - fwd_ipt_add_format(b, - " -A mssfix -o %s -p tcp --tcp-flags SYN,RST SYN" - " -j TCPMSS --clamp-mss-to-pmtu", n->ifname); - fwd_ipt_add_comment(b, "mssfix", z, NULL, n); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_filter)) != NULL ) + { + p.type = FWD_PR_TCP; + fwd_xt_parse_out(x, n, 0); /* -o ... */ + fwd_xt_parse_proto(x, &p, 0); /* -p tcp */ + + /* -m tcp --tcp-flags SYN,RST SYN */ + if( (m = fwd_xt_get_match(x, "tcp")) != NULL ) + fwd_xt_parse_match(x, m, "--tcp-flags", "SYN,RST", "SYN"); + + /* -j TCPMSS --clamp-mss-to-pmtu */ + if( (t = fwd_xt_get_target(x, "TCPMSS")) != NULL ) + fwd_xt_parse_target(x, t, "--clamp-mss-to-pmtu"); + + /* -m comment ... */ + fwd_r_add_comment(x, "mssfix", z, NULL, n); + + /* -A mssfix */ + fwd_xt_exec_rule(x, "mssfix"); + } } /* Build intra-zone forwarding rules */ @@ -641,12 +625,14 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net) n->name, n->ifname, z->name, n->name, n->ifname, z->name, n2->name, n2->ifname); - b = fwd_ipt_init("filter"); - fwd_ipt_add_format(b, " -A zones -i %s -o %s", - n->ifname, n2->ifname); - fwd_ipt_add_policy_target(b, z->forward); - fwd_ipt_add_comment(b, "zone", z, n, n2); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_filter)) != NULL ) + { + fwd_xt_parse_in(x, n, 0); /* -i ... */ + 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 */ + } } } @@ -661,12 +647,14 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net) f->dest->name, n2->name, n2->ifname); /* Build forwarding rule */ - b = fwd_ipt_init("filter"); - fwd_ipt_add_format(b, " -A forwardings -i %s -o %s", - n->ifname, n2->ifname); - fwd_ipt_add_policy_target(b, FWD_P_ACCEPT); - fwd_ipt_add_comment(b, "forward", z, n, n2); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_filter)) != NULL ) + { + fwd_xt_parse_in(x, n, 0); /* -i ... */ + 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 */ + } } } @@ -677,43 +665,49 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net) n->name, n->ifname, z->name, n->name, n->ifname); /* DNAT */ - b = fwd_ipt_init("nat"); - fwd_ipt_add_format(b, " -A redirects -i %s -d %s", - n->ifname, inet_ntoa(a->ipaddr.v4)); - fwd_ipt_add_proto(b, r->proto); - fwd_ipt_add_srcaddr(b, r->src_ip); - fwd_ipt_add_srcport(b, r->src_port); - fwd_ipt_add_destport(b, r->src_dport); - fwd_ipt_add_srcmac(b, r->src_mac); - fwd_ipt_add_dnat_target(b, r->dest_ip, r->dest_port); - fwd_ipt_add_comment(b, "redir", z, n, NULL); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_nat)) != NULL ) + { + fwd_xt_parse_in(x, n, 0); /* -i ... */ + fwd_xt_parse_src(x, r->src_ip, 0); /* -s ... */ + fwd_xt_parse_dest(x, &a->ipaddr, 0); /* -d ... */ + fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */ + fwd_r_add_sport(x, r->src_port); /* --sport ... */ + fwd_r_add_dport(x, r->src_dport); /* --dport ... */ + 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 */ + } /* Forward */ - b = fwd_ipt_init("filter"); - fwd_ipt_add_format(b, " -A redirects -i %s", n->ifname); - fwd_ipt_add_proto(b, r->proto); - fwd_ipt_add_srcmac(b, r->src_mac); - fwd_ipt_add_srcaddr(b, r->src_ip); - fwd_ipt_add_srcport(b, r->src_port); - fwd_ipt_add_destaddr(b, r->dest_ip); - fwd_ipt_add_destport(b, r->dest_port); - fwd_ipt_add_policy_target(b, FWD_P_ACCEPT); - fwd_ipt_add_comment(b, "redir", z, n, NULL); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_filter)) != NULL ) + { + fwd_xt_parse_in(x, n, 0); /* -i ... */ + fwd_xt_parse_src(x, r->src_ip, 0); /* -s ... */ + fwd_xt_parse_dest(x, r->dest_ip, 0); /* -d ... */ + fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */ + fwd_r_add_srcmac(x, r->src_mac); /* -m mac --mac-source ... */ + fwd_r_add_sport(x, r->src_port); /* --sport ... */ + 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 */ + } /* Add loopback rule if neither src_ip nor src_mac are defined */ if( !r->src_ip && !r->src_mac ) { - b = fwd_ipt_init("nat"); - fwd_ipt_add_format(b, " -A redirects -i ! %s -d %s", - n->ifname, inet_ntoa(r->dest_ip->addr)); - fwd_ipt_add_proto(b, r->proto); - fwd_ipt_add_srcport(b, r->src_port); - fwd_ipt_add_destport(b, r->src_dport); - fwd_ipt_add_format(b, " -j MASQUERADE"); - fwd_ipt_add_comment(b, "redir", z, n, NULL); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_nat)) != NULL ) + { + fwd_xt_parse_in(x, n, 1); /* -i ! ... */ + fwd_xt_parse_dest(x, r->dest_ip, 0); /* -d ... */ + fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */ + fwd_r_add_sport(x, r->src_port); /* --sport ... */ + 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 */ + } } } @@ -730,19 +724,21 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net) n->name, n->ifname, z->name, n->name, n->ifname, f->dest->name, n2->name, n2->ifname); - b = fwd_ipt_init("filter"); - fwd_ipt_add_format(b, " -A rules -i %s -o %s", - n->ifname, n2->ifname); - fwd_ipt_add_proto(b, c->proto); - fwd_ipt_add_icmptype(b, c->icmp_type); - fwd_ipt_add_srcmac(b, c->src_mac); - fwd_ipt_add_srcaddr(b, c->src_ip); - fwd_ipt_add_srcport(b, c->src_port); - fwd_ipt_add_destaddr(b, c->dest_ip); - fwd_ipt_add_destport(b, c->dest_port); - fwd_ipt_add_policy_target(b, c->target); - fwd_ipt_add_comment(b, "rule", z, n, n2); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_filter)) != NULL ) + { + fwd_xt_parse_in(x, n, 0); /* -i ... */ + fwd_xt_parse_out(x, n2, 0); /* -o ... */ + fwd_xt_parse_src(x, c->src_ip, 0); /* -s ... */ + fwd_xt_parse_dest(x, c->dest_ip, 0); /* -d ... */ + fwd_xt_parse_proto(x, c->proto, 0); /* -p ... */ + fwd_r_add_icmptype(x, c->icmp_type); /* --icmp-type ... */ + fwd_r_add_srcmac(x, c->src_mac); /* --mac-source ... */ + fwd_r_add_sport(x, c->src_port); /* --sport ... */ + 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 */ + } } } @@ -752,19 +748,30 @@ void fwd_ipt_addif(struct fwd_handle *h, const char *net) printf("\n# Net %s (%s) - rule Z:%s N:%s I:%s\n", n->name, n->ifname, z->name, n->name, n->ifname); - b = fwd_ipt_init("filter"); - fwd_ipt_add_format(b, " -A rules -i %s", n->ifname); - fwd_ipt_add_proto(b, c->proto); - fwd_ipt_add_icmptype(b, c->icmp_type); - fwd_ipt_add_srcmac(b, c->src_mac); - fwd_ipt_add_srcaddr(b, c->src_ip); - fwd_ipt_add_srcport(b, c->src_port); - fwd_ipt_add_destaddr(b, c->dest_ip); - fwd_ipt_add_destport(b, c->dest_port); - fwd_ipt_add_policy_target(b, c->target); - fwd_ipt_add_comment(b, "rule", z, n, n2); - fwd_ipt_exec(b); + if( (x = fwd_xt_init_rule(h_filter)) != NULL ) + { + fwd_xt_parse_in(x, n, 0); /* -i ... */ + fwd_xt_parse_src(x, c->src_ip, 0); /* -s ... */ + fwd_xt_parse_dest(x, c->dest_ip, 0); /* -d ... */ + fwd_xt_parse_proto(x, c->proto, 0); /* -p ... */ + fwd_r_add_icmptype(x, c->icmp_type); /* --icmp-type ... */ + fwd_r_add_srcmac(x, c->src_mac); /* --mac-source ... */ + fwd_r_add_sport(x, c->src_port); /* --sport ... */ + 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 */ + } } } + + 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); } |