Merge branch 'tomato-shibby' into tomato-shibby-RT-N
[tomato.git] / release / src / router / rc / firewall.c
blob914e85b2859730c4f8ea0998d122bb186f74c9f5
1 /*
3 Copyright 2003-2005, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Modified for Tomato Firmware
22 Portions, Copyright (C) 2006-2009 Jonathan Zarate
26 #include "rc.h"
28 #include <stdarg.h>
29 #include <arpa/inet.h>
30 #include <dirent.h>
32 static int web_lanport;
33 wanface_list_t wanfaces;
34 char lanface[IFNAMSIZ + 1];
35 char lan1face[IFNAMSIZ + 1];
36 char lan2face[IFNAMSIZ + 1];
37 char lan3face[IFNAMSIZ + 1];
38 #ifdef TCONFIG_IPV6
39 char wan6face[IFNAMSIZ + 1];
40 #endif
41 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
42 #ifdef LINUX26
43 static int can_enable_fastnat;
44 #endif
46 #ifdef DEBUG_IPTFILE
47 static int debug_only = 0;
48 #endif
50 static int gateway_mode;
51 static int remotemanage;
52 static int wanup;
54 const char *chain_in_drop;
55 const char *chain_in_accept;
56 const char *chain_out_drop;
57 const char *chain_out_accept;
58 const char *chain_out_reject;
60 const char chain_wan_prerouting[] = "WANPREROUTING";
61 const char ipt_fname[] = "/etc/iptables";
62 FILE *ipt_file;
64 #ifdef TCONFIG_IPV6
65 const char ip6t_fname[] = "/etc/ip6tables";
66 FILE *ip6t_file;
68 // RFC-4890, sec. 4.3.1
69 const int allowed_icmpv6[] = { 1, 2, 3, 4, 128, 129 };
70 #endif
72 static int is_sta(int idx, int unit, int subunit, void *param)
74 return (nvram_match(wl_nvname("mode", unit, subunit), "sta") && (nvram_match(wl_nvname("bss_enabled", unit, subunit), "1")));
78 struct {
79 } firewall_data;
82 // -----------------------------------------------------------------------------
84 #ifdef LINUX26
85 static const char *fastnat_run_dir = "/var/run/fastnat";
87 void allow_fastnat(const char *service, int allow)
89 char p[128];
91 snprintf(p, sizeof(p), "%s/%s", fastnat_run_dir, service);
92 if (allow) {
93 unlink(p);
95 else {
96 mkdir_if_none(fastnat_run_dir);
97 f_write_string(p, "", 0, 0);
101 static inline int fastnat_allowed(void)
103 DIR *dir;
104 struct dirent *dp;
105 int enabled;
107 enabled = !nvram_get_int("qos_enable") && !nvram_get_int("fastnat_disable");
109 if (enabled && (dir = opendir(fastnat_run_dir))) {
110 while ((dp = readdir(dir))) {
111 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
112 continue;
113 enabled = 0;
114 break;
116 closedir(dir);
119 return (enabled);
122 void try_enabling_fastnat(void)
124 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_fastnat",
125 fastnat_allowed() ? "1" : "0", 0, 0);
127 #endif
129 void enable_ip_forward(void)
132 ip_forward - BOOLEAN
133 0 - disabled (default)
134 not 0 - enabled
136 Forward Packets between interfaces.
138 This variable is special, its change resets all configuration
139 parameters to their default state (RFC1122 for hosts, RFC1812
140 for routers)
142 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
146 #ifdef TCONFIG_IPV6
147 void enable_ip6_forward(void)
149 if (ipv6_enabled()) {
150 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
151 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
153 else {
154 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "0", 0, 0);
155 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "0", 0, 0);
158 #endif
161 // -----------------------------------------------------------------------------
164 static int ip2cclass(char *ipaddr, char *new, int count)
166 int ip[4];
168 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
169 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
174 static int dmz_dst(char *s)
176 struct in_addr ia;
177 char *p;
178 int n;
180 if (nvram_get_int("dmz_enable") <= 0) return 0;
182 p = nvram_safe_get("dmz_ipaddr");
183 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
184 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
185 if (s) sprintf(s, "%s%d", lan_cclass, n);
186 return 1;
189 if (s) strcpy(s, inet_ntoa(ia));
190 return 1;
193 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
195 char *pre, *post;
197 pre = (name && *name) ? " for \"" : "";
198 post = (name && *name) ? "\"" : "";
200 syslog(LOG_WARNING, "firewall: "
201 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
202 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
205 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
206 int strict, const char *categ, const char *name)
208 char p[INET6_ADDRSTRLEN * 2];
209 int r = 0;
211 if ((s) && (*s) && (*dir))
213 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
214 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
215 r = IPT_V4;
217 #ifdef TCONFIG_IPV6
218 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
219 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
220 r = IPT_V6;
222 #endif
223 else {
224 snprintf(addr, maxlen, "-%c %s", dir[0], s);
225 if (sscanf(s, "%[^/]/", p)) {
226 #ifdef TCONFIG_IPV6
227 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
228 #else
229 r = host_addrtypes(p, IPT_V4);
230 #endif
234 else
236 *addr = 0;
237 r = (IPT_V4 | IPT_V6);
240 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
241 ipt_log_unresolved(s, categ, name,
242 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
245 return (r & af);
248 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
249 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
250 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
253 static void get_src(const char *nv, char *src)
255 char *p;
257 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
258 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
260 else {
261 *src = 0;
266 void ipt_write(const char *format, ...)
268 va_list args;
270 va_start(args, format);
271 vfprintf(ipt_file, format, args);
272 va_end(args);
275 void ip6t_write(const char *format, ...)
277 #ifdef TCONFIG_IPV6
278 va_list args;
280 va_start(args, format);
281 vfprintf(ip6t_file, format, args);
282 va_end(args);
283 #endif
286 // -----------------------------------------------------------------------------
288 int ipt_dscp(const char *v, char *opt)
290 unsigned int n;
292 if (*v == 0) {
293 *opt = 0;
294 return 0;
297 n = strtoul(v, NULL, 0);
298 if (n > 63) n = 63;
299 sprintf(opt, " -m dscp --dscp 0x%02X", n);
301 #ifdef LINUX26
302 modprobe("xt_dscp");
303 #else
304 modprobe("ipt_dscp");
305 #endif
306 return 1;
309 // -----------------------------------------------------------------------------
312 int ipt_ipp2p(const char *v, char *opt)
314 int n = atoi(v);
316 if (n == 0) {
317 *opt = 0;
318 return 0;
321 strcpy(opt, "-m ipp2p ");
322 if ((n & 0xFFF) == 0xFFF) {
323 strcat(opt, "--ipp2p");
325 else {
326 // x12
327 if (n & 0x0001) strcat(opt, "--apple ");
328 if (n & 0x0002) strcat(opt, "--ares ");
329 if (n & 0x0004) strcat(opt, "--bit ");
330 if (n & 0x0008) strcat(opt, "--dc ");
331 if (n & 0x0010) strcat(opt, "--edk ");
332 if (n & 0x0020) strcat(opt, "--gnu ");
333 if (n & 0x0040) strcat(opt, "--kazaa ");
334 if (n & 0x0080) strcat(opt, "--mute ");
335 if (n & 0x0100) strcat(opt, "--soul ");
336 if (n & 0x0200) strcat(opt, "--waste ");
337 if (n & 0x0400) strcat(opt, "--winmx ");
338 if (n & 0x0800) strcat(opt, "--xdcc ");
339 #ifdef LINUX26
340 if (n & 0x1000) strcat(opt, "--pp ");
341 if (n & 0x2000) strcat(opt, "--xunlei ");
342 #endif
345 modprobe("ipt_ipp2p");
346 return 1;
350 // -----------------------------------------------------------------------------
353 char **layer7_in;
355 // This L7 matches inbound traffic, caches the results, then the L7 outbound
356 // should read the cached result and set the appropriate marks -- zzz
357 void ipt_layer7_inbound(void)
359 int en, i;
360 char **p;
362 if (!layer7_in) return;
364 en = nvram_match("nf_l7in", "1");
365 if (en) {
366 ipt_write(":L7in - [0:0]\n");
367 for (i = 0; i < wanfaces.count; ++i) {
368 if (*(wanfaces.iface[i].name)) {
369 ipt_write("-A FORWARD -i %s -j L7in\n",
370 wanfaces.iface[i].name);
375 p = layer7_in;
376 while (*p) {
377 if (en) {
378 ipt_write("-A L7in %s -j RETURN\n", *p);
379 #ifdef LINUX26
380 can_enable_fastnat = 0;
381 #endif
383 free(*p);
384 ++p;
386 free(layer7_in);
387 layer7_in = NULL;
390 int ipt_layer7(const char *v, char *opt)
392 char s[128];
393 char *path;
395 *opt = 0;
396 if (*v == 0) return 0;
397 if (strlen(v) > 32) return -1;
399 path = "/etc/l7-extra";
400 sprintf(s, "%s/%s.pat", path, v);
401 if (!f_exists(s)) {
402 path = "/etc/l7-protocols";
403 sprintf(s, "%s/%s.pat", path, v);
404 if (!f_exists(s)) {
405 syslog(LOG_ERR, "L7 %s was not found", v);
406 return -1;
410 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
412 if (nvram_match("nf_l7in", "1")) {
413 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
414 if (layer7_in) {
415 char **p;
417 p = layer7_in;
418 while (*p) {
419 if (strcmp(*p, opt) == 0) return 1;
420 ++p;
422 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
426 #ifdef LINUX26
427 modprobe("xt_layer7");
428 #else
429 modprobe("ipt_layer7");
430 #endif
431 return 1;
434 // -----------------------------------------------------------------------------
436 static void ipt_account(void) {
437 struct in_addr ipaddr, netmask, network;
438 char lanN_ifname[] = "lanXX_ifname";
439 char lanN_ipaddr[] = "lanXX_ipaddr";
440 char lanN_netmask[] = "lanXX_netmask";
441 char lanN[] = "lanXX";
442 char netaddrnetmask[] = "255.255.255.255/255.255.255.255 ";
443 char br;
445 for(br=0 ; br<=3 ; br++) {
446 char bridge[2] = "0";
447 if (br!=0)
448 bridge[0]+=br;
449 else
450 strcpy(bridge, "");
452 sprintf(lanN_ifname, "lan%s_ifname", bridge);
454 if (strcmp(nvram_safe_get(lanN_ifname), "")!=0) {
456 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
457 sprintf(lanN_netmask, "lan%s_netmask", bridge);
458 sprintf(lanN, "lan%s", bridge);
460 inet_aton(nvram_safe_get(lanN_ipaddr), &ipaddr);
461 inet_aton(nvram_safe_get(lanN_netmask), &netmask);
463 // bitwise AND of ip and netmask gives the network
464 network.s_addr = ipaddr.s_addr & netmask.s_addr;
466 sprintf(netaddrnetmask, "%s/%s", inet_ntoa(network), nvram_safe_get(lanN_netmask));
468 //ipv4 only
469 ipt_write("-A FORWARD -m account --aaddr %s --aname %s\n", netaddrnetmask, lanN);
474 // -----------------------------------------------------------------------------
476 static void save_webmon(void)
478 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
479 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
482 static void ipt_webmon()
484 int wmtype, clear, i;
485 char t[512];
486 char src[128];
487 char *p, *c;
488 int ok;
490 if (!nvram_get_int("log_wm")) return;
492 #ifdef LINUX26
493 can_enable_fastnat = 0;
494 #endif
495 wmtype = nvram_get_int("log_wmtype");
496 clear = nvram_get_int("log_wmclear");
498 ip46t_write(":monitor - [0:0]\n");
500 // include IPs
501 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
502 p = t;
503 do {
504 if ((c = strchr(p, ',')) != NULL) *c = 0;
506 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
507 #ifdef TCONFIG_IPV6
508 if (*wan6face && (ok & IPT_V6))
509 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
510 #endif
511 if (ok & IPT_V4) {
512 for (i = 0; i < wanfaces.count; ++i) {
513 if (*(wanfaces.iface[i].name)) {
514 ipt_write("-A FORWARD -o %s %s -j monitor\n",
515 wanfaces.iface[i].name, src);
521 if (!c) break;
522 p = c + 1;
523 } while (*p);
525 // exclude IPs
526 if (wmtype == 2) {
527 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
528 p = t;
529 do {
530 if ((c = strchr(p, ',')) != NULL) *c = 0;
531 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
532 if (*src)
533 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
535 if (!c) break;
536 p = c + 1;
537 } while (*p);
540 char webdomain[100];
541 char websearch[100];
543 if( nvram_match( "webmon_bkp", "1" ) ) {
544 xstart( "/usr/sbin/webmon_bkp", "add" ); // add jobs to cru
546 sprintf(webdomain, "--domain_load_file %s/webmon_recent_domains", nvram_safe_get("webmon_dir"));
547 sprintf(websearch, "--search_load_file %s/webmon_recent_searches", nvram_safe_get("webmon_dir"));
548 } else {
549 sprintf(webdomain, "--domain_load_file /var/webmon/domain");
550 sprintf(websearch, "--search_load_file /var/webmon/search");
553 ip46t_write(
554 "-A monitor -p tcp -m webmon "
555 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
556 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
557 (clear & 1) == 0 ? webdomain : "--clear_domain",
558 (clear & 2) == 0 ? websearch : "--clear_search");
560 if( nvram_match( "webmon_bkp", "1" ) )
561 xstart( "/usr/sbin/webmon_bkp", "hourly" ); // make a copy immediately
564 #ifdef LINUX26
565 modprobe("xt_webmon");
566 #else
567 modprobe("ipt_webmon");
568 #endif
573 // -----------------------------------------------------------------------------
574 // MANGLE
575 // -----------------------------------------------------------------------------
577 static void mangle_table(void)
579 int ttl;
580 char *p, *wanface;
582 ip46t_write(
583 "*mangle\n"
584 ":PREROUTING ACCEPT [0:0]\n"
585 ":OUTPUT ACCEPT [0:0]\n");
587 if (wanup) {
589 ipt_qos();
590 //1 for mangle
591 ipt_qoslimit(1);
593 p = nvram_safe_get("nf_ttl");
594 if (strncmp(p, "c:", 2) == 0) {
595 p += 2;
596 ttl = atoi(p);
597 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
599 else if ((ttl = atoi(p)) != 0) {
600 if (ttl > 0) {
601 p = "inc";
603 else {
604 ttl = -ttl;
605 p = "dec";
607 if (ttl > 255) p = NULL;
609 else p = NULL;
611 if (p) {
612 #ifdef LINUX26
613 modprobe("xt_HL");
614 #else
615 modprobe("ipt_TTL");
616 #endif
617 // set TTL on primary WAN iface only
618 wanface = wanfaces.iface[0].name;
619 ipt_write(
620 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
621 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
622 wanface, p, ttl,
623 wanface, p, ttl);
624 #ifdef TCONFIG_IPV6
625 // FIXME: IPv6 HL should be configurable separately from TTL.
626 // disable it until GUI setting is implemented.
627 #if 0
628 ip6t_write(
629 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
630 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
631 wan6face, p, ttl,
632 wan6face, p, ttl);
633 #endif
634 #endif
638 ip46t_write("COMMIT\n");
641 // -----------------------------------------------------------------------------
642 // NAT
643 // -----------------------------------------------------------------------------
645 static void nat_table(void)
647 char lanaddr[32];
648 char lanmask[32];
649 char lan1addr[32];
650 char lan1mask[32];
651 char lan2addr[32];
652 char lan2mask[32];
653 char lan3addr[32];
654 char lan3mask[32];
655 char dst[64];
656 char src[64];
657 char t[512];
658 char *p, *c;
659 int i;
661 ipt_write("*nat\n"
662 ":PREROUTING ACCEPT [0:0]\n"
663 ":POSTROUTING ACCEPT [0:0]\n"
664 ":OUTPUT ACCEPT [0:0]\n"
665 ":%s - [0:0]\n",
666 chain_wan_prerouting);
668 //2 for nat
669 ipt_qoslimit(2);
671 if (gateway_mode) {
672 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
673 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
674 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
675 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
676 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
677 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
678 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
679 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
682 for (i = 0; i < wanfaces.count; ++i) {
683 if (*(wanfaces.iface[i].name)) {
684 // chain_wan_prerouting
685 if (wanup) {
686 ipt_write("-A PREROUTING -d %s -j %s\n",
687 wanfaces.iface[i].ip, chain_wan_prerouting);
690 // Drop incoming packets which destination IP address is to our LAN side directly
691 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
692 wanfaces.iface[i].name,
693 lanaddr, lanmask); // note: ipt will correct lanaddr
694 if(strcmp(lan1addr,"")!=0)
695 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
696 wanfaces.iface[i].name,
697 lan1addr, lan1mask);
698 if(strcmp(lan2addr,"")!=0)
699 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
700 wanfaces.iface[i].name,
701 lan2addr, lan2mask);
702 if(strcmp(lan3addr,"")!=0)
703 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
704 wanfaces.iface[i].name,
705 lan3addr, lan3mask);
709 if (wanup) {
710 if (nvram_match("dns_intcpt", "1")) {
711 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
712 lanaddr, lanmask,
713 lanaddr, lanmask,
714 lanaddr);
715 if(strcmp(lan1addr,"")!=0)
716 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
717 lan1addr, lan1mask,
718 lan1addr, lan1mask,
719 lan1addr);
720 if(strcmp(lan2addr,"")!=0)
721 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
722 lan2addr, lan2mask,
723 lan2addr, lan2mask,
724 lan2addr);
725 if(strcmp(lan3addr,"")!=0)
726 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
727 lan3addr, lan3mask,
728 lan3addr, lan3mask,
729 lan3addr);
732 // ICMP packets are always redirected to INPUT chains
733 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
736 //force remote access to router if DMZ is enabled - shibby
737 if( (nvram_match("dmz_enable", "1")) && (nvram_match("dmz_ra", "1")) ) {
738 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
739 p = t;
740 do {
741 if ((c = strchr(p, ',')) != NULL) *c = 0;
742 ipt_source(p, src, "ra", NULL);
744 if (remotemanage) {
745 ipt_write("-A %s -p tcp -m tcp %s --dport %s -j DNAT --to-destination %s:%d\n",
746 chain_wan_prerouting, src, nvram_safe_get("http_wanport"), lanaddr, web_lanport);
749 if (nvram_get_int("sshd_remote")) {
750 ipt_write("-A %s %s -p tcp -m tcp --dport %s -j DNAT --to-destination %s:%s\n",
751 chain_wan_prerouting, src, nvram_safe_get("sshd_rport"), lanaddr, nvram_safe_get("sshd_port"));
754 if (!c) break;
755 p = c + 1;
756 } while (*p);
760 ipt_forward(IPT_TABLE_NAT);
761 ipt_triggered(IPT_TABLE_NAT);
764 if (nvram_get_int("upnp_enable") & 3) {
765 ipt_write(":upnp - [0:0]\n");
767 for (i = 0; i < wanfaces.count; ++i) {
768 if (*(wanfaces.iface[i].name)) {
769 if (wanup) {
770 // ! for loopback (all) to work
771 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces.iface[i].ip);
773 else {
774 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
780 #ifdef TCONFIG_TOR
781 //TOR
782 if (nvram_match("tor_enable", "1")) {
783 if (nvram_match("tor_iface", "br0")) {
784 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
785 nvram_safe_get("tor_iface"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("tor_transport") );
786 } else if (nvram_match("tor_iface", "br1")) {
787 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
788 nvram_safe_get("tor_iface"), nvram_safe_get("lan1_ipaddr"), nvram_safe_get("lan1_ipaddr"), nvram_safe_get("tor_transport") );
789 } else if (nvram_match("tor_iface", "br2")) {
790 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
791 nvram_safe_get("tor_iface"), nvram_safe_get("lan2_ipaddr"), nvram_safe_get("lan2_ipaddr"), nvram_safe_get("tor_transport") );
792 } else if (nvram_match("tor_iface", "br3")) {
793 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
794 nvram_safe_get("tor_iface"), nvram_safe_get("lan3_ipaddr"), nvram_safe_get("lan3_ipaddr"), nvram_safe_get("tor_transport") );
795 } else {
796 strlcpy(t, nvram_safe_get("tor_users"), sizeof(t));
797 p = t;
798 do {
799 if ((c = strchr(p, ',')) != NULL) *c = 0;
801 if (ipt_source_strict(p, src, "tor", NULL))
802 ipt_write("-A PREROUTING %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
803 src, nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("tor_transport") );
805 if (!c) break;
806 p = c + 1;
807 } while (*p);
810 #endif
812 if (wanup) {
813 if (dmz_dst(dst)) {
814 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
815 p = t;
816 do {
817 if ((c = strchr(p, ',')) != NULL) *c = 0;
818 if (ipt_source_strict(p, src, "dmz", NULL))
819 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
820 if (!c) break;
821 p = c + 1;
822 } while (*p);
826 p = "";
827 #ifdef TCONFIG_IPV6
828 switch (get_ipv6_service()) {
829 case IPV6_6IN4:
830 // avoid NATing proto-41 packets when using 6in4 tunnel
831 p = "-p ! 41";
832 break;
834 #endif
836 for (i = 0; i < wanfaces.count; ++i) {
837 if (*(wanfaces.iface[i].name)) {
838 if ((!wanup) || (nvram_get_int("ne_snat") != 1))
839 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
840 else
841 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
845 char *modem_ipaddr;
846 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
847 && (modem_ipaddr = nvram_safe_get("modem_ipaddr")) && *modem_ipaddr && !nvram_match("modem_ipaddr","0.0.0.0")
848 && (!foreach_wif(1, NULL, is_sta)) )
849 ipt_write("-A POSTROUTING -o %s -d %s -j MASQUERADE\n", nvram_safe_get("wan_ifname"), modem_ipaddr);
851 switch (nvram_get_int("nf_loopback")) {
852 case 1: // 1 = forwarded-only
853 case 2: // 2 = disable
854 break;
855 default: // 0 = all (same as block_loopback=0)
856 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
857 lanface,
858 lanaddr, lanmask,
859 lanaddr, lanmask,
860 lanaddr);
861 if (strcmp(lan1face,"")!=0)
862 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
863 lan1face,
864 lan1addr, lan1mask,
865 lan1addr, lan1mask,
866 lan1addr);
867 if (strcmp(lan2face,"")!=0)
868 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
869 lan2face,
870 lan2addr, lan2mask,
871 lan2addr, lan2mask,
872 lan2addr);
873 if (strcmp(lan3face,"")!=0)
874 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
875 lan3face,
876 lan3addr, lan3mask,
877 lan3addr, lan3mask,
878 lan3addr);
879 break;
882 ipt_write("COMMIT\n");
885 // -----------------------------------------------------------------------------
886 // FILTER
887 // -----------------------------------------------------------------------------
889 static void filter_input(void)
891 char s[64];
892 char t[512];
893 char *en;
894 char *sec;
895 char *hit;
896 int n;
897 char *p, *c;
899 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
900 for (n = 0; n < wanfaces.count; ++n) {
901 if (*(wanfaces.iface[n].name)) {
902 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
903 if (strcmp(lan1face,"")!=0)
904 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
905 if (strcmp(lan2face,"")!=0)
906 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
907 if (strcmp(lan3face,"")!=0)
908 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
913 ipt_write(
914 "-A INPUT -m state --state INVALID -j DROP\n"
915 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
917 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
918 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
920 ? what if the user uses the start button in GUI ?
921 if (nvram_get_int("telnetd_eas"))
922 if (nvram_get_int("sshd_eas"))
924 #ifdef LINUX26
925 modprobe("xt_recent");
926 #else
927 modprobe("ipt_recent");
928 #endif
930 ipt_write(
931 "-N shlimit\n"
932 "-A shlimit -m recent --set --name shlimit\n"
933 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
934 atoi(hit) + 1, sec, chain_in_drop);
936 if (n & 1) {
937 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
938 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
939 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
942 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
945 #ifdef TCONFIG_FTP
946 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
947 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
948 #ifdef LINUX26
949 modprobe("xt_recent");
950 #else
951 modprobe("ipt_recent");
952 #endif
954 ipt_write(
955 "-N ftplimit\n"
956 "-A ftplimit -m recent --set --name ftp\n"
957 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
958 atoi(hit) + 1, sec, chain_in_drop);
959 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
961 #endif
963 ipt_write(
964 "-A INPUT -i lo -j ACCEPT\n"
965 "-A INPUT -i %s -j ACCEPT\n",
966 lanface);
967 if (strcmp(lan1face,"")!=0)
968 ipt_write(
969 "-A INPUT -i %s -j ACCEPT\n",
970 lan1face);
971 if (strcmp(lan2face,"")!=0)
972 ipt_write(
973 "-A INPUT -i %s -j ACCEPT\n",
974 lan2face);
975 if (strcmp(lan3face,"")!=0)
976 ipt_write(
977 "-A INPUT -i %s -j ACCEPT\n",
978 lan3face);
980 #ifdef TCONFIG_IPV6
981 n = get_ipv6_service();
982 switch (n) {
983 case IPV6_ANYCAST_6TO4:
984 case IPV6_6IN4:
985 // Accept ICMP requests from the remote tunnel endpoint
986 if (n == IPV6_ANYCAST_6TO4)
987 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
988 else
989 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
990 if (*s && strcmp(s, "0.0.0.0") != 0)
991 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
992 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
993 break;
995 #endif
997 // ICMP request from WAN interface
998 if (nvram_match("block_wan", "0")) {
999 if (nvram_match("block_wan_limit", "0")) {
1000 // allow ICMP packets to be received
1001 ipt_write("-A INPUT -p icmp -j %s\n", chain_in_accept);
1002 // allow udp traceroute packets
1003 ipt_write("-A INPUT -p udp --dport 33434:33534 -j %s\n", chain_in_accept);
1004 } else {
1005 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
1006 ipt_write("-A INPUT -p icmp -m limit --limit %d/second -j %s\n", nvram_get_int("block_wan_limit_icmp"), chain_in_accept);
1007 // allow udp traceroute packets, but restrict the flow to avoid ping flood attacks
1008 ipt_write("-A INPUT -p udp --dport 33434:33534 -m limit --limit %d/second -j %s\n", nvram_get_int("block_wan_limit_tr"), chain_in_accept);
1012 /* Accept incoming packets from broken dhcp servers, which are sending replies
1013 * from addresses other than used for query. This could lead to a lower level
1014 * of security, so allow to disable it via nvram variable.
1016 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
1017 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
1020 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1021 p = t;
1022 do {
1023 if ((c = strchr(p, ',')) != NULL) *c = 0;
1025 if (ipt_source(p, s, "remote management", NULL)) {
1027 if (remotemanage) {
1028 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1029 s, nvram_safe_get("http_wanport"), chain_in_accept);
1032 if (nvram_get_int("sshd_remote")) {
1033 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1034 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1038 if (!c) break;
1039 p = c + 1;
1040 } while (*p);
1042 #ifdef TCONFIG_FTP // !!TB - FTP Server
1043 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1044 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1045 p = t;
1046 do {
1047 if ((c = strchr(p, ',')) != NULL) *c = 0;
1048 if (ipt_source(p, s, "ftp", "remote access")) {
1049 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1050 s, nvram_safe_get("ftp_port"), chain_in_accept);
1052 if (!c) break;
1053 p = c + 1;
1054 } while (*p);
1056 #endif
1058 #ifdef TCONFIG_SNMP
1059 if( nvram_match( "snmp_enable", "1" ) && nvram_match("snmp_remote", "1"))
1061 strlcpy(t, nvram_safe_get("snmp_remote_sip"), sizeof(t));
1062 p = t;
1063 do {
1064 if ((c = strchr(p, ',')) != NULL) *c = 0;
1066 if (ipt_source(p, s, "snmp", "remote")) {
1067 ipt_write("-A INPUT -p udp %s --dport %s -j %s\n",
1068 s, nvram_safe_get("snmp_port"), chain_in_accept);
1071 if (!c) break;
1072 p = c + 1;
1073 } while (*p);
1075 #endif
1077 // IGMP query from WAN interface
1078 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1079 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
1080 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
1083 // Routing protocol, RIP, accept
1084 if (nvram_invmatch("dr_wan_rx", "0")) {
1085 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
1088 //BT Client ports from WAN interface
1089 if (nvram_match("bt_enable", "1")) {
1090 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port" ) );
1091 if (nvram_match( "bt_rpc_wan", "1") )
1093 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port_gui" ) );
1097 // if logging
1098 if (*chain_in_drop == 'l') {
1099 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
1102 // default policy: DROP
1105 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
1106 static void clampmss(void)
1108 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
1109 #ifdef TCONFIG_IPV6
1110 switch (get_ipv6_service()) {
1111 case IPV6_ANYCAST_6TO4:
1112 case IPV6_6IN4:
1113 ip6t_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
1114 break;
1116 #endif
1119 static void filter_forward(void)
1121 char dst[64];
1122 char src[64];
1123 char t[512];
1124 char *p, *c;
1125 int i;
1127 #ifdef TCONFIG_IPV6
1128 ip6t_write(
1129 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
1130 #endif
1132 if (nvram_match("cstats_enable", "1")) {
1133 ipt_account();
1136 ip46t_write(
1137 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
1138 lanface, lanface);
1139 if (strcmp(lan1face,"")!=0)
1140 ip46t_write(
1141 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1142 lan1face, lan1face);
1143 if (strcmp(lan2face,"")!=0)
1144 ip46t_write(
1145 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1146 lan2face, lan2face);
1147 if (strcmp(lan3face,"")!=0)
1148 ip46t_write(
1149 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1150 lan3face, lan3face);
1152 char lanAccess[17] = "0000000000000000";
1154 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
1155 char *nv, *nvp, *b;
1156 int n;
1157 nvp = nv = strdup(nvram_safe_get("lan_access"));
1158 if (nv) {
1159 while ((b = strsep(&nvp, ">")) != NULL) {
1161 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
1163 1 = enabled
1164 0 = src bridge
1165 1.2.3.4 = src addr
1166 1 = dst bridge
1167 5.6.7.8 = dst addr
1168 desc = desc
1170 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
1171 if (*d != '1')
1172 continue;
1173 if (!ipt_addr(src, sizeof(src), saddr, "src", IPT_V4|IPT_V6, 0, "LAN access", desc))
1174 continue;
1175 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", IPT_V4|IPT_V6, 0, "LAN access", desc))
1176 continue;
1178 //ipv4 only
1179 ipt_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
1180 "br",
1181 sbr,
1182 "br",
1183 dbr,
1184 src,
1185 dst);
1187 if ((strcmp(src,"")==0) && (strcmp(dst,"")==0))
1188 lanAccess[((*sbr-48)+(*dbr-48)*4)] = '1';
1192 free(nv);
1194 ip46t_write(
1195 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
1197 // clamp tcp mss to pmtu
1198 clampmss();
1200 if (wanup) {
1201 ipt_restrictions();
1203 ipt_layer7_inbound();
1206 ipt_webmon();
1208 ip46t_write(
1209 ":wanin - [0:0]\n"
1210 ":wanout - [0:0]\n"
1211 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1213 char lanN_ifname[] = "lanXX_ifname";
1214 char br;
1215 for(br=0 ; br<=3 ; br++) {
1216 char bridge[2] = "0";
1217 if (br!=0)
1218 bridge[0]+=br;
1219 else
1220 strcpy(bridge, "");
1222 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1223 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1224 char lanN_ifname2[] = "lanXX_ifname";
1225 char br2;
1226 for(br2=0 ; br2<=3 ; br2++) {
1227 if (br==br2) continue;
1229 if (lanAccess[((br)+(br2)*4)] == '1') continue;
1231 char bridge2[2] = "0";
1232 if (br2!=0)
1233 bridge2[0]+=br2;
1234 else
1235 strcpy(bridge2, "");
1237 sprintf(lanN_ifname2, "lan%s_ifname", bridge2);
1238 if (strncmp(nvram_safe_get(lanN_ifname2), "br", 2) == 0) {
1239 ipt_write("-A FORWARD -i %s -o %s -j DROP\n",
1240 nvram_safe_get(lanN_ifname),
1241 nvram_safe_get(lanN_ifname2));
1244 // ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1248 #ifdef TCONFIG_PPTPD
1249 //Add for pptp server
1250 if (nvram_match("pptpd_enable", "1")) {
1251 ipt_write("-A INPUT -p tcp --dport 1723 -j ACCEPT\n");
1252 ipt_write("-A INPUT -p 47 -j ACCEPT\n");
1254 #endif
1256 #ifdef TCONFIG_IPV6
1257 // Filter out invalid WAN->WAN connections
1258 if (*wan6face)
1259 // ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face, lanface, chain_in_drop); //shibby - we cant drop connections from WAN to LAN1-3
1260 ip6t_write("-A FORWARD -o %s -i %s -j %s\n", wan6face, wan6face, chain_in_drop); //shibby - drop connection from WAN -> WAN only
1262 #ifdef LINUX26
1263 modprobe("xt_length");
1264 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1265 #endif
1267 // ICMPv6 rules
1268 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
1269 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
1272 //IPv6
1273 if (*wan6face) {
1274 ip6t_write(
1275 "-A FORWARD -i %s -j wanin\n" // generic from wan
1276 "-A FORWARD -o %s -j wanout\n", // generic to wan
1277 wan6face, wan6face);
1279 #endif
1281 //IPv4
1282 for (i = 0; i < wanfaces.count; ++i) {
1283 if (*(wanfaces.iface[i].name)) {
1284 ipt_write(
1285 "-A FORWARD -i %s -j wanin\n" // generic from wan
1286 "-A FORWARD -o %s -j wanout\n", // generic to wan
1287 wanfaces.iface[i].name, wanfaces.iface[i].name);
1291 for(br=0 ; br<=3 ; br++) {
1292 char bridge[2] = "0";
1293 if (br!=0)
1294 bridge[0]+=br;
1295 else
1296 strcpy(bridge, "");
1298 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1299 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1300 ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1304 #ifdef TCONFIG_IPV6
1305 //IPv6 forward LAN->WAN accept
1306 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wan6face, chain_out_accept);
1308 if (strcmp(lan1face,"")!=0)
1309 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wan6face, chain_out_accept);
1310 if (strcmp(lan2face,"")!=0)
1311 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wan6face, chain_out_accept);
1312 if (strcmp(lan3face,"")!=0)
1313 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wan6face, chain_out_accept);
1314 #endif
1316 // IPv4 only
1317 if (nvram_get_int("upnp_enable") & 3) {
1318 ipt_write(":upnp - [0:0]\n");
1319 for (i = 0; i < wanfaces.count; ++i) {
1320 if (*(wanfaces.iface[i].name)) {
1321 ipt_write("-A FORWARD -i %s -j upnp\n",
1322 wanfaces.iface[i].name);
1327 if (wanup) {
1328 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1329 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1331 ipt_triggered(IPT_TABLE_FILTER);
1332 ipt_forward(IPT_TABLE_FILTER);
1333 #ifdef TCONFIG_IPV6
1334 ip6t_forward();
1335 #endif
1337 if (dmz_dst(dst)) {
1338 char dmz_ifname[IFNAMSIZ+1];
1339 strlcpy(dmz_ifname, nvram_safe_get("dmz_ifname"), sizeof(dmz_ifname));
1340 if(strcmp(dmz_ifname, "") == 0)
1341 strlcpy(dmz_ifname, lanface, sizeof(lanface));
1342 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1343 p = t;
1344 do {
1345 if ((c = strchr(p, ',')) != NULL) *c = 0;
1346 if (ipt_source(p, src, "dmz", NULL))
1347 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", dmz_ifname, src, dst, chain_in_accept);
1348 if (!c) break;
1349 p = c + 1;
1350 } while (*p);
1354 // default policy: DROP
1357 static void filter_log(void)
1359 int n;
1360 char limit[128];
1362 n = nvram_get_int("log_limit");
1363 if ((n >= 1) && (n <= 9999)) {
1364 sprintf(limit, "-m limit --limit %d/m", n);
1366 else {
1367 limit[0] = 0;
1370 #ifdef TCONFIG_IPV6
1371 modprobe("ip6t_LOG");
1372 #endif
1373 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1374 ip46t_write(
1375 ":logdrop - [0:0]\n"
1376 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1377 #ifdef LINUX26
1378 " --log-macdecode"
1379 #endif
1380 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1381 "-A logdrop -j DROP\n"
1382 ":logreject - [0:0]\n"
1383 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1384 #ifdef LINUX26
1385 " --log-macdecode"
1386 #endif
1387 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1388 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1389 limit, limit);
1391 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1392 ip46t_write(
1393 ":logaccept - [0:0]\n"
1394 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1395 #ifdef LINUX26
1396 " --log-macdecode"
1397 #endif
1398 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1399 "-A logaccept -j ACCEPT\n",
1400 limit);
1404 #ifdef TCONFIG_IPV6
1405 static void filter6_input(void)
1407 char s[128];
1408 char t[512];
1409 char *en;
1410 char *sec;
1411 char *hit;
1412 int n;
1413 char *p, *c;
1415 // RFC-4890, sec. 4.4.1
1416 const int allowed_local_icmpv6[] =
1417 { 130, 131, 132, 133, 134, 135, 136,
1418 141, 142, 143,
1419 148, 149, 151, 152, 153 };
1421 ip6t_write(
1422 "-A INPUT -m rt --rt-type 0 -j %s\n"
1423 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1424 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1425 chain_in_drop);
1427 #ifdef LINUX26
1428 modprobe("xt_length");
1429 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1430 #endif
1432 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1433 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1434 #ifdef LINUX26
1435 modprobe("xt_recent");
1436 #else
1437 modprobe("ipt_recent");
1438 #endif
1440 ip6t_write(
1441 "-N shlimit\n"
1442 "-A shlimit -m recent --set --name shlimit\n"
1443 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1444 atoi(hit) + 1, sec, chain_in_drop);
1446 if (n & 1) {
1447 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1448 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1449 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1452 if (n & 2) ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("telnetd_port"));
1455 #ifdef TCONFIG_FTP
1456 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1457 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1458 #ifdef LINUX26
1459 modprobe("xt_recent");
1460 #else
1461 modprobe("ipt_recent");
1462 #endif
1464 ip6t_write(
1465 "-N ftplimit\n"
1466 "-A ftplimit -m recent --set --name ftp\n"
1467 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1468 atoi(hit) + 1, sec, chain_in_drop);
1469 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1471 #endif // TCONFIG_FTP
1473 ip6t_write(
1474 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1475 "-A INPUT -i lo -j ACCEPT\n",
1476 lanface );
1478 switch (get_ipv6_service()) {
1479 case IPV6_ANYCAST_6TO4:
1480 case IPV6_NATIVE_DHCP:
1481 // allow responses from the dhcpv6 server
1482 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1483 break;
1486 // ICMPv6 rules
1487 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1488 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1490 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1491 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1494 // Remote Managment
1495 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1496 p = t;
1497 do {
1498 if ((c = strchr(p, ',')) != NULL) *c = 0;
1500 if (ip6t_source(p, s, "remote management", NULL)) {
1502 if (remotemanage) {
1503 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1504 s, nvram_safe_get("http_wanport"), chain_in_accept);
1507 if (nvram_get_int("sshd_remote")) {
1508 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1509 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1513 if (!c) break;
1514 p = c + 1;
1515 } while (*p);
1517 #ifdef TCONFIG_FTP
1518 // FTP server
1519 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1520 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1521 p = t;
1522 do {
1523 if ((c = strchr(p, ',')) != NULL) *c = 0;
1524 if (ip6t_source(p, s, "ftp", "remote access")) {
1525 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1526 s, nvram_safe_get("ftp_port"), chain_in_accept);
1528 if (!c) break;
1529 p = c + 1;
1530 } while (*p);
1532 #endif
1534 // if logging
1535 if (*chain_in_drop == 'l') {
1536 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1539 // default policy: DROP
1542 #endif
1544 static void filter_table(void)
1546 ip46t_write(
1547 "*filter\n"
1548 ":INPUT DROP [0:0]\n"
1549 ":OUTPUT ACCEPT [0:0]\n"
1552 filter_log();
1554 filter_input();
1555 #ifdef TCONFIG_IPV6
1556 filter6_input();
1557 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1558 #endif
1560 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1561 ip46t_write(":FORWARD DROP [0:0]\n");
1562 filter_forward();
1564 else {
1565 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1566 clampmss();
1568 ip46t_write("COMMIT\n");
1571 // -----------------------------------------------------------------------------
1573 int start_firewall(void)
1575 DIR *dir;
1576 struct dirent *dirent;
1577 char s[256];
1578 char *c, *wanface;
1579 int n;
1580 int wanproto;
1581 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1582 #ifdef TCONFIG_IPV6
1583 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1584 #endif
1586 simple_lock("firewall");
1587 simple_lock("restrictions");
1589 wanup = check_wanup();
1591 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1593 /* NAT performance tweaks
1594 * These values can be overriden later if needed via firewall script
1596 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1597 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1598 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1599 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1600 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1601 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1602 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1603 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1604 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1605 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1606 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1607 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1609 /* DoS-related tweaks */
1610 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1611 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1612 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1614 wanproto = get_wan_proto();
1615 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1617 #ifdef TCONFIG_EMF
1618 /* Force IGMPv2 due EMF limitations */
1619 if (nvram_get_int("emf_enable")) {
1620 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1621 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1623 #endif
1625 n = nvram_get_int("log_in");
1626 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1627 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1629 n = nvram_get_int("log_out");
1630 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1631 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1632 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1634 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1636 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1637 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1638 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1639 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1641 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1642 wanface = wanfaces.iface[0].name;
1643 #ifdef TCONFIG_IPV6
1644 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1645 #endif
1647 #ifdef LINUX26
1648 can_enable_fastnat = 1;
1649 #endif
1651 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1652 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1653 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1655 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1656 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1657 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1659 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1660 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1661 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1663 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1664 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1665 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1669 block obviously spoofed IP addresses
1671 rp_filter - BOOLEAN
1672 1 - do source validation by reversed path, as specified in RFC1812
1673 Recommended option for single homed hosts and stub network
1674 routers. Could cause troubles for complicated (not loop free)
1675 networks running a slow unreliable protocol (sort of RIP),
1676 or using static routes.
1677 0 - No source validation.
1679 c = nvram_get("wan_ifname");
1680 /* mcast needs rp filter to be turned off only for non default iface */
1681 if (!(nvram_match("multicast_pass", "1")) || !(nvram_match("udpxy_enable", "1")) || strcmp(wanface, c) == 0) c = NULL;
1683 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1684 while ((dirent = readdir(dir)) != NULL) {
1685 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1686 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1688 closedir(dir);
1691 remotemanage = 0;
1692 gateway_mode = !nvram_match("wk_mode", "router");
1693 if (gateway_mode) {
1694 /* Remote management */
1695 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1696 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1698 if (nvram_match("remote_mgt_https", "1")) {
1699 web_lanport = nvram_get_int("https_lanport");
1700 if (web_lanport <= 0) web_lanport = 443;
1701 } else {
1702 web_lanport = nvram_get_int("http_lanport");
1703 if (web_lanport <= 0) web_lanport = 80;
1707 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1708 notice_set("iptables", "Unable to create iptables restore file");
1709 simple_unlock("firewall");
1710 return 0;
1713 #ifdef TCONFIG_IPV6
1714 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1715 notice_set("ip6tables", "Unable to create ip6tables restore file");
1716 simple_unlock("firewall");
1717 return 0;
1719 modprobe("nf_conntrack_ipv6");
1720 modprobe("ip6t_REJECT");
1721 #endif
1723 //shibby
1724 //if (nvram_match("imq_enable", "1")) {
1725 // char numdevs[10];
1726 // sprintf(numdevs, "numdevs=%d", nvram_get_int("imq_numdevs"));
1727 // modprobe("imq", numdevs );
1729 modprobe("imq");
1730 #ifdef LINUX26
1731 modprobe("xt_IMQ");
1732 #else
1733 modprobe("ipt_IMQ");
1734 #endif
1735 // }
1738 mangle_table();
1739 nat_table();
1740 filter_table();
1742 fclose(ipt_file);
1743 ipt_file = NULL;
1745 #ifdef TCONFIG_IPV6
1746 fclose(ip6t_file);
1747 ip6t_file = NULL;
1748 #endif
1750 #ifdef DEBUG_IPTFILE
1751 if (debug_only) {
1752 simple_unlock("firewall");
1753 simple_unlock("restrictions");
1754 return 0;
1756 #endif
1758 save_webmon();
1760 if (nvram_get_int("upnp_enable") & 3) {
1761 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1762 if (killall("miniupnpd", SIGUSR2) == 0) {
1763 f_wait_notexists("/etc/upnp/save", 5);
1767 notice_set("iptables", "");
1768 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1769 led(LED_DIAG, 0);
1770 notice_set("iptables", "");
1772 else {
1773 sprintf(s, "%s.error", ipt_fname);
1774 rename(ipt_fname, s);
1775 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1776 led(LED_DIAG, 1);
1780 -P INPUT DROP
1781 -F INPUT
1782 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1783 -A INPUT -i br0 -j ACCEPT
1785 -P FORWARD DROP
1786 -F FORWARD
1787 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1788 -A FORWARD -i br0 -j ACCEPT
1793 #ifdef TCONFIG_IPV6
1794 if (ipv6_enabled()) {
1795 notice_set("ip6tables", "");
1796 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1797 notice_set("ip6tables", "");
1799 else {
1800 sprintf(s, "%s.error", ip6t_fname);
1801 rename(ip6t_fname, s);
1802 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1803 led(LED_DIAG, 1);
1806 else {
1807 eval("ip6tables", "-F");
1808 eval("ip6tables", "-t", "mangle", "-F");
1810 #endif
1812 if (nvram_get_int("upnp_enable") & 3) {
1813 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1814 killall("miniupnpd", SIGUSR2);
1817 simple_unlock("restrictions");
1818 sched_restrictions();
1819 enable_ip_forward();
1820 #ifdef TCONFIG_IPV6
1821 if (ipv6_enabled()) enable_ip6_forward();
1822 #endif
1824 led(LED_DMZ, dmz_dst(NULL));
1826 #ifdef TCONFIG_IPV6
1827 modprobe_r("nf_conntrack_ipv6");
1828 modprobe_r("ip6t_LOG");
1829 modprobe_r("ip6t_REJECT");
1830 #endif
1831 #ifdef LINUX26
1832 modprobe_r("xt_layer7");
1833 modprobe_r("xt_recent");
1834 modprobe_r("xt_HL");
1835 modprobe_r("xt_length");
1836 modprobe_r("xt_web");
1837 modprobe_r("xt_webmon");
1838 modprobe_r("xt_dscp");
1839 #else
1840 modprobe_r("ipt_layer7");
1841 modprobe_r("ipt_recent");
1842 modprobe_r("ipt_TTL");
1843 modprobe_r("ipt_web");
1844 modprobe_r("ipt_webmon");
1845 modprobe_r("ipt_dscp");
1846 #endif
1847 modprobe_r("ipt_ipp2p");
1849 unlink("/var/webmon/domain");
1850 unlink("/var/webmon/search");
1852 #ifdef TCONFIG_OPENVPN
1853 run_vpn_firewall_scripts();
1854 #endif
1855 run_nvscript("script_fire", NULL, 1);
1857 #ifdef LINUX26
1858 allow_fastnat("firewall", can_enable_fastnat);
1859 try_enabling_fastnat();
1860 #endif
1861 simple_unlock("firewall");
1862 return 0;
1865 int stop_firewall(void)
1867 led(LED_DMZ, 0);
1868 return 0;
1871 #ifdef DEBUG_IPTFILE
1872 void create_test_iptfile(void)
1874 debug_only = 1;
1875 start_firewall();
1876 debug_only = 0;
1878 #endif