Load IMQ module for QoS
[tomato.git] / release / src / router / rc / firewall.c
blob3eed198c33ee8ef59eb1c5661e27126a67d38fe1
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);
144 #ifdef TCONFIG_IPV6
145 if (ipv6_enabled()) {
146 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
147 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
149 #endif
153 // -----------------------------------------------------------------------------
156 static int ip2cclass(char *ipaddr, char *new, int count)
158 int ip[4];
160 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
161 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
166 static int dmz_dst(char *s)
168 struct in_addr ia;
169 char *p;
170 int n;
172 if (nvram_get_int("dmz_enable") <= 0) return 0;
174 p = nvram_safe_get("dmz_ipaddr");
175 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
176 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
177 if (s) sprintf(s, "%s%d", lan_cclass, n);
178 return 1;
181 if (s) strcpy(s, inet_ntoa(ia));
182 return 1;
185 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
187 char *pre, *post;
189 pre = (name && *name) ? " for \"" : "";
190 post = (name && *name) ? "\"" : "";
192 syslog(LOG_WARNING, "firewall: "
193 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
194 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
197 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
198 int strict, const char *categ, const char *name)
200 char p[INET6_ADDRSTRLEN * 2];
201 int r = 0;
203 if ((s) && (*s) && (*dir))
205 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
206 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
207 r = IPT_V4;
209 #ifdef TCONFIG_IPV6
210 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
211 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
212 r = IPT_V6;
214 #endif
215 else {
216 snprintf(addr, maxlen, "-%c %s", dir[0], s);
217 if (sscanf(s, "%[^/]/", p)) {
218 #ifdef TCONFIG_IPV6
219 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
220 #else
221 r = host_addrtypes(p, IPT_V4);
222 #endif
226 else
228 *addr = 0;
229 r = (IPT_V4 | IPT_V6);
232 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
233 ipt_log_unresolved(s, categ, name,
234 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
237 return (r & af);
240 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
241 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
242 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
245 static void get_src(const char *nv, char *src)
247 char *p;
249 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
250 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
252 else {
253 *src = 0;
258 void ipt_write(const char *format, ...)
260 va_list args;
262 va_start(args, format);
263 vfprintf(ipt_file, format, args);
264 va_end(args);
267 void ip6t_write(const char *format, ...)
269 #ifdef TCONFIG_IPV6
270 va_list args;
272 va_start(args, format);
273 vfprintf(ip6t_file, format, args);
274 va_end(args);
275 #endif
278 // -----------------------------------------------------------------------------
280 int ipt_dscp(const char *v, char *opt)
282 unsigned int n;
284 if (*v == 0) {
285 *opt = 0;
286 return 0;
289 n = strtoul(v, NULL, 0);
290 if (n > 63) n = 63;
291 sprintf(opt, " -m dscp --dscp 0x%02X", n);
293 #ifdef LINUX26
294 modprobe("xt_dscp");
295 #else
296 modprobe("ipt_dscp");
297 #endif
298 return 1;
301 // -----------------------------------------------------------------------------
304 int ipt_ipp2p(const char *v, char *opt)
306 int n = atoi(v);
308 if (n == 0) {
309 *opt = 0;
310 return 0;
313 strcpy(opt, "-m ipp2p ");
314 if ((n & 0xFFF) == 0xFFF) {
315 strcat(opt, "--ipp2p");
317 else {
318 // x12
319 if (n & 0x0001) strcat(opt, "--apple ");
320 if (n & 0x0002) strcat(opt, "--ares ");
321 if (n & 0x0004) strcat(opt, "--bit ");
322 if (n & 0x0008) strcat(opt, "--dc ");
323 if (n & 0x0010) strcat(opt, "--edk ");
324 if (n & 0x0020) strcat(opt, "--gnu ");
325 if (n & 0x0040) strcat(opt, "--kazaa ");
326 if (n & 0x0080) strcat(opt, "--mute ");
327 if (n & 0x0100) strcat(opt, "--soul ");
328 if (n & 0x0200) strcat(opt, "--waste ");
329 if (n & 0x0400) strcat(opt, "--winmx ");
330 if (n & 0x0800) strcat(opt, "--xdcc ");
331 #ifdef LINUX26
332 if (n & 0x1000) strcat(opt, "--pp ");
333 if (n & 0x2000) strcat(opt, "--xunlei ");
334 #endif
337 modprobe("ipt_ipp2p");
338 return 1;
342 // -----------------------------------------------------------------------------
345 char **layer7_in;
347 // This L7 matches inbound traffic, caches the results, then the L7 outbound
348 // should read the cached result and set the appropriate marks -- zzz
349 void ipt_layer7_inbound(void)
351 int en, i;
352 char **p;
354 if (!layer7_in) return;
356 en = nvram_match("nf_l7in", "1");
357 if (en) {
358 ipt_write(":L7in - [0:0]\n");
359 for (i = 0; i < wanfaces.count; ++i) {
360 if (*(wanfaces.iface[i].name)) {
361 ipt_write("-A FORWARD -i %s -j L7in\n",
362 wanfaces.iface[i].name);
367 p = layer7_in;
368 while (*p) {
369 if (en) {
370 ipt_write("-A L7in %s -j RETURN\n", *p);
371 #ifdef LINUX26
372 can_enable_fastnat = 0;
373 #endif
375 free(*p);
376 ++p;
378 free(layer7_in);
379 layer7_in = NULL;
382 int ipt_layer7(const char *v, char *opt)
384 char s[128];
385 char *path;
387 *opt = 0;
388 if (*v == 0) return 0;
389 if (strlen(v) > 32) return -1;
391 path = "/etc/l7-extra";
392 sprintf(s, "%s/%s.pat", path, v);
393 if (!f_exists(s)) {
394 path = "/etc/l7-protocols";
395 sprintf(s, "%s/%s.pat", path, v);
396 if (!f_exists(s)) {
397 syslog(LOG_ERR, "L7 %s was not found", v);
398 return -1;
402 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
404 if (nvram_match("nf_l7in", "1")) {
405 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
406 if (layer7_in) {
407 char **p;
409 p = layer7_in;
410 while (*p) {
411 if (strcmp(*p, opt) == 0) return 1;
412 ++p;
414 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
418 #ifdef LINUX26
419 modprobe("xt_layer7");
420 #else
421 modprobe("ipt_layer7");
422 #endif
423 return 1;
426 // -----------------------------------------------------------------------------
428 static void ipt_account(void) {
429 struct in_addr ipaddr, netmask, network;
430 char lanN_ifname[] = "lanXX_ifname";
431 char lanN_ipaddr[] = "lanXX_ipaddr";
432 char lanN_netmask[] = "lanXX_netmask";
433 char lanN[] = "lanXX";
434 char netaddrnetmask[] = "255.255.255.255/255.255.255.255 ";
435 char br;
437 for(br=0 ; br<=3 ; br++) {
438 char bridge[2] = "0";
439 if (br!=0)
440 bridge[0]+=br;
441 else
442 strcpy(bridge, "");
444 sprintf(lanN_ifname, "lan%s_ifname", bridge);
446 if (strcmp(nvram_safe_get(lanN_ifname), "")!=0) {
448 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
449 sprintf(lanN_netmask, "lan%s_netmask", bridge);
450 sprintf(lanN, "lan%s", bridge);
452 inet_aton(nvram_safe_get(lanN_ipaddr), &ipaddr);
453 inet_aton(nvram_safe_get(lanN_netmask), &netmask);
455 // bitwise AND of ip and netmask gives the network
456 network.s_addr = ipaddr.s_addr & netmask.s_addr;
458 sprintf(netaddrnetmask, "%s/%s", inet_ntoa(network), nvram_safe_get(lanN_netmask));
460 //ipv4 only
461 ipt_write("-A FORWARD -m account --aaddr %s --aname %s\n", netaddrnetmask, lanN);
466 // -----------------------------------------------------------------------------
468 static void save_webmon(void)
470 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
471 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
474 static void ipt_webmon()
476 int wmtype, clear, i;
477 char t[512];
478 char src[128];
479 char *p, *c;
480 int ok;
482 if (!nvram_get_int("log_wm")) return;
484 #ifdef LINUX26
485 can_enable_fastnat = 0;
486 #endif
487 wmtype = nvram_get_int("log_wmtype");
488 clear = nvram_get_int("log_wmclear");
490 ip46t_write(":monitor - [0:0]\n");
492 // include IPs
493 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
494 p = t;
495 do {
496 if ((c = strchr(p, ',')) != NULL) *c = 0;
498 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
499 #ifdef TCONFIG_IPV6
500 if (*wan6face && (ok & IPT_V6))
501 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
502 #endif
503 if (ok & IPT_V4) {
504 for (i = 0; i < wanfaces.count; ++i) {
505 if (*(wanfaces.iface[i].name)) {
506 ipt_write("-A FORWARD -o %s %s -j monitor\n",
507 wanfaces.iface[i].name, src);
513 if (!c) break;
514 p = c + 1;
515 } while (*p);
517 // exclude IPs
518 if (wmtype == 2) {
519 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
520 p = t;
521 do {
522 if ((c = strchr(p, ',')) != NULL) *c = 0;
523 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
524 if (*src)
525 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
527 if (!c) break;
528 p = c + 1;
529 } while (*p);
532 ip46t_write(
533 "-A monitor -p tcp -m webmon "
534 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
535 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
536 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
537 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
539 #ifdef LINUX26
540 modprobe("xt_webmon");
541 #else
542 modprobe("ipt_webmon");
543 #endif
547 // -----------------------------------------------------------------------------
548 // MANGLE
549 // -----------------------------------------------------------------------------
551 static void mangle_table(void)
553 int ttl;
554 char *p, *wanface;
556 ip46t_write(
557 "*mangle\n"
558 ":PREROUTING ACCEPT [0:0]\n"
559 ":OUTPUT ACCEPT [0:0]\n");
561 if (wanup) {
563 ipt_qos();
564 //1 for mangle
565 ipt_qoslimit(1);
567 p = nvram_safe_get("nf_ttl");
568 if (strncmp(p, "c:", 2) == 0) {
569 p += 2;
570 ttl = atoi(p);
571 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
573 else if ((ttl = atoi(p)) != 0) {
574 if (ttl > 0) {
575 p = "inc";
577 else {
578 ttl = -ttl;
579 p = "dec";
581 if (ttl > 255) p = NULL;
583 else p = NULL;
585 if (p) {
586 #ifdef LINUX26
587 modprobe("xt_HL");
588 #else
589 modprobe("ipt_TTL");
590 #endif
591 // set TTL on primary WAN iface only
592 wanface = wanfaces.iface[0].name;
593 ipt_write(
594 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
595 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
596 wanface, p, ttl,
597 wanface, p, ttl);
598 #ifdef TCONFIG_IPV6
599 // FIXME: IPv6 HL should be configurable separately from TTL.
600 // disable it until GUI setting is implemented.
601 #if 0
602 ip6t_write(
603 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
604 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
605 wan6face, p, ttl,
606 wan6face, p, ttl);
607 #endif
608 #endif
612 ip46t_write("COMMIT\n");
615 // -----------------------------------------------------------------------------
616 // NAT
617 // -----------------------------------------------------------------------------
619 static void nat_table(void)
621 char lanaddr[32];
622 char lanmask[32];
623 char lan1addr[32];
624 char lan1mask[32];
625 char lan2addr[32];
626 char lan2mask[32];
627 char lan3addr[32];
628 char lan3mask[32];
629 char dst[64];
630 char src[64];
631 char t[512];
632 char *p, *c;
633 int i;
635 ipt_write("*nat\n"
636 ":PREROUTING ACCEPT [0:0]\n"
637 ":POSTROUTING ACCEPT [0:0]\n"
638 ":OUTPUT ACCEPT [0:0]\n"
639 ":%s - [0:0]\n",
640 chain_wan_prerouting);
642 //2 for nat
643 ipt_qoslimit(2);
645 if (gateway_mode) {
646 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
647 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
648 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
649 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
650 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
651 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
652 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
653 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
656 for (i = 0; i < wanfaces.count; ++i) {
657 if (*(wanfaces.iface[i].name)) {
658 // chain_wan_prerouting
659 if (wanup) {
660 ipt_write("-A PREROUTING -d %s -j %s\n",
661 wanfaces.iface[i].ip, chain_wan_prerouting);
664 // Drop incoming packets which destination IP address is to our LAN side directly
665 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
666 wanfaces.iface[i].name,
667 lanaddr, lanmask); // note: ipt will correct lanaddr
668 if(strcmp(lan1addr,"")!=0)
669 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
670 wanfaces.iface[i].name,
671 lan1addr, lan1mask);
672 if(strcmp(lan2addr,"")!=0)
673 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
674 wanfaces.iface[i].name,
675 lan2addr, lan2mask);
676 if(strcmp(lan3addr,"")!=0)
677 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
678 wanfaces.iface[i].name,
679 lan3addr, lan3mask);
683 if (wanup) {
684 if (nvram_match("dns_intcpt", "1")) {
685 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
686 lanaddr, lanmask,
687 lanaddr, lanmask,
688 lanaddr);
689 if(strcmp(lan1addr,"")!=0)
690 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
691 lan1addr, lan1mask,
692 lan1addr, lan1mask,
693 lan1addr);
694 if(strcmp(lan2addr,"")!=0)
695 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
696 lan2addr, lan2mask,
697 lan2addr, lan2mask,
698 lan2addr);
699 if(strcmp(lan3addr,"")!=0)
700 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
701 lan3addr, lan3mask,
702 lan3addr, lan3mask,
703 lan3addr);
706 // ICMP packets are always redirected to INPUT chains
707 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
710 //force remote access to router if DMZ is enabled - shibby
711 if( (nvram_match("dmz_enable", "1")) && (nvram_match("dmz_ra", "1")) ) {
712 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
713 p = t;
714 do {
715 if ((c = strchr(p, ',')) != NULL) *c = 0;
716 ipt_source(p, src, "ra", NULL);
718 if (remotemanage) {
719 ipt_write("-A %s -p tcp -m tcp %s --dport %s -j DNAT --to-destination %s:%d\n",
720 chain_wan_prerouting, src, nvram_safe_get("http_wanport"), lanaddr, web_lanport);
723 if (nvram_get_int("sshd_remote")) {
724 ipt_write("-A %s %s -p tcp -m tcp --dport %s -j DNAT --to-destination %s:%s\n",
725 chain_wan_prerouting, src, nvram_safe_get("sshd_rport"), lanaddr, nvram_safe_get("sshd_port"));
728 if (!c) break;
729 p = c + 1;
730 } while (*p);
734 ipt_forward(IPT_TABLE_NAT);
735 ipt_triggered(IPT_TABLE_NAT);
738 if (nvram_get_int("upnp_enable") & 3) {
739 ipt_write(":upnp - [0:0]\n");
741 for (i = 0; i < wanfaces.count; ++i) {
742 if (*(wanfaces.iface[i].name)) {
743 if (wanup) {
744 // ! for loopback (all) to work
745 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces.iface[i].ip);
747 else {
748 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
754 #ifdef TCONFIG_TOR
755 //TOR
756 if (nvram_match("tor_enable", "1")) {
757 if (nvram_match("tor_iface", "br0")) {
758 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
759 nvram_safe_get("tor_iface"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("tor_transport") );
760 } else if (nvram_match("tor_iface", "br1")) {
761 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
762 nvram_safe_get("tor_iface"), nvram_safe_get("lan1_ipaddr"), nvram_safe_get("lan1_ipaddr"), nvram_safe_get("tor_transport") );
763 } else if (nvram_match("tor_iface", "br2")) {
764 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
765 nvram_safe_get("tor_iface"), nvram_safe_get("lan2_ipaddr"), nvram_safe_get("lan2_ipaddr"), nvram_safe_get("tor_transport") );
766 } else if (nvram_match("tor_iface", "br3")) {
767 ipt_write("-A PREROUTING -i %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
768 nvram_safe_get("tor_iface"), nvram_safe_get("lan3_ipaddr"), nvram_safe_get("lan3_ipaddr"), nvram_safe_get("tor_transport") );
769 } else {
770 strlcpy(t, nvram_safe_get("tor_users"), sizeof(t));
771 p = t;
772 do {
773 if ((c = strchr(p, ',')) != NULL) *c = 0;
775 if (ipt_source_strict(p, src, "tor", NULL))
776 ipt_write("-A PREROUTING %s -p tcp --dport 80 ! -d %s -j DNAT --to-destination %s:%s\n",
777 src, nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_ipaddr"), nvram_safe_get("tor_transport") );
779 if (!c) break;
780 p = c + 1;
781 } while (*p);
784 #endif
786 if (wanup) {
787 if (dmz_dst(dst)) {
788 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
789 p = t;
790 do {
791 if ((c = strchr(p, ',')) != NULL) *c = 0;
792 if (ipt_source_strict(p, src, "dmz", NULL))
793 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
794 if (!c) break;
795 p = c + 1;
796 } while (*p);
800 p = "";
801 #ifdef TCONFIG_IPV6
802 switch (get_ipv6_service()) {
803 case IPV6_6IN4:
804 // avoid NATing proto-41 packets when using 6in4 tunnel
805 p = "-p ! 41";
806 break;
808 #endif
810 for (i = 0; i < wanfaces.count; ++i) {
811 if (*(wanfaces.iface[i].name)) {
812 if ((!wanup) || (nvram_get_int("ne_snat") != 1))
813 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
814 else
815 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
819 char *modem_ipaddr;
820 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
821 && (modem_ipaddr = nvram_safe_get("modem_ipaddr")) && *modem_ipaddr && !nvram_match("modem_ipaddr","0.0.0.0")
822 && (!foreach_wif(1, NULL, is_sta)) )
823 ipt_write("-A POSTROUTING -o %s -d %s -j MASQUERADE\n", nvram_safe_get("wan_ifname"), modem_ipaddr);
825 switch (nvram_get_int("nf_loopback")) {
826 case 1: // 1 = forwarded-only
827 case 2: // 2 = disable
828 break;
829 default: // 0 = all (same as block_loopback=0)
830 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
831 lanface,
832 lanaddr, lanmask,
833 lanaddr, lanmask,
834 lanaddr);
835 if (strcmp(lan1face,"")!=0)
836 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
837 lan1face,
838 lan1addr, lan1mask,
839 lan1addr, lan1mask,
840 lan1addr);
841 if (strcmp(lan2face,"")!=0)
842 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
843 lan2face,
844 lan2addr, lan2mask,
845 lan2addr, lan2mask,
846 lan2addr);
847 if (strcmp(lan3face,"")!=0)
848 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
849 lan3face,
850 lan3addr, lan3mask,
851 lan3addr, lan3mask,
852 lan3addr);
853 break;
856 ipt_write("COMMIT\n");
859 // -----------------------------------------------------------------------------
860 // FILTER
861 // -----------------------------------------------------------------------------
863 static void filter_input(void)
865 char s[64];
866 char t[512];
867 char *en;
868 char *sec;
869 char *hit;
870 int n;
871 char *p, *c;
873 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
874 for (n = 0; n < wanfaces.count; ++n) {
875 if (*(wanfaces.iface[n].name)) {
876 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
877 if (strcmp(lan1face,"")!=0)
878 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
879 if (strcmp(lan2face,"")!=0)
880 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
881 if (strcmp(lan3face,"")!=0)
882 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
887 ipt_write(
888 "-A INPUT -m state --state INVALID -j DROP\n"
889 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
891 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
892 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
894 ? what if the user uses the start button in GUI ?
895 if (nvram_get_int("telnetd_eas"))
896 if (nvram_get_int("sshd_eas"))
898 #ifdef LINUX26
899 modprobe("xt_recent");
900 #else
901 modprobe("ipt_recent");
902 #endif
904 ipt_write(
905 "-N shlimit\n"
906 "-A shlimit -m recent --set --name shlimit\n"
907 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
908 atoi(hit) + 1, sec, chain_in_drop);
910 if (n & 1) {
911 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
912 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
913 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
916 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
919 #ifdef TCONFIG_FTP
920 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
921 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
922 #ifdef LINUX26
923 modprobe("xt_recent");
924 #else
925 modprobe("ipt_recent");
926 #endif
928 ipt_write(
929 "-N ftplimit\n"
930 "-A ftplimit -m recent --set --name ftp\n"
931 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
932 atoi(hit) + 1, sec, chain_in_drop);
933 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
935 #endif
937 ipt_write(
938 "-A INPUT -i lo -j ACCEPT\n"
939 "-A INPUT -i %s -j ACCEPT\n",
940 lanface);
941 if (strcmp(lan1face,"")!=0)
942 ipt_write(
943 "-A INPUT -i %s -j ACCEPT\n",
944 lan1face);
945 if (strcmp(lan2face,"")!=0)
946 ipt_write(
947 "-A INPUT -i %s -j ACCEPT\n",
948 lan2face);
949 if (strcmp(lan3face,"")!=0)
950 ipt_write(
951 "-A INPUT -i %s -j ACCEPT\n",
952 lan3face);
954 #ifdef TCONFIG_IPV6
955 n = get_ipv6_service();
956 switch (n) {
957 case IPV6_ANYCAST_6TO4:
958 case IPV6_6IN4:
959 // Accept ICMP requests from the remote tunnel endpoint
960 if (n == IPV6_ANYCAST_6TO4)
961 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
962 else
963 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
964 if (*s && strcmp(s, "0.0.0.0") != 0)
965 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
966 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
967 break;
969 #endif
971 // ICMP request from WAN interface
972 if (nvram_match("block_wan", "0")) {
973 if (nvram_match("block_wan_limit", "0")) {
974 // allow ICMP packets to be received
975 ipt_write("-A INPUT -p icmp -j %s\n", chain_in_accept);
976 // allow udp traceroute packets
977 ipt_write("-A INPUT -p udp --dport 33434:33534 -j %s\n", chain_in_accept);
978 } else {
979 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
980 ipt_write("-A INPUT -p icmp -m limit --limit %d/second -j %s\n", nvram_get_int("block_wan_limit_icmp"), chain_in_accept);
981 // allow udp traceroute packets, but restrict the flow to avoid ping flood attacks
982 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);
986 /* Accept incoming packets from broken dhcp servers, which are sending replies
987 * from addresses other than used for query. This could lead to a lower level
988 * of security, so allow to disable it via nvram variable.
990 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
991 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
994 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
995 p = t;
996 do {
997 if ((c = strchr(p, ',')) != NULL) *c = 0;
999 if (ipt_source(p, s, "remote management", NULL)) {
1001 if (remotemanage) {
1002 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1003 s, nvram_safe_get("http_wanport"), chain_in_accept);
1006 if (nvram_get_int("sshd_remote")) {
1007 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1008 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1012 if (!c) break;
1013 p = c + 1;
1014 } while (*p);
1016 #ifdef TCONFIG_FTP // !!TB - FTP Server
1017 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1018 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1019 p = t;
1020 do {
1021 if ((c = strchr(p, ',')) != NULL) *c = 0;
1022 if (ipt_source(p, s, "ftp", "remote access")) {
1023 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1024 s, nvram_safe_get("ftp_port"), chain_in_accept);
1026 if (!c) break;
1027 p = c + 1;
1028 } while (*p);
1030 #endif
1032 #ifdef TCONFIG_SNMP
1033 if( nvram_match( "snmp_enable", "1" ) && nvram_match("snmp_remote", "1"))
1035 strlcpy(t, nvram_safe_get("snmp_remote_sip"), sizeof(t));
1036 p = t;
1037 do {
1038 if ((c = strchr(p, ',')) != NULL) *c = 0;
1040 if (ipt_source(p, s, "snmp", "remote")) {
1041 ipt_write("-A INPUT -p udp %s --dport %s -j %s\n",
1042 s, nvram_safe_get("snmp_port"), chain_in_accept);
1045 if (!c) break;
1046 p = c + 1;
1047 } while (*p);
1049 #endif
1051 // IGMP query from WAN interface
1052 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1053 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
1054 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
1057 // Routing protocol, RIP, accept
1058 if (nvram_invmatch("dr_wan_rx", "0")) {
1059 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
1062 //BT Client ports from WAN interface
1063 if (nvram_match("bt_enable", "1")) {
1064 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port" ) );
1065 if (nvram_match( "bt_rpc_wan", "1") )
1067 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port_gui" ) );
1071 // if logging
1072 if (*chain_in_drop == 'l') {
1073 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
1076 // default policy: DROP
1079 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
1080 static void clampmss(void)
1082 #if 1
1083 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
1084 #else
1085 int rmtu = nvram_get_int("wan_run_mtu");
1086 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu - 39);
1087 if (rmtu < 576) {
1088 ipt_write("--clamp-mss-to-pmtu\n");
1090 else {
1091 ipt_write("--set-mss %d\n", rmtu - 40);
1093 #endif
1096 static void filter_forward(void)
1098 char dst[64];
1099 char src[64];
1100 char t[512];
1101 char *p, *c;
1102 int i;
1104 #ifdef TCONFIG_IPV6
1105 ip6t_write(
1106 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
1107 #endif
1109 if (nvram_match("cstats_enable", "1")) {
1110 ipt_account();
1113 ip46t_write(
1114 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
1115 lanface, lanface);
1116 if (strcmp(lan1face,"")!=0)
1117 ip46t_write(
1118 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1119 lan1face, lan1face);
1120 if (strcmp(lan2face,"")!=0)
1121 ip46t_write(
1122 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1123 lan2face, lan2face);
1124 if (strcmp(lan3face,"")!=0)
1125 ip46t_write(
1126 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1127 lan3face, lan3face);
1129 char lanAccess[17] = "0000000000000000";
1131 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
1132 char *nv, *nvp, *b;
1133 int n;
1134 nvp = nv = strdup(nvram_safe_get("lan_access"));
1135 if (nv) {
1136 while ((b = strsep(&nvp, ">")) != NULL) {
1138 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
1140 1 = enabled
1141 0 = src bridge
1142 1.2.3.4 = src addr
1143 1 = dst bridge
1144 5.6.7.8 = dst addr
1145 desc = desc
1147 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
1148 if (*d != '1')
1149 continue;
1150 if (!ipt_addr(src, sizeof(src), saddr, "src", IPT_V4|IPT_V6, 0, "LAN access", desc))
1151 continue;
1152 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", IPT_V4|IPT_V6, 0, "LAN access", desc))
1153 continue;
1155 //ipv4 only
1156 ipt_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
1157 "br",
1158 sbr,
1159 "br",
1160 dbr,
1161 src,
1162 dst);
1164 if ((strcmp(src,"")==0) && (strcmp(dst,"")==0))
1165 lanAccess[((*sbr-48)+(*dbr-48)*4)] = '1';
1169 free(nv);
1171 ip46t_write(
1172 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
1174 // clamp tcp mss to pmtu
1175 clampmss();
1177 if (wanup) {
1178 ipt_restrictions();
1180 ipt_layer7_inbound();
1183 ipt_webmon();
1185 ip46t_write(
1186 ":wanin - [0:0]\n"
1187 ":wanout - [0:0]\n"
1188 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1190 char lanN_ifname[] = "lanXX_ifname";
1191 char br;
1192 for(br=0 ; br<=3 ; br++) {
1193 char bridge[2] = "0";
1194 if (br!=0)
1195 bridge[0]+=br;
1196 else
1197 strcpy(bridge, "");
1199 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1200 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1201 char lanN_ifname2[] = "lanXX_ifname";
1202 char br2;
1203 for(br2=0 ; br2<=3 ; br2++) {
1204 if (br==br2) continue;
1206 if (lanAccess[((br)+(br2)*4)] == '1') continue;
1208 char bridge2[2] = "0";
1209 if (br2!=0)
1210 bridge2[0]+=br2;
1211 else
1212 strcpy(bridge2, "");
1214 sprintf(lanN_ifname2, "lan%s_ifname", bridge2);
1215 if (strncmp(nvram_safe_get(lanN_ifname2), "br", 2) == 0) {
1216 ipt_write("-A FORWARD -i %s -o %s -j DROP\n",
1217 nvram_safe_get(lanN_ifname),
1218 nvram_safe_get(lanN_ifname2));
1221 // ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1225 #ifdef TCONFIG_PPTPD
1226 //Add for pptp server
1227 if (nvram_match("pptpd_enable", "1")) {
1228 ipt_write("-A INPUT -p tcp --dport 1723 -j ACCEPT\n");
1229 ipt_write("-A INPUT -p 47 -j ACCEPT\n");
1231 #endif
1233 #ifdef TCONFIG_IPV6
1234 // Filter out invalid WAN->WAN connections
1235 if (*wan6face)
1236 // 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
1237 ip6t_write("-A FORWARD -o %s -i %s -j %s\n", wan6face, wan6face, chain_in_drop); //shibby - drop connection from WAN -> WAN only
1239 #ifdef LINUX26
1240 modprobe("xt_length");
1241 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1242 #endif
1244 // ICMPv6 rules
1245 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
1246 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
1249 //IPv6
1250 if (*wan6face) {
1251 ip6t_write(
1252 "-A FORWARD -i %s -j wanin\n" // generic from wan
1253 "-A FORWARD -o %s -j wanout\n", // generic to wan
1254 wan6face, wan6face);
1256 #endif
1258 //IPv4
1259 for (i = 0; i < wanfaces.count; ++i) {
1260 if (*(wanfaces.iface[i].name)) {
1261 ipt_write(
1262 "-A FORWARD -i %s -j wanin\n" // generic from wan
1263 "-A FORWARD -o %s -j wanout\n", // generic to wan
1264 wanfaces.iface[i].name, wanfaces.iface[i].name);
1268 for(br=0 ; br<=3 ; br++) {
1269 char bridge[2] = "0";
1270 if (br!=0)
1271 bridge[0]+=br;
1272 else
1273 strcpy(bridge, "");
1275 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1276 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1277 ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1281 #ifdef TCONFIG_IPV6
1282 //IPv6 forward LAN->WAN accept
1283 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wan6face, chain_out_accept);
1285 if (strcmp(lan1face,"")!=0)
1286 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wan6face, chain_out_accept);
1287 if (strcmp(lan2face,"")!=0)
1288 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wan6face, chain_out_accept);
1289 if (strcmp(lan3face,"")!=0)
1290 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wan6face, chain_out_accept);
1291 #endif
1293 // IPv4 only
1294 if (nvram_get_int("upnp_enable") & 3) {
1295 ipt_write(":upnp - [0:0]\n");
1296 for (i = 0; i < wanfaces.count; ++i) {
1297 if (*(wanfaces.iface[i].name)) {
1298 ipt_write("-A FORWARD -i %s -j upnp\n",
1299 wanfaces.iface[i].name);
1304 if (wanup) {
1305 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1306 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1308 ipt_triggered(IPT_TABLE_FILTER);
1309 ipt_forward(IPT_TABLE_FILTER);
1310 #ifdef TCONFIG_IPV6
1311 ip6t_forward();
1312 #endif
1314 if (dmz_dst(dst)) {
1315 char dmz_ifname[IFNAMSIZ+1];
1316 strlcpy(dmz_ifname, nvram_safe_get("dmz_ifname"), sizeof(dmz_ifname));
1317 if(strcmp(dmz_ifname, "") == 0)
1318 strlcpy(dmz_ifname, lanface, sizeof(lanface));
1319 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1320 p = t;
1321 do {
1322 if ((c = strchr(p, ',')) != NULL) *c = 0;
1323 if (ipt_source(p, src, "dmz", NULL))
1324 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", dmz_ifname, src, dst, chain_in_accept);
1325 if (!c) break;
1326 p = c + 1;
1327 } while (*p);
1331 // default policy: DROP
1334 static void filter_log(void)
1336 int n;
1337 char limit[128];
1339 n = nvram_get_int("log_limit");
1340 if ((n >= 1) && (n <= 9999)) {
1341 sprintf(limit, "-m limit --limit %d/m", n);
1343 else {
1344 limit[0] = 0;
1347 #ifdef TCONFIG_IPV6
1348 modprobe("ip6t_LOG");
1349 #endif
1350 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1351 ip46t_write(
1352 ":logdrop - [0:0]\n"
1353 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1354 #ifdef LINUX26
1355 " --log-macdecode"
1356 #endif
1357 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1358 "-A logdrop -j DROP\n"
1359 ":logreject - [0:0]\n"
1360 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1361 #ifdef LINUX26
1362 " --log-macdecode"
1363 #endif
1364 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1365 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1366 limit, limit);
1368 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1369 ip46t_write(
1370 ":logaccept - [0:0]\n"
1371 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1372 #ifdef LINUX26
1373 " --log-macdecode"
1374 #endif
1375 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1376 "-A logaccept -j ACCEPT\n",
1377 limit);
1381 #ifdef TCONFIG_IPV6
1382 static void filter6_input(void)
1384 char s[128];
1385 char t[512];
1386 char *en;
1387 char *sec;
1388 char *hit;
1389 int n;
1390 char *p, *c;
1392 // RFC-4890, sec. 4.4.1
1393 const int allowed_local_icmpv6[] =
1394 { 130, 131, 132, 133, 134, 135, 136,
1395 141, 142, 143,
1396 148, 149, 151, 152, 153 };
1398 ip6t_write(
1399 "-A INPUT -m rt --rt-type 0 -j %s\n"
1400 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1401 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1402 chain_in_drop);
1404 #ifdef LINUX26
1405 modprobe("xt_length");
1406 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1407 #endif
1409 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1410 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1411 #ifdef LINUX26
1412 modprobe("xt_recent");
1413 #else
1414 modprobe("ipt_recent");
1415 #endif
1417 ip6t_write(
1418 "-N shlimit\n"
1419 "-A shlimit -m recent --set --name shlimit\n"
1420 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1421 atoi(hit) + 1, sec, chain_in_drop);
1423 if (n & 1) {
1424 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1425 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1426 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1429 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"));
1432 #ifdef TCONFIG_FTP
1433 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1434 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1435 #ifdef LINUX26
1436 modprobe("xt_recent");
1437 #else
1438 modprobe("ipt_recent");
1439 #endif
1441 ip6t_write(
1442 "-N ftplimit\n"
1443 "-A ftplimit -m recent --set --name ftp\n"
1444 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1445 atoi(hit) + 1, sec, chain_in_drop);
1446 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1448 #endif // TCONFIG_FTP
1450 ip6t_write(
1451 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1452 "-A INPUT -i lo -j ACCEPT\n",
1453 lanface );
1455 switch (get_ipv6_service()) {
1456 case IPV6_ANYCAST_6TO4:
1457 case IPV6_NATIVE_DHCP:
1458 // allow responses from the dhcpv6 server
1459 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1460 break;
1463 // ICMPv6 rules
1464 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1465 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1467 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1468 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1471 // Remote Managment
1472 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1473 p = t;
1474 do {
1475 if ((c = strchr(p, ',')) != NULL) *c = 0;
1477 if (ip6t_source(p, s, "remote management", NULL)) {
1479 if (remotemanage) {
1480 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1481 s, nvram_safe_get("http_wanport"), chain_in_accept);
1484 if (nvram_get_int("sshd_remote")) {
1485 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1486 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1490 if (!c) break;
1491 p = c + 1;
1492 } while (*p);
1494 #ifdef TCONFIG_FTP
1495 // FTP server
1496 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1497 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1498 p = t;
1499 do {
1500 if ((c = strchr(p, ',')) != NULL) *c = 0;
1501 if (ip6t_source(p, s, "ftp", "remote access")) {
1502 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1503 s, nvram_safe_get("ftp_port"), chain_in_accept);
1505 if (!c) break;
1506 p = c + 1;
1507 } while (*p);
1509 #endif
1511 // if logging
1512 if (*chain_in_drop == 'l') {
1513 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1516 // default policy: DROP
1519 #endif
1521 static void filter_table(void)
1523 ip46t_write(
1524 "*filter\n"
1525 ":INPUT DROP [0:0]\n"
1526 ":OUTPUT ACCEPT [0:0]\n"
1529 filter_log();
1531 filter_input();
1532 #ifdef TCONFIG_IPV6
1533 filter6_input();
1534 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1535 #endif
1537 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1538 ip46t_write(":FORWARD DROP [0:0]\n");
1539 filter_forward();
1541 else {
1542 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1543 clampmss();
1545 ip46t_write("COMMIT\n");
1548 // -----------------------------------------------------------------------------
1550 int start_firewall(void)
1552 DIR *dir;
1553 struct dirent *dirent;
1554 char s[256];
1555 char *c, *wanface;
1556 int n;
1557 int wanproto;
1558 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1559 #ifdef TCONFIG_IPV6
1560 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1561 #endif
1563 simple_lock("firewall");
1564 simple_lock("restrictions");
1566 wanup = check_wanup();
1568 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1570 /* NAT performance tweaks
1571 * These values can be overriden later if needed via firewall script
1573 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1574 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1575 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1576 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1577 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1578 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1579 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1580 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1581 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1582 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1583 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1584 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1586 /* DoS-related tweaks */
1587 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1588 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1589 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1591 wanproto = get_wan_proto();
1592 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1594 #ifdef TCONFIG_EMF
1595 /* Force IGMPv2 due EMF limitations */
1596 if (nvram_get_int("emf_enable")) {
1597 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1598 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1600 #endif
1602 n = nvram_get_int("log_in");
1603 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1604 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1606 n = nvram_get_int("log_out");
1607 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1608 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1609 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1611 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1613 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1614 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1615 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1616 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1618 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1619 wanface = wanfaces.iface[0].name;
1620 #ifdef TCONFIG_IPV6
1621 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1622 #endif
1624 #ifdef LINUX26
1625 can_enable_fastnat = 1;
1626 #endif
1628 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1629 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1630 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1632 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1633 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1634 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1636 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1637 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1638 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1640 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1641 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1642 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1646 block obviously spoofed IP addresses
1648 rp_filter - BOOLEAN
1649 1 - do source validation by reversed path, as specified in RFC1812
1650 Recommended option for single homed hosts and stub network
1651 routers. Could cause troubles for complicated (not loop free)
1652 networks running a slow unreliable protocol (sort of RIP),
1653 or using static routes.
1654 0 - No source validation.
1656 c = nvram_get("wan_ifname");
1657 /* mcast needs rp filter to be turned off only for non default iface */
1658 if (!(nvram_match("multicast_pass", "1")) || !(nvram_match("udpxy_enable", "1")) || strcmp(wanface, c) == 0) c = NULL;
1660 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1661 while ((dirent = readdir(dir)) != NULL) {
1662 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1663 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1665 closedir(dir);
1668 remotemanage = 0;
1669 gateway_mode = !nvram_match("wk_mode", "router");
1670 if (gateway_mode) {
1671 /* Remote management */
1672 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1673 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1675 if (nvram_match("remote_mgt_https", "1")) {
1676 web_lanport = nvram_get_int("https_lanport");
1677 if (web_lanport <= 0) web_lanport = 443;
1678 } else {
1679 web_lanport = nvram_get_int("http_lanport");
1680 if (web_lanport <= 0) web_lanport = 80;
1684 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1685 notice_set("iptables", "Unable to create iptables restore file");
1686 simple_unlock("firewall");
1687 return 0;
1690 #ifdef TCONFIG_IPV6
1691 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1692 notice_set("ip6tables", "Unable to create ip6tables restore file");
1693 simple_unlock("firewall");
1694 return 0;
1696 modprobe("nf_conntrack_ipv6");
1697 modprobe("ip6t_REJECT");
1698 #endif
1700 //shibby
1701 //if (nvram_match("imq_enable", "1")) {
1702 // char numdevs[10];
1703 // sprintf(numdevs, "numdevs=%d", nvram_get_int("imq_numdevs"));
1704 // modprobe("imq", numdevs );
1706 modprobe("imq");
1707 #ifdef LINUX26
1708 modprobe("xt_IMQ");
1709 #else
1710 modprobe("ipt_IMQ");
1711 #endif
1712 // }
1715 mangle_table();
1716 nat_table();
1717 filter_table();
1719 fclose(ipt_file);
1720 ipt_file = NULL;
1722 #ifdef TCONFIG_IPV6
1723 fclose(ip6t_file);
1724 ip6t_file = NULL;
1725 #endif
1727 #ifdef DEBUG_IPTFILE
1728 if (debug_only) {
1729 simple_unlock("firewall");
1730 simple_unlock("restrictions");
1731 return 0;
1733 #endif
1735 save_webmon();
1737 if (nvram_get_int("upnp_enable") & 3) {
1738 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1739 if (killall("miniupnpd", SIGUSR2) == 0) {
1740 f_wait_notexists("/etc/upnp/save", 5);
1744 notice_set("iptables", "");
1745 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1746 led(LED_DIAG, 0);
1747 notice_set("iptables", "");
1749 else {
1750 sprintf(s, "%s.error", ipt_fname);
1751 rename(ipt_fname, s);
1752 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1753 led(LED_DIAG, 1);
1757 -P INPUT DROP
1758 -F INPUT
1759 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1760 -A INPUT -i br0 -j ACCEPT
1762 -P FORWARD DROP
1763 -F FORWARD
1764 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1765 -A FORWARD -i br0 -j ACCEPT
1770 #ifdef TCONFIG_IPV6
1771 if (ipv6_enabled()) {
1772 notice_set("ip6tables", "");
1773 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1774 notice_set("ip6tables", "");
1776 else {
1777 sprintf(s, "%s.error", ip6t_fname);
1778 rename(ip6t_fname, s);
1779 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1780 led(LED_DIAG, 1);
1783 else {
1784 eval("ip6tables", "-F");
1785 eval("ip6tables", "-t", "mangle", "-F");
1787 #endif
1789 if (nvram_get_int("upnp_enable") & 3) {
1790 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1791 killall("miniupnpd", SIGUSR2);
1794 simple_unlock("restrictions");
1795 sched_restrictions();
1796 enable_ip_forward();
1798 led(LED_DMZ, dmz_dst(NULL));
1800 #ifdef TCONFIG_IPV6
1801 modprobe_r("nf_conntrack_ipv6");
1802 modprobe_r("ip6t_LOG");
1803 modprobe_r("ip6t_REJECT");
1804 #endif
1805 #ifdef LINUX26
1806 modprobe_r("xt_layer7");
1807 modprobe_r("xt_recent");
1808 modprobe_r("xt_HL");
1809 modprobe_r("xt_length");
1810 modprobe_r("xt_web");
1811 modprobe_r("xt_webmon");
1812 modprobe_r("xt_dscp");
1813 #else
1814 modprobe_r("ipt_layer7");
1815 modprobe_r("ipt_recent");
1816 modprobe_r("ipt_TTL");
1817 modprobe_r("ipt_web");
1818 modprobe_r("ipt_webmon");
1819 modprobe_r("ipt_dscp");
1820 #endif
1821 modprobe_r("ipt_ipp2p");
1823 unlink("/var/webmon/domain");
1824 unlink("/var/webmon/search");
1826 #ifdef TCONFIG_OPENVPN
1827 run_vpn_firewall_scripts();
1828 #endif
1829 run_nvscript("script_fire", NULL, 1);
1831 #ifdef LINUX26
1832 allow_fastnat("firewall", can_enable_fastnat);
1833 try_enabling_fastnat();
1834 #endif
1835 simple_unlock("firewall");
1836 return 0;
1839 int stop_firewall(void)
1841 led(LED_DMZ, 0);
1842 return 0;
1845 #ifdef DEBUG_IPTFILE
1846 void create_test_iptfile(void)
1848 debug_only = 1;
1849 start_firewall();
1850 debug_only = 0;
1852 #endif