4 Copyright (C) 2006-2009 Jonathan Zarate
10 #include <arpa/inet.h>
12 extern char chain_wan_prerouting
[];
14 static const char tcpudp
[2][4] = {"tcp", "udp"};
16 void ipt_forward(ipt_table_t table
)
19 const char *proto
, *saddr
, *xports
, *iport
, *iaddr
, *desc
;
26 nvp
= nv
= strdup(nvram_safe_get("portforward"));
29 while ((b
= strsep(&nvp
, ">")) != NULL
) {
31 [<1.01] 1<3<30,40-45<60<5<desc
32 [<1.07] 1<3<30,40-45<60<192.168.1.5<desc
34 1<3<71.72.73.74<30,40-45<60<192.168.1.5<desc
38 71.72.73.74 = src addr
41 192.168.1.5 = dst addr
45 n
= vstrsep(b
, "<", &c
, &proto
, &saddr
, &xports
, &iport
, &iaddr
, &desc
);
46 if ((n
< 6) || (*c
!= '1')) continue;
56 if (!ipt_addr(src
, sizeof(src
), saddr
, "src", IPT_V4
, 1, "IPv4 port forwarding", desc
))
59 if (strchr(iaddr
, '.') == NULL
&& strtol(iaddr
, NULL
, 10) > 0) {
60 // < 1.01: 5 -> 192.168.1.5
61 strcpy(ip
, lan_cclass
);
62 strlcat(ip
, iaddr
, sizeof(ip
));
65 if (host_addrtypes(iaddr
, IPT_V4
) != IPT_V4
) {
66 ipt_log_unresolved(iaddr
, "IPv4", "IPv4 port forwarding", desc
);
69 strlcpy(ip
, iaddr
, sizeof(ip
));
72 mdport
= (strchr(xports
, ',') != NULL
) ? "-m multiport --dports" : "--dport";
73 for (i
= 0; i
< 2; ++i
) {
74 if ((1 << i
) & (*proto
- '0')) {
76 if (table
== IPT_TABLE_NAT
) {
77 ipt_write("-A %s -p %s %s %s %s -j DNAT --to-destination %s%s%s\n",
82 ip
, *iport
? ":" : "", iport
);
84 if (nvram_get_int("nf_loopback") == 1) {
85 for (n
= 0; n
< wanfaces
.count
; ++n
) {
86 if (*(wanfaces
.iface
[n
].name
)) {
87 ipt_write("-A POSTROUTING -p %s %s %s -s %s/%s -d %s -j SNAT --to-source %s\n",
89 mdport
, *iport
? iport
: xports
,
90 nvram_safe_get("lan_ipaddr"), // corrected by ipt
91 nvram_safe_get("lan_netmask"),
93 wanfaces
.iface
[n
].ip
);
99 ipt_write("-A wanin %s -p %s -m %s -d %s %s %s -j %s\n",
104 mdport
, *iport
? iport
: xports
,
113 void ipt_triggered(ipt_table_t table
)
116 const char *proto
, *mports
, *fports
;
123 nvp
= nv
= strdup(nvram_safe_get("trigforward"));
127 while ((b
= strsep(&nvp
, ">")) != NULL
) {
128 if ((vstrsep(b
, "<", &c
, &proto
, &mports
, &fports
) != 4) || (*c
!= '1')) continue;
129 for (i
= 0; i
< 2; ++i
) {
130 if ((1 << i
) & (*proto
- '0')) {
132 // should only be created if there is at least one enabled
134 if (table
== IPT_TABLE_NAT
) {
135 ipt_write("-A %s -j TRIGGER --trigger-type dnat\n", chain_wan_prerouting
);
139 ipt_write(":triggers - [0:0]\n"
140 "-A wanout -j triggers\n"
141 "-A wanin -j TRIGGER --trigger-type in\n");
145 strlcpy(s
, mports
, sizeof(s
));
146 if ((p
= strchr(s
, ':')) != NULL
) *p
= '-';
147 if ((p
= strchr(fports
, ':')) != NULL
) *p
= '-';
149 ipt_write("-A triggers -p %s -m %s --dport %s "
150 "-j TRIGGER --trigger-type out --trigger-proto %s --trigger-match %s --trigger-relate %s\n",
153 // can't use multiport... trigger-match must be set to the same
154 // ports as dport since it's used to refresh timer during inbound -- zzz
164 void ip6t_forward(void)
167 const char *proto
, *saddr
, *daddr
, *dports
, *desc
;
173 nvp
= nv
= strdup(nvram_safe_get("ipv6_portforward"));
176 while ((b
= strsep(&nvp
, ">")) != NULL
) {
178 1<3<2001:23:45:67::/64<2600:abc:def:123::1<30,40-45<desc
182 2001:23:45:67::/64 = src addr
183 2600:abc:def:123::1 = dst addr (optional)
187 if ((vstrsep(b
, "<", &c
, &proto
, &saddr
, &daddr
, &dports
, &desc
) != 6) || (*c
!= '1')) continue;
189 if (!ipt_addr(src
, sizeof(src
), saddr
, "src", IPT_V6
, 1, "IPv6 port forwarding", desc
))
192 if ((*daddr
) && (host_addrtypes(daddr
, IPT_V6
) != IPT_V6
)) {
193 ipt_log_unresolved(daddr
, "IPv6", "IPv6 port forwarding", desc
);
197 mdport
= (strchr(dports
, ',') != NULL
) ? "-m multiport --dports" : "--dport";
198 for (i
= 0; i
< 2; ++i
) {
199 if ((1 << i
) & (*proto
- '0')) {
201 ip6t_write("-A wanin %s -p %s -m %s %s%s %s %s -j %s\n",
205 (*daddr
) ? "-d " : "", daddr
,