cosmetics
[tomato.git] / release / src / router / rc / firewall.c
bloba8cdf346aa4f0717c6a14cdf6f9732f57d0f49d8
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 wanface_list_t wanfaces;
33 char lanface[IFNAMSIZ + 1];
34 #ifdef TCONFIG_IPV6
35 char wan6face[IFNAMSIZ + 1];
36 #endif
37 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
38 #ifdef LINUX26
39 static int can_enable_fastnat;
40 #endif
42 #ifdef DEBUG_IPTFILE
43 static int debug_only = 0;
44 #endif
46 static int gateway_mode;
47 static int remotemanage;
48 static int wanup;
50 const char *chain_in_drop;
51 const char *chain_in_accept;
52 const char *chain_out_drop;
53 const char *chain_out_accept;
54 const char *chain_out_reject;
56 const char chain_wan_prerouting[] = "WANPREROUTING";
57 const char ipt_fname[] = "/etc/iptables";
58 FILE *ipt_file;
60 #ifdef TCONFIG_IPV6
61 const char ip6t_fname[] = "/etc/ip6tables";
62 FILE *ip6t_file;
64 // RFC-4890, sec. 4.3.1
65 const int allowed_icmpv6[] = { 1, 2, 3, 4, 128, 129 };
66 #endif
70 struct {
71 } firewall_data;
74 // -----------------------------------------------------------------------------
76 #ifdef LINUX26
77 static const char *fastnat_run_dir = "/var/run/fastnat";
79 void allow_fastnat(const char *service, int allow)
81 char p[128];
83 snprintf(p, sizeof(p), "%s/%s", fastnat_run_dir, service);
84 if (allow) {
85 unlink(p);
87 else {
88 mkdir_if_none(fastnat_run_dir);
89 f_write_string(p, "", 0, 0);
93 static inline int fastnat_allowed(void)
95 DIR *dir;
96 struct dirent *dp;
97 int enabled;
99 enabled = !nvram_get_int("qos_enable") && !nvram_get_int("fastnat_disable");
101 if (enabled && (dir = opendir(fastnat_run_dir))) {
102 while ((dp = readdir(dir))) {
103 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
104 continue;
105 enabled = 0;
106 break;
108 closedir(dir);
111 return (enabled);
114 void try_enabling_fastnat(void)
116 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_fastnat",
117 fastnat_allowed() ? "1" : "0", 0, 0);
119 #endif
121 void enable_ip_forward(void)
124 ip_forward - BOOLEAN
125 0 - disabled (default)
126 not 0 - enabled
128 Forward Packets between interfaces.
130 This variable is special, its change resets all configuration
131 parameters to their default state (RFC1122 for hosts, RFC1812
132 for routers)
134 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
136 #ifdef TCONFIG_IPV6
137 if (ipv6_enabled()) {
138 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
139 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
141 #endif
145 // -----------------------------------------------------------------------------
148 static int ip2cclass(char *ipaddr, char *new, int count)
150 int ip[4];
152 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
153 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
158 static int dmz_dst(char *s)
160 struct in_addr ia;
161 char *p;
162 int n;
164 if (nvram_get_int("dmz_enable") <= 0) return 0;
166 p = nvram_safe_get("dmz_ipaddr");
167 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
168 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
169 if (s) sprintf(s, "%s%d", lan_cclass, n);
170 return 1;
173 if (s) strcpy(s, inet_ntoa(ia));
174 return 1;
177 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
179 char *pre, *post;
181 pre = (name && *name) ? " for \"" : "";
182 post = (name && *name) ? "\"" : "";
184 syslog(LOG_WARNING, "firewall: "
185 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
186 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
189 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
190 int strict, const char *categ, const char *name)
192 char p[INET6_ADDRSTRLEN * 2];
193 int r = 0;
195 if ((s) && (*s) && (*dir))
197 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
198 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
199 r = IPT_V4;
201 #ifdef TCONFIG_IPV6
202 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
203 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
204 r = IPT_V6;
206 #endif
207 else {
208 snprintf(addr, maxlen, "-%c %s", dir[0], s);
209 if (sscanf(s, "%[^/]/", p)) {
210 #ifdef TCONFIG_IPV6
211 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
212 #else
213 r = host_addrtypes(p, IPT_V4);
214 #endif
218 else
220 *addr = 0;
221 r = (IPT_V4 | IPT_V6);
224 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
225 ipt_log_unresolved(s, categ, name,
226 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
229 return (r & af);
232 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
233 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
234 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
237 static void get_src(const char *nv, char *src)
239 char *p;
241 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
242 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
244 else {
245 *src = 0;
250 void ipt_write(const char *format, ...)
252 va_list args;
254 va_start(args, format);
255 vfprintf(ipt_file, format, args);
256 va_end(args);
259 void ip6t_write(const char *format, ...)
261 #ifdef TCONFIG_IPV6
262 va_list args;
264 va_start(args, format);
265 vfprintf(ip6t_file, format, args);
266 va_end(args);
267 #endif
270 // -----------------------------------------------------------------------------
272 int ipt_dscp(const char *v, char *opt)
274 unsigned int n;
276 if (*v == 0) {
277 *opt = 0;
278 return 0;
281 n = strtoul(v, NULL, 0);
282 if (n > 63) n = 63;
283 sprintf(opt, " -m dscp --dscp 0x%02X", n);
285 #ifdef LINUX26
286 modprobe("xt_dscp");
287 #else
288 modprobe("ipt_dscp");
289 #endif
290 return 1;
293 // -----------------------------------------------------------------------------
296 int ipt_ipp2p(const char *v, char *opt)
298 int n = atoi(v);
300 if (n == 0) {
301 *opt = 0;
302 return 0;
305 strcpy(opt, "-m ipp2p ");
306 if ((n & 0xFFF) == 0xFFF) {
307 strcat(opt, "--ipp2p");
309 else {
310 // x12
311 if (n & 0x0001) strcat(opt, "--apple ");
312 if (n & 0x0002) strcat(opt, "--ares ");
313 if (n & 0x0004) strcat(opt, "--bit ");
314 if (n & 0x0008) strcat(opt, "--dc ");
315 if (n & 0x0010) strcat(opt, "--edk ");
316 if (n & 0x0020) strcat(opt, "--gnu ");
317 if (n & 0x0040) strcat(opt, "--kazaa ");
318 if (n & 0x0080) strcat(opt, "--mute ");
319 if (n & 0x0100) strcat(opt, "--soul ");
320 if (n & 0x0200) strcat(opt, "--waste ");
321 if (n & 0x0400) strcat(opt, "--winmx ");
322 if (n & 0x0800) strcat(opt, "--xdcc ");
325 modprobe("ipt_ipp2p");
326 return 1;
330 // -----------------------------------------------------------------------------
333 char **layer7_in;
335 // This L7 matches inbound traffic, caches the results, then the L7 outbound
336 // should read the cached result and set the appropriate marks -- zzz
337 void ipt_layer7_inbound(void)
339 int en, i;
340 char **p;
342 if (!layer7_in) return;
344 en = nvram_match("nf_l7in", "1");
345 if (en) {
346 ipt_write(":L7in - [0:0]\n");
347 for (i = 0; i < wanfaces.count; ++i) {
348 if (*(wanfaces.iface[i].name)) {
349 ipt_write("-A FORWARD -i %s -j L7in\n",
350 wanfaces.iface[i].name);
355 p = layer7_in;
356 while (*p) {
357 if (en) {
358 ipt_write("-A L7in %s -j RETURN\n", *p);
359 #ifdef LINUX26
360 can_enable_fastnat = 0;
361 #endif
363 free(*p);
364 ++p;
366 free(layer7_in);
367 layer7_in = NULL;
370 int ipt_layer7(const char *v, char *opt)
372 char s[128];
373 char *path;
375 *opt = 0;
376 if (*v == 0) return 0;
377 if (strlen(v) > 32) return -1;
379 path = "/etc/l7-extra";
380 sprintf(s, "%s/%s.pat", path, v);
381 if (!f_exists(s)) {
382 path = "/etc/l7-protocols";
383 sprintf(s, "%s/%s.pat", path, v);
384 if (!f_exists(s)) {
385 syslog(LOG_ERR, "L7 %s was not found", v);
386 return -1;
390 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
392 if (nvram_match("nf_l7in", "1")) {
393 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
394 if (layer7_in) {
395 char **p;
397 p = layer7_in;
398 while (*p) {
399 if (strcmp(*p, opt) == 0) return 1;
400 ++p;
402 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
406 #ifdef LINUX26
407 modprobe("xt_layer7");
408 #else
409 modprobe("ipt_layer7");
410 #endif
411 return 1;
415 // -----------------------------------------------------------------------------
417 static void save_webmon(void)
419 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
420 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
423 static void ipt_webmon()
425 int wmtype, clear, i;
426 char t[512];
427 char src[128];
428 char *p, *c;
429 int ok;
431 if (!nvram_get_int("log_wm")) return;
433 #ifdef LINUX26
434 can_enable_fastnat = 0;
435 #endif
436 wmtype = nvram_get_int("log_wmtype");
437 clear = nvram_get_int("log_wmclear");
439 ip46t_write(":monitor - [0:0]\n");
441 // include IPs
442 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
443 p = t;
444 do {
445 if ((c = strchr(p, ',')) != NULL) *c = 0;
447 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
448 #ifdef TCONFIG_IPV6
449 if (*wan6face && (ok & IPT_V6))
450 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
451 #endif
452 if (ok & IPT_V4) {
453 for (i = 0; i < wanfaces.count; ++i) {
454 if (*(wanfaces.iface[i].name)) {
455 ipt_write("-A FORWARD -o %s %s -j monitor\n",
456 wanfaces.iface[i].name, src);
462 if (!c) break;
463 p = c + 1;
464 } while (*p);
466 // exclude IPs
467 if (wmtype == 2) {
468 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
469 p = t;
470 do {
471 if ((c = strchr(p, ',')) != NULL) *c = 0;
472 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
473 if (*src)
474 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
476 if (!c) break;
477 p = c + 1;
478 } while (*p);
481 ip46t_write(
482 "-A monitor -p tcp -m webmon "
483 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
484 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
485 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
486 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
488 #ifdef LINUX26
489 modprobe("xt_webmon");
490 #else
491 modprobe("ipt_webmon");
492 #endif
496 // -----------------------------------------------------------------------------
497 // MANGLE
498 // -----------------------------------------------------------------------------
500 static void mangle_table(void)
502 int ttl;
503 char *p, *wanface;
505 ip46t_write(
506 "*mangle\n"
507 ":PREROUTING ACCEPT [0:0]\n"
508 ":OUTPUT ACCEPT [0:0]\n");
510 if (wanup) {
512 ipt_qos();
513 //1 for mangle
514 ipt_qoslimit(1);
516 p = nvram_safe_get("nf_ttl");
517 if (strncmp(p, "c:", 2) == 0) {
518 p += 2;
519 ttl = atoi(p);
520 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
522 else if ((ttl = atoi(p)) != 0) {
523 if (ttl > 0) {
524 p = "inc";
526 else {
527 ttl = -ttl;
528 p = "dec";
530 if (ttl > 255) p = NULL;
532 else p = NULL;
534 if (p) {
535 #ifdef LINUX26
536 modprobe("xt_HL");
537 #else
538 modprobe("ipt_TTL");
539 #endif
540 // set TTL on primary WAN iface only
541 wanface = wanfaces.iface[0].name;
542 ipt_write(
543 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
544 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
545 wanface, p, ttl,
546 wanface, p, ttl);
547 #ifdef TCONFIG_IPV6
548 // FIXME: IPv6 HL should be configurable separately from TTL.
549 // disable it until GUI setting is implemented.
550 #if 0
551 ip6t_write(
552 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
553 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
554 wan6face, p, ttl,
555 wan6face, p, ttl);
556 #endif
557 #endif
561 ip46t_write("COMMIT\n");
564 // -----------------------------------------------------------------------------
565 // NAT
566 // -----------------------------------------------------------------------------
568 static void nat_table(void)
570 char lanaddr[32];
571 char lanmask[32];
572 char dst[64];
573 char src[64];
574 char t[512];
575 char *p, *c;
576 int i;
578 ipt_write("*nat\n"
579 ":PREROUTING ACCEPT [0:0]\n"
580 ":POSTROUTING ACCEPT [0:0]\n"
581 ":OUTPUT ACCEPT [0:0]\n"
582 ":%s - [0:0]\n",
583 chain_wan_prerouting);
585 //2 for nat
586 ipt_qoslimit(2);
588 if (gateway_mode) {
589 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
590 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
592 for (i = 0; i < wanfaces.count; ++i) {
593 if (*(wanfaces.iface[i].name)) {
594 // Drop incoming packets which destination IP address is to our LAN side directly
595 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
596 wanfaces.iface[i].name,
597 lanaddr, lanmask); // note: ipt will correct lanaddr
599 // chain_wan_prerouting
600 if (wanup) {
601 ipt_write("-A PREROUTING -d %s -j %s\n",
602 wanfaces.iface[i].ip, chain_wan_prerouting);
607 if (wanup) {
608 if (nvram_match("dns_intcpt", "1")) {
609 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
610 lanaddr, lanmask,
611 lanaddr, lanmask,
612 lanaddr);
615 // ICMP packets are always redirected to INPUT chains
616 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
618 ipt_forward(IPT_TABLE_NAT);
619 ipt_triggered(IPT_TABLE_NAT);
622 if (nvram_get_int("upnp_enable") & 3) {
623 ipt_write(":upnp - [0:0]\n");
625 for (i = 0; i < wanfaces.count; ++i) {
626 if (*(wanfaces.iface[i].name)) {
627 if (wanup) {
628 // ! for loopback (all) to work
629 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces.iface[i].ip);
631 else {
632 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
638 if (wanup) {
639 if (dmz_dst(dst)) {
640 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
641 p = t;
642 do {
643 if ((c = strchr(p, ',')) != NULL) *c = 0;
644 if (ipt_source_strict(p, src, "dmz", NULL))
645 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
646 if (!c) break;
647 p = c + 1;
648 } while (*p);
652 p = "";
653 #ifdef TCONFIG_IPV6
654 switch (get_ipv6_service()) {
655 case IPV6_6IN4:
656 // avoid NATing proto-41 packets when using 6in4 tunnel
657 p = "-p ! 41";
658 break;
660 #endif
662 for (i = 0; i < wanfaces.count; ++i) {
663 if (*(wanfaces.iface[i].name)) {
664 if ((!wanup) || (nvram_get_int("net_snat") != 1))
665 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
666 else
667 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
671 switch (nvram_get_int("nf_loopback")) {
672 case 1: // 1 = forwarded-only
673 case 2: // 2 = disable
674 break;
675 default: // 0 = all (same as block_loopback=0)
676 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
677 lanface,
678 lanaddr, lanmask,
679 lanaddr, lanmask,
680 lanaddr);
681 break;
684 ipt_write("COMMIT\n");
687 // -----------------------------------------------------------------------------
688 // FILTER
689 // -----------------------------------------------------------------------------
691 static void filter_input(void)
693 char s[64];
694 char t[512];
695 char *en;
696 char *sec;
697 char *hit;
698 int n;
699 char *p, *c;
701 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
702 for (n = 0; n < wanfaces.count; ++n) {
703 if (*(wanfaces.iface[n].name)) {
704 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
709 ipt_write(
710 "-A INPUT -m state --state INVALID -j DROP\n"
711 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
713 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
714 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
716 ? what if the user uses the start button in GUI ?
717 if (nvram_get_int("telnetd_eas"))
718 if (nvram_get_int("sshd_eas"))
720 #ifdef LINUX26
721 modprobe("xt_recent");
722 #else
723 modprobe("ipt_recent");
724 #endif
726 ipt_write(
727 "-N shlimit\n"
728 "-A shlimit -m recent --set --name shlimit\n"
729 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
730 atoi(hit) + 1, sec, chain_in_drop);
732 if (n & 1) {
733 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
734 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
735 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
738 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
741 #ifdef TCONFIG_FTP
742 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
743 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
744 #ifdef LINUX26
745 modprobe("xt_recent");
746 #else
747 modprobe("ipt_recent");
748 #endif
750 ipt_write(
751 "-N ftplimit\n"
752 "-A ftplimit -m recent --set --name ftp\n"
753 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
754 atoi(hit) + 1, sec, chain_in_drop);
755 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
757 #endif
759 ipt_write(
760 "-A INPUT -i %s -j ACCEPT\n"
761 "-A INPUT -i lo -j ACCEPT\n",
762 lanface);
764 #ifdef TCONFIG_IPV6
765 n = get_ipv6_service();
766 switch (n) {
767 case IPV6_ANYCAST_6TO4:
768 case IPV6_6IN4:
769 // Accept ICMP requests from the remote tunnel endpoint
770 if (n == IPV6_ANYCAST_6TO4)
771 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
772 else
773 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
774 if (*s && strcmp(s, "0.0.0.0") != 0)
775 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
776 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
777 break;
779 #endif
781 // ICMP request from WAN interface
782 if (nvram_match("block_wan", "0")) {
783 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
784 ipt_write("-A INPUT -p icmp -m limit --limit 1/second -j %s\n", chain_in_accept);
785 // allow udp traceroute packets
786 ipt_write("-A INPUT -p udp --dport 33434:33534 -m limit --limit 5/second -j %s\n", chain_in_accept);
789 /* Accept incoming packets from broken dhcp servers, which are sending replies
790 * from addresses other than used for query. This could lead to a lower level
791 * of security, so allow to disable it via nvram variable.
793 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
794 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
797 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
798 p = t;
799 do {
800 if ((c = strchr(p, ',')) != NULL) *c = 0;
802 if (ipt_source(p, s, "remote management", NULL)) {
804 if (remotemanage) {
805 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
806 s, nvram_safe_get("http_wanport"), chain_in_accept);
809 if (nvram_get_int("sshd_remote")) {
810 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
811 s, nvram_safe_get("sshd_rport"), chain_in_accept);
815 if (!c) break;
816 p = c + 1;
817 } while (*p);
819 #ifdef TCONFIG_FTP // !!TB - FTP Server
820 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
821 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
822 p = t;
823 do {
824 if ((c = strchr(p, ',')) != NULL) *c = 0;
825 if (ipt_source(p, s, "ftp", "remote access")) {
826 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
827 s, nvram_safe_get("ftp_port"), chain_in_accept);
829 if (!c) break;
830 p = c + 1;
831 } while (*p);
833 #endif
835 // IGMP query from WAN interface
836 if (nvram_match("multicast_pass", "1")) {
837 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
838 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
841 // Routing protocol, RIP, accept
842 if (nvram_invmatch("dr_wan_rx", "0")) {
843 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
846 // if logging
847 if (*chain_in_drop == 'l') {
848 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
851 // default policy: DROP
854 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
855 static void clampmss(void)
857 #if 1
858 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
859 #else
860 int rmtu = nvram_get_int("wan_run_mtu");
861 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu - 39);
862 if (rmtu < 576) {
863 ipt_write("--clamp-mss-to-pmtu\n");
865 else {
866 ipt_write("--set-mss %d\n", rmtu - 40);
868 #endif
871 static void filter_forward(void)
873 char dst[64];
874 char src[64];
875 char t[512];
876 char *p, *c;
877 int i;
879 #ifdef TCONFIG_IPV6
880 ip6t_write(
881 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
882 #endif
884 ip46t_write(
885 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
886 lanface, lanface);
888 // IPv4 only ?
889 ipt_write(
890 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
892 // clamp tcp mss to pmtu
893 clampmss();
895 if (wanup) {
896 ipt_restrictions();
898 ipt_layer7_inbound();
901 ipt_webmon();
903 ip46t_write(
904 ":wanin - [0:0]\n"
905 ":wanout - [0:0]\n"
906 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
908 #ifdef TCONFIG_IPV6
909 // Filter out invalid WAN->WAN connections
910 if (*wan6face)
911 ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face, lanface, chain_in_drop);
913 #ifdef LINUX26
914 modprobe("xt_length");
915 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
916 #endif
918 // ICMPv6 rules
919 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
920 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
923 if (*wan6face) {
924 ip6t_write(
925 "-A FORWARD -i %s -j wanin\n" // generic from wan
926 "-A FORWARD -o %s -j wanout\n", // generic to wan
927 wan6face, wan6face);
929 #endif
931 for (i = 0; i < wanfaces.count; ++i) {
932 if (*(wanfaces.iface[i].name)) {
933 ipt_write(
934 "-A FORWARD -i %s -j wanin\n" // generic from wan
935 "-A FORWARD -o %s -j wanout\n", // generic to wan
936 wanfaces.iface[i].name, wanfaces.iface[i].name);
940 ip46t_write("-A FORWARD -i %s -j %s\n", // from lan
941 lanface, chain_out_accept);
943 // IPv4 only
944 if (nvram_get_int("upnp_enable") & 3) {
945 ipt_write(":upnp - [0:0]\n");
946 for (i = 0; i < wanfaces.count; ++i) {
947 if (*(wanfaces.iface[i].name)) {
948 ipt_write("-A FORWARD -i %s -j upnp\n",
949 wanfaces.iface[i].name);
954 if (wanup) {
955 if (nvram_match("multicast_pass", "1")) {
956 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
958 ipt_triggered(IPT_TABLE_FILTER);
959 ipt_forward(IPT_TABLE_FILTER);
960 #ifdef TCONFIG_IPV6
961 ip6t_forward();
962 #endif
964 if (dmz_dst(dst)) {
965 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
966 p = t;
967 do {
968 if ((c = strchr(p, ',')) != NULL) *c = 0;
969 if (ipt_source_strict(p, src, "dmz", NULL))
970 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
971 if (!c) break;
972 p = c + 1;
973 } while (*p);
977 // default policy: DROP
980 static void filter_log(void)
982 int n;
983 char limit[128];
985 n = nvram_get_int("log_limit");
986 if ((n >= 1) && (n <= 9999)) {
987 sprintf(limit, "-m limit --limit %d/m", n);
989 else {
990 limit[0] = 0;
993 #ifdef TCONFIG_IPV6
994 modprobe("ip6t_LOG");
995 #endif
996 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
997 ip46t_write(
998 ":logdrop - [0:0]\n"
999 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1000 #ifdef LINUX26
1001 " --log-macdecode"
1002 #endif
1003 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1004 "-A logdrop -j DROP\n"
1005 ":logreject - [0:0]\n"
1006 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1007 #ifdef LINUX26
1008 " --log-macdecode"
1009 #endif
1010 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1011 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1012 limit, limit);
1014 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1015 ip46t_write(
1016 ":logaccept - [0:0]\n"
1017 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1018 #ifdef LINUX26
1019 " --log-macdecode"
1020 #endif
1021 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1022 "-A logaccept -j ACCEPT\n",
1023 limit);
1027 #ifdef TCONFIG_IPV6
1028 static void filter6_input(void)
1030 char s[128];
1031 char t[512];
1032 char *en;
1033 char *sec;
1034 char *hit;
1035 int n;
1036 char *p, *c;
1038 // RFC-4890, sec. 4.4.1
1039 const int allowed_local_icmpv6[] =
1040 { 130, 131, 132, 133, 134, 135, 136,
1041 141, 142, 143,
1042 148, 149, 151, 152, 153 };
1044 ip6t_write(
1045 "-A INPUT -m rt --rt-type 0 -j %s\n"
1046 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1047 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1048 chain_in_drop);
1050 #ifdef LINUX26
1051 modprobe("xt_length");
1052 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1053 #endif
1055 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1056 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1057 #ifdef LINUX26
1058 modprobe("xt_recent");
1059 #else
1060 modprobe("ipt_recent");
1061 #endif
1063 ip6t_write(
1064 "-N shlimit\n"
1065 "-A shlimit -m recent --set --name shlimit\n"
1066 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1067 atoi(hit) + 1, sec, chain_in_drop);
1069 if (n & 1) {
1070 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1071 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1072 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1075 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"));
1078 #ifdef TCONFIG_FTP
1079 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1080 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1081 #ifdef LINUX26
1082 modprobe("xt_recent");
1083 #else
1084 modprobe("ipt_recent");
1085 #endif
1087 ip6t_write(
1088 "-N ftplimit\n"
1089 "-A ftplimit -m recent --set --name ftp\n"
1090 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1091 atoi(hit) + 1, sec, chain_in_drop);
1092 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1094 #endif // TCONFIG_FTP
1096 ip6t_write(
1097 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1098 "-A INPUT -i lo -j ACCEPT\n",
1099 lanface );
1101 switch (get_ipv6_service()) {
1102 case IPV6_ANYCAST_6TO4:
1103 case IPV6_NATIVE_DHCP:
1104 // allow responses from the dhcpv6 server
1105 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1106 break;
1109 // ICMPv6 rules
1110 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1111 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1113 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1114 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1117 // Remote Managment
1118 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1119 p = t;
1120 do {
1121 if ((c = strchr(p, ',')) != NULL) *c = 0;
1123 if (ip6t_source(p, s, "remote management", NULL)) {
1125 if (remotemanage) {
1126 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1127 s, nvram_safe_get("http_wanport"), chain_in_accept);
1130 if (nvram_get_int("sshd_remote")) {
1131 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1132 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1136 if (!c) break;
1137 p = c + 1;
1138 } while (*p);
1140 #ifdef TCONFIG_FTP
1141 // FTP server
1142 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1143 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1144 p = t;
1145 do {
1146 if ((c = strchr(p, ',')) != NULL) *c = 0;
1147 if (ip6t_source(p, s, "ftp", "remote access")) {
1148 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1149 s, nvram_safe_get("ftp_port"), chain_in_accept);
1151 if (!c) break;
1152 p = c + 1;
1153 } while (*p);
1155 #endif
1157 // if logging
1158 if (*chain_in_drop == 'l') {
1159 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1162 // default policy: DROP
1165 #endif
1167 static void filter_table(void)
1169 ip46t_write(
1170 "*filter\n"
1171 ":INPUT DROP [0:0]\n"
1172 ":OUTPUT ACCEPT [0:0]\n"
1175 filter_log();
1177 filter_input();
1178 #ifdef TCONFIG_IPV6
1179 filter6_input();
1180 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1181 #endif
1183 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1184 ip46t_write(":FORWARD DROP [0:0]\n");
1185 filter_forward();
1187 else {
1188 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1189 clampmss();
1191 ip46t_write("COMMIT\n");
1195 // -----------------------------------------------------------------------------
1197 int start_firewall(void)
1199 DIR *dir;
1200 struct dirent *dirent;
1201 char s[256];
1202 char *c, *wanface;
1203 int n;
1204 int wanproto;
1205 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1206 #ifdef TCONFIG_IPV6
1207 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1208 #endif
1210 simple_lock("firewall");
1211 simple_lock("restrictions");
1213 wanup = check_wanup();
1215 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1217 /* NAT performance tweaks
1218 * These values can be overriden later if needed via firewall script
1220 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1221 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1222 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1223 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1224 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1225 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1226 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1227 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1228 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1229 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1230 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1231 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1233 /* DoS-related tweaks */
1234 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1235 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1236 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1238 wanproto = get_wan_proto();
1239 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1241 #ifdef TCONFIG_EMF
1242 /* Force IGMPv2 due EMF limitations */
1243 if (nvram_get_int("emf_enable")) {
1244 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1245 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1247 #endif
1249 n = nvram_get_int("log_in");
1250 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1251 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1253 n = nvram_get_int("log_out");
1254 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1255 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1256 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1258 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1260 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1262 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1263 wanface = wanfaces.iface[0].name;
1264 #ifdef TCONFIG_IPV6
1265 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1266 #endif
1268 #ifdef LINUX26
1269 can_enable_fastnat = 1;
1270 #endif
1272 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1273 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1274 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1277 block obviously spoofed IP addresses
1279 rp_filter - BOOLEAN
1280 1 - do source validation by reversed path, as specified in RFC1812
1281 Recommended option for single homed hosts and stub network
1282 routers. Could cause troubles for complicated (not loop free)
1283 networks running a slow unreliable protocol (sort of RIP),
1284 or using static routes.
1285 0 - No source validation.
1287 c = nvram_get("wan_ifname");
1288 /* mcast needs rp filter to be turned off only for non default iface */
1289 if (!(nvram_match("multicast_pass", "1")) || strcmp(wanface, c) == 0) c = NULL;
1291 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1292 while ((dirent = readdir(dir)) != NULL) {
1293 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1294 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1296 closedir(dir);
1299 remotemanage = 0;
1300 gateway_mode = !nvram_match("wk_mode", "router");
1301 if (gateway_mode) {
1302 /* Remote management */
1303 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1304 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1307 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1308 notice_set("iptables", "Unable to create iptables restore file");
1309 simple_unlock("firewall");
1310 return 0;
1313 #ifdef TCONFIG_IPV6
1314 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1315 notice_set("ip6tables", "Unable to create ip6tables restore file");
1316 simple_unlock("firewall");
1317 return 0;
1319 modprobe("nf_conntrack_ipv6");
1320 modprobe("ip6t_REJECT");
1321 #endif
1322 /*Deon Thomas attempt to start xt_IMQ and imq */
1323 /*shibby - fix modprobing IMQ for kernel 2.4 */
1324 modprobe("imq");
1325 #ifdef LINUX26
1326 modprobe("xt_IMQ");
1327 #else
1328 modprobe("ipt_IMQ");
1329 #endif
1331 mangle_table();
1332 nat_table();
1333 filter_table();
1335 fclose(ipt_file);
1336 ipt_file = NULL;
1338 #ifdef TCONFIG_IPV6
1339 fclose(ip6t_file);
1340 ip6t_file = NULL;
1341 #endif
1343 #ifdef DEBUG_IPTFILE
1344 if (debug_only) {
1345 simple_unlock("firewall");
1346 simple_unlock("restrictions");
1347 return 0;
1349 #endif
1351 save_webmon();
1353 if (nvram_get_int("upnp_enable") & 3) {
1354 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1355 if (killall("miniupnpd", SIGUSR2) == 0) {
1356 f_wait_notexists("/etc/upnp/save", 5);
1360 notice_set("iptables", "");
1361 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1362 led(LED_DIAG, 0);
1363 notice_set("iptables", "");
1365 else {
1366 sprintf(s, "%s.error", ipt_fname);
1367 rename(ipt_fname, s);
1368 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1369 led(LED_DIAG, 1);
1373 -P INPUT DROP
1374 -F INPUT
1375 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1376 -A INPUT -i br0 -j ACCEPT
1378 -P FORWARD DROP
1379 -F FORWARD
1380 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1381 -A FORWARD -i br0 -j ACCEPT
1386 #ifdef TCONFIG_IPV6
1387 if (ipv6_enabled()) {
1388 notice_set("ip6tables", "");
1389 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1390 notice_set("ip6tables", "");
1392 else {
1393 sprintf(s, "%s.error", ip6t_fname);
1394 rename(ip6t_fname, s);
1395 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1396 led(LED_DIAG, 1);
1399 else {
1400 eval("ip6tables", "-F");
1401 eval("ip6tables", "-t", "mangle", "-F");
1403 #endif
1405 if (nvram_get_int("upnp_enable") & 3) {
1406 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1407 killall("miniupnpd", SIGUSR2);
1410 simple_unlock("restrictions");
1411 sched_restrictions();
1412 enable_ip_forward();
1414 led(LED_DMZ, dmz_dst(NULL));
1416 #ifdef TCONFIG_IPV6
1417 modprobe_r("nf_conntrack_ipv6");
1418 modprobe_r("ip6t_LOG");
1419 modprobe_r("ip6t_REJECT");
1420 #endif
1421 #ifdef LINUX26
1422 modprobe_r("xt_layer7");
1423 modprobe_r("xt_recent");
1424 modprobe_r("xt_HL");
1425 modprobe_r("xt_length");
1426 modprobe_r("xt_web");
1427 modprobe_r("xt_webmon");
1428 modprobe_r("xt_dscp");
1429 #else
1430 modprobe_r("ipt_layer7");
1431 modprobe_r("ipt_recent");
1432 modprobe_r("ipt_TTL");
1433 modprobe_r("ipt_web");
1434 modprobe_r("ipt_webmon");
1435 modprobe_r("ipt_dscp");
1436 #endif
1437 modprobe_r("ipt_ipp2p");
1439 unlink("/var/webmon/domain");
1440 unlink("/var/webmon/search");
1442 #ifdef TCONFIG_OPENVPN
1443 run_vpn_firewall_scripts();
1444 #endif
1445 run_nvscript("script_fire", NULL, 1);
1447 #ifdef LINUX26
1448 allow_fastnat("firewall", can_enable_fastnat);
1449 try_enabling_fastnat();
1450 #endif
1452 start_bwclimon();
1454 simple_unlock("firewall");
1455 return 0;
1458 int stop_firewall(void)
1460 led(LED_DMZ, 0);
1461 return 0;
1464 #ifdef DEBUG_IPTFILE
1465 void create_test_iptfile(void)
1467 debug_only = 1;
1468 start_firewall();
1469 debug_only = 0;
1471 #endif