Add support for device and direction parameters
[project/firewall3.git] / snats.c
diff --git a/snats.c b/snats.c
index 11bcc068390661e0cc68f0324abbc5de4e928267..1e0119265e6ddb896f0da68b2ab043c27dd1e3c3 100644 (file)
--- a/snats.c
+++ b/snats.c
@@ -26,6 +26,7 @@ const struct fw3_option fw3_snat_opts[] = {
        FW3_OPT("family",              family,    snat,     family),
 
        FW3_OPT("src",                 device,    snat,     src),
+       FW3_OPT("device",              string,    snat,     device),
 
        FW3_OPT("ipset",               setmatch,  snat,     ipset),
 
@@ -45,6 +46,8 @@ const struct fw3_option fw3_snat_opts[] = {
        FW3_OPT("limit",               limit,     snat,     limit),
        FW3_OPT("limit_burst",         int,       snat,     limit.burst),
 
+       FW3_OPT("connlimit_ports",     bool,      snat,     connlimit_ports),
+
        FW3_OPT("utc_time",            bool,      snat,     time.utc),
        FW3_OPT("start_date",          date,      snat,     time.datestart),
        FW3_OPT("stop_date",           date,      snat,     time.datestop),
@@ -247,13 +250,23 @@ set_target(struct fw3_ipt_rule *r, struct fw3_snat *snat,
                }
 
                if (snat->port_snat.set && proto && !proto->any &&
-                   (proto->protocol == 6 || proto->protocol == 17))
+                   (proto->protocol == 6 || proto->protocol == 17 || proto->protocol == 1))
                {
                        if (snat->port_snat.port_min == snat->port_snat.port_max)
                                sprintf(buf + strlen(buf), ":%u", snat->port_snat.port_min);
                        else
                                sprintf(buf + strlen(buf), ":%u-%u",
                                                snat->port_snat.port_min, snat->port_snat.port_max);
+
+                       if (snat->connlimit_ports) {
+                               char portcntbuf[6];
+                               snprintf(portcntbuf, sizeof(portcntbuf), "%u",
+                                               1 + snat->port_snat.port_max - snat->port_snat.port_min);
+
+                               fw3_ipt_rule_addarg(r, false, "-m", "connlimit");
+                               fw3_ipt_rule_addarg(r, false, "--connlimit-daddr", NULL);
+                               fw3_ipt_rule_addarg(r, false, "--connlimit-upto", portcntbuf);
+                       }
                }
 
                fw3_ipt_rule_target(r, "SNAT");
@@ -296,6 +309,7 @@ print_snat(struct fw3_ipt_handle *h, struct fw3_state *state,
 
                r = fw3_ipt_rule_create(h, proto, NULL, NULL, src, dst);
                fw3_ipt_rule_sport_dport(r, spt, dpt);
+               fw3_ipt_rule_device(r, snat->device, true);
                fw3_ipt_rule_ipset(r, &snat->ipset);
                fw3_ipt_rule_limit(r, &snat->limit);
                fw3_ipt_rule_time(r, &snat->time);