TomatoVPN 1.27vpn3.6 release
[tomato.git] / release / src / router / rc / forward.c
blob4965dc951d9148c33f7885192653e351b39e4bb8
1 /*
3 Tomato Firmware
4 Copyright (C) 2006-2009 Jonathan Zarate
6 */
8 #include "rc.h"
10 #include <arpa/inet.h>
13 static const char tcpudp[2][4] = {"tcp", "udp"};
15 void ipt_forward(ipt_table_t table)
17 char *nv, *nvp, *b;
18 const char *proto, *saddr, *xports, *iport, *iaddr;
19 const char *c;
20 const char *mdport;
21 int i;
22 char ip[64];
23 char src[64];
25 nvp = nv = strdup(nvram_safe_get("portforward"));
26 if (!nv) return;
28 while ((b = strsep(&nvp, ">")) != NULL) {
30 [<1.01] 1<3<30,40-45<60<5<desc
31 [<1.07] 1<3<30,40-45<60<192.168.1.5<desc
33 1<3<71.72.73.74<30,40-45<60<192.168.1.5<desc
35 1 = enabled
36 3 = tcp & udp
37 71.72.73.74 = src addr
38 30,40-45 = ext port
39 60 = int port
40 192.168.1.5 = dst addr
41 desc = desc
44 if ((vstrsep(b, "<", &c, &proto, &saddr, &xports, &iport, &iaddr) != 6) || (*c != '1')) continue;
46 src[0] = 0;
47 if (*saddr != 0) {
48 if (strchr(saddr, '.') == NULL) {
49 // <1.07
50 iaddr = iport;
51 iport = xports;
52 xports = saddr;
53 saddr = "";
55 else if (strlen(saddr) < 32) {
56 sprintf(src, "-%s %s", strchr(saddr, '-') ? "m iprange --src-range" : "s", saddr);
60 mdport = (strchr(xports, ',') != NULL) ? "-m mport --dports" : "--dport";
61 for (i = 0; i < 2; ++i) {
62 if ((1 << i) & (*proto - '0')) {
63 c = tcpudp[i];
64 if (strchr(iaddr, '.')) {
65 strlcpy(ip, iaddr, sizeof(ip));
67 else {
68 // < 1.01: 5 -> 192.168.1.5
69 strcpy(ip, lan_cclass);
70 strlcat(ip, iaddr, sizeof(ip));
72 if (table == IPT_TABLE_NAT) {
73 ipt_write("-A PREROUTING -p %s %s -d %s %s %s -j DNAT --to-destination %s%s%s\n",
75 src,
76 wanaddr,
77 mdport, xports,
78 ip, *iport ? ":" : "", iport);
80 if (nvram_get_int("nf_loopback") == 1) {
81 ipt_write("-A POSTROUTING -p %s %s %s -s %s/%s -d %s -j SNAT --to-source %s\n",
83 mdport, *iport ? iport : xports,
84 nvram_safe_get("lan_ipaddr"), // corrected by ipt
85 nvram_safe_get("lan_netmask"),
86 ip,
87 nvram_safe_get("wan_ipaddr"));
90 else { // filter
91 ipt_write("-A wanin %s -p %s -m %s -d %s %s %s -j %s\n",
92 src,
95 ip,
96 mdport, *iport ? iport : xports,
97 chain_in_accept);
102 free(nv);
106 void ipt_triggered(ipt_table_t table)
108 char *nv, *nvp, *b;
109 const char *proto, *mports, *fports;
110 const char *c;
111 char *p;
112 int i;
113 int first;
114 char s[256];
116 nvp = nv = strdup(nvram_safe_get("trigforward"));
117 if (!nv) return;
119 first = 1;
120 while ((b = strsep(&nvp, ">")) != NULL) {
121 if ((vstrsep(b, "<", &c, &proto, &mports, &fports) != 4) || (*c != '1')) continue;
122 for (i = 0; i < 2; ++i) {
123 if ((1 << i) & (*proto - '0')) {
124 if (first) {
125 // should only be created if there is at least one enabled
127 if (table == IPT_TABLE_NAT) {
128 ipt_write("-A PREROUTING -d %s -j TRIGGER --trigger-type dnat\n", wanaddr);
129 goto QUIT;
132 ipt_write(":triggers - [0:0]\n"
133 "-A wanout -j triggers\n"
134 "-A wanin -j TRIGGER --trigger-type in\n");
136 first = 0;
138 strlcpy(s, mports, sizeof(s));
139 if ((p = strchr(s, ':')) != NULL) *p = '-';
140 if ((p = strchr(fports, ':')) != NULL) *p = '-';
141 c = tcpudp[i];
142 ipt_write("-A triggers -p %s -m %s --dport %s "
143 "-j TRIGGER --trigger-type out --trigger-proto %s --trigger-match %s --trigger-relate %s\n",
144 c, c, mports,
145 c, s, fports);
146 // can't use mport... trigger-match must be set to the same
147 // ports as dport since it's used to refresh timer during inbound -- zzz
152 QUIT:
153 free(nv);