Merge branch 'tomato-RT' into Toastman-RT
[tomato.git] / release / src / router / rc / firewall.c
blob4900eb6da8fa8ad57a3f327d1732778863d554e6
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 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
858 #ifdef TCONFIG_IPV6
859 switch (get_ipv6_service()) {
860 case IPV6_ANYCAST_6TO4:
861 case IPV6_6IN4:
862 ip6t_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
863 break;
865 #endif
868 static void filter_forward(void)
870 char dst[64];
871 char src[64];
872 char t[512];
873 char *p, *c;
874 int i;
876 #ifdef TCONFIG_IPV6
877 ip6t_write(
878 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
879 #endif
881 ip46t_write(
882 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
883 lanface, lanface);
885 // IPv4 only ?
886 ipt_write(
887 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
889 // clamp tcp mss to pmtu
890 clampmss();
892 if (wanup) {
893 ipt_restrictions();
895 ipt_layer7_inbound();
898 ipt_webmon();
900 ip46t_write(
901 ":wanin - [0:0]\n"
902 ":wanout - [0:0]\n"
903 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
905 #ifdef TCONFIG_IPV6
906 // Filter out invalid WAN->WAN connections
907 if (*wan6face)
908 ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face, lanface, chain_in_drop);
910 #ifdef LINUX26
911 modprobe("xt_length");
912 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
913 #endif
915 // ICMPv6 rules
916 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
917 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
920 if (*wan6face) {
921 ip6t_write(
922 "-A FORWARD -i %s -j wanin\n" // generic from wan
923 "-A FORWARD -o %s -j wanout\n", // generic to wan
924 wan6face, wan6face);
926 #endif
928 for (i = 0; i < wanfaces.count; ++i) {
929 if (*(wanfaces.iface[i].name)) {
930 ipt_write(
931 "-A FORWARD -i %s -j wanin\n" // generic from wan
932 "-A FORWARD -o %s -j wanout\n", // generic to wan
933 wanfaces.iface[i].name, wanfaces.iface[i].name);
937 ip46t_write("-A FORWARD -i %s -j %s\n", // from lan
938 lanface, chain_out_accept);
940 // IPv4 only
941 if (nvram_get_int("upnp_enable") & 3) {
942 ipt_write(":upnp - [0:0]\n");
943 for (i = 0; i < wanfaces.count; ++i) {
944 if (*(wanfaces.iface[i].name)) {
945 ipt_write("-A FORWARD -i %s -j upnp\n",
946 wanfaces.iface[i].name);
951 if (wanup) {
952 if (nvram_match("multicast_pass", "1")) {
953 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
955 ipt_triggered(IPT_TABLE_FILTER);
956 ipt_forward(IPT_TABLE_FILTER);
957 #ifdef TCONFIG_IPV6
958 ip6t_forward();
959 #endif
961 if (dmz_dst(dst)) {
962 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
963 p = t;
964 do {
965 if ((c = strchr(p, ',')) != NULL) *c = 0;
966 if (ipt_source_strict(p, src, "dmz", NULL))
967 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
968 if (!c) break;
969 p = c + 1;
970 } while (*p);
974 // default policy: DROP
977 static void filter_log(void)
979 int n;
980 char limit[128];
982 n = nvram_get_int("log_limit");
983 if ((n >= 1) && (n <= 9999)) {
984 sprintf(limit, "-m limit --limit %d/m", n);
986 else {
987 limit[0] = 0;
990 #ifdef TCONFIG_IPV6
991 modprobe("ip6t_LOG");
992 #endif
993 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
994 ip46t_write(
995 ":logdrop - [0:0]\n"
996 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
997 #ifdef LINUX26
998 " --log-macdecode"
999 #endif
1000 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1001 "-A logdrop -j DROP\n"
1002 ":logreject - [0:0]\n"
1003 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1004 #ifdef LINUX26
1005 " --log-macdecode"
1006 #endif
1007 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1008 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1009 limit, limit);
1011 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1012 ip46t_write(
1013 ":logaccept - [0:0]\n"
1014 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1015 #ifdef LINUX26
1016 " --log-macdecode"
1017 #endif
1018 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1019 "-A logaccept -j ACCEPT\n",
1020 limit);
1024 #ifdef TCONFIG_IPV6
1025 static void filter6_input(void)
1027 char s[128];
1028 char t[512];
1029 char *en;
1030 char *sec;
1031 char *hit;
1032 int n;
1033 char *p, *c;
1035 // RFC-4890, sec. 4.4.1
1036 const int allowed_local_icmpv6[] =
1037 { 130, 131, 132, 133, 134, 135, 136,
1038 141, 142, 143,
1039 148, 149, 151, 152, 153 };
1041 ip6t_write(
1042 "-A INPUT -m rt --rt-type 0 -j %s\n"
1043 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1044 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1045 chain_in_drop);
1047 #ifdef LINUX26
1048 modprobe("xt_length");
1049 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1050 #endif
1052 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1053 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1054 #ifdef LINUX26
1055 modprobe("xt_recent");
1056 #else
1057 modprobe("ipt_recent");
1058 #endif
1060 ip6t_write(
1061 "-N shlimit\n"
1062 "-A shlimit -m recent --set --name shlimit\n"
1063 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1064 atoi(hit) + 1, sec, chain_in_drop);
1066 if (n & 1) {
1067 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1068 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1069 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1072 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"));
1075 #ifdef TCONFIG_FTP
1076 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1077 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1078 #ifdef LINUX26
1079 modprobe("xt_recent");
1080 #else
1081 modprobe("ipt_recent");
1082 #endif
1084 ip6t_write(
1085 "-N ftplimit\n"
1086 "-A ftplimit -m recent --set --name ftp\n"
1087 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1088 atoi(hit) + 1, sec, chain_in_drop);
1089 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1091 #endif // TCONFIG_FTP
1093 ip6t_write(
1094 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1095 "-A INPUT -i lo -j ACCEPT\n",
1096 lanface );
1098 switch (get_ipv6_service()) {
1099 case IPV6_ANYCAST_6TO4:
1100 case IPV6_NATIVE_DHCP:
1101 // allow responses from the dhcpv6 server
1102 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1103 break;
1106 // ICMPv6 rules
1107 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1108 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1110 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1111 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1114 // Remote Managment
1115 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1116 p = t;
1117 do {
1118 if ((c = strchr(p, ',')) != NULL) *c = 0;
1120 if (ip6t_source(p, s, "remote management", NULL)) {
1122 if (remotemanage) {
1123 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1124 s, nvram_safe_get("http_wanport"), chain_in_accept);
1127 if (nvram_get_int("sshd_remote")) {
1128 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1129 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1133 if (!c) break;
1134 p = c + 1;
1135 } while (*p);
1137 #ifdef TCONFIG_FTP
1138 // FTP server
1139 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1140 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1141 p = t;
1142 do {
1143 if ((c = strchr(p, ',')) != NULL) *c = 0;
1144 if (ip6t_source(p, s, "ftp", "remote access")) {
1145 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1146 s, nvram_safe_get("ftp_port"), chain_in_accept);
1148 if (!c) break;
1149 p = c + 1;
1150 } while (*p);
1152 #endif
1154 // if logging
1155 if (*chain_in_drop == 'l') {
1156 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1159 // default policy: DROP
1162 #endif
1164 static void filter_table(void)
1166 ip46t_write(
1167 "*filter\n"
1168 ":INPUT DROP [0:0]\n"
1169 ":OUTPUT ACCEPT [0:0]\n"
1172 filter_log();
1174 filter_input();
1175 #ifdef TCONFIG_IPV6
1176 filter6_input();
1177 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1178 #endif
1180 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1181 ip46t_write(":FORWARD DROP [0:0]\n");
1182 filter_forward();
1184 else {
1185 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1186 clampmss();
1188 ip46t_write("COMMIT\n");
1192 // -----------------------------------------------------------------------------
1194 int start_firewall(void)
1196 DIR *dir;
1197 struct dirent *dirent;
1198 char s[256];
1199 char *c, *wanface;
1200 int n;
1201 int wanproto;
1202 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1203 #ifdef TCONFIG_IPV6
1204 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1205 #endif
1207 simple_lock("firewall");
1208 simple_lock("restrictions");
1210 wanup = check_wanup();
1212 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1214 /* NAT performance tweaks
1215 * These values can be overriden later if needed via firewall script
1217 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1218 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1219 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1220 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1221 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1222 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1223 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1224 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1225 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1226 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1227 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1228 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1230 /* DoS-related tweaks */
1231 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1232 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1233 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1235 wanproto = get_wan_proto();
1236 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1238 #ifdef TCONFIG_EMF
1239 /* Force IGMPv2 due EMF limitations */
1240 if (nvram_get_int("emf_enable")) {
1241 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1242 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1244 #endif
1246 n = nvram_get_int("log_in");
1247 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1248 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1250 n = nvram_get_int("log_out");
1251 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1252 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1253 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1255 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1257 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1259 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1260 wanface = wanfaces.iface[0].name;
1261 #ifdef TCONFIG_IPV6
1262 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1263 #endif
1265 #ifdef LINUX26
1266 can_enable_fastnat = 1;
1267 #endif
1269 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1270 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1271 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1274 block obviously spoofed IP addresses
1276 rp_filter - BOOLEAN
1277 1 - do source validation by reversed path, as specified in RFC1812
1278 Recommended option for single homed hosts and stub network
1279 routers. Could cause troubles for complicated (not loop free)
1280 networks running a slow unreliable protocol (sort of RIP),
1281 or using static routes.
1282 0 - No source validation.
1284 c = nvram_get("wan_ifname");
1285 /* mcast needs rp filter to be turned off only for non default iface */
1286 if (!(nvram_match("multicast_pass", "1")) || strcmp(wanface, c) == 0) c = NULL;
1288 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1289 while ((dirent = readdir(dir)) != NULL) {
1290 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1291 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1293 closedir(dir);
1296 remotemanage = 0;
1297 gateway_mode = !nvram_match("wk_mode", "router");
1298 if (gateway_mode) {
1299 /* Remote management */
1300 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1301 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1304 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1305 notice_set("iptables", "Unable to create iptables restore file");
1306 simple_unlock("firewall");
1307 return 0;
1310 #ifdef TCONFIG_IPV6
1311 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1312 notice_set("ip6tables", "Unable to create ip6tables restore file");
1313 simple_unlock("firewall");
1314 return 0;
1316 modprobe("nf_conntrack_ipv6");
1317 modprobe("ip6t_REJECT");
1318 #endif
1319 /*Deon Thomas attempt to start xt_IMQ and imq */
1320 /*shibby - fix modprobing IMQ for kernel 2.4 */
1321 modprobe("imq");
1322 #ifdef LINUX26
1323 modprobe("xt_IMQ");
1324 #else
1325 modprobe("ipt_IMQ");
1326 #endif
1328 mangle_table();
1329 nat_table();
1330 filter_table();
1332 fclose(ipt_file);
1333 ipt_file = NULL;
1335 #ifdef TCONFIG_IPV6
1336 fclose(ip6t_file);
1337 ip6t_file = NULL;
1338 #endif
1340 #ifdef DEBUG_IPTFILE
1341 if (debug_only) {
1342 simple_unlock("firewall");
1343 simple_unlock("restrictions");
1344 return 0;
1346 #endif
1348 save_webmon();
1350 if (nvram_get_int("upnp_enable") & 3) {
1351 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1352 if (killall("miniupnpd", SIGUSR2) == 0) {
1353 f_wait_notexists("/etc/upnp/save", 5);
1357 notice_set("iptables", "");
1358 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1359 led(LED_DIAG, 0);
1360 notice_set("iptables", "");
1362 else {
1363 sprintf(s, "%s.error", ipt_fname);
1364 rename(ipt_fname, s);
1365 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1366 led(LED_DIAG, 1);
1370 -P INPUT DROP
1371 -F INPUT
1372 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1373 -A INPUT -i br0 -j ACCEPT
1375 -P FORWARD DROP
1376 -F FORWARD
1377 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1378 -A FORWARD -i br0 -j ACCEPT
1383 #ifdef TCONFIG_IPV6
1384 if (ipv6_enabled()) {
1385 notice_set("ip6tables", "");
1386 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1387 notice_set("ip6tables", "");
1389 else {
1390 sprintf(s, "%s.error", ip6t_fname);
1391 rename(ip6t_fname, s);
1392 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1393 led(LED_DIAG, 1);
1396 else {
1397 eval("ip6tables", "-F");
1398 eval("ip6tables", "-t", "mangle", "-F");
1400 #endif
1402 if (nvram_get_int("upnp_enable") & 3) {
1403 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1404 killall("miniupnpd", SIGUSR2);
1407 simple_unlock("restrictions");
1408 sched_restrictions();
1409 enable_ip_forward();
1411 led(LED_DMZ, dmz_dst(NULL));
1413 #ifdef TCONFIG_IPV6
1414 modprobe_r("nf_conntrack_ipv6");
1415 modprobe_r("ip6t_LOG");
1416 modprobe_r("ip6t_REJECT");
1417 #endif
1418 #ifdef LINUX26
1419 modprobe_r("xt_layer7");
1420 modprobe_r("xt_recent");
1421 modprobe_r("xt_HL");
1422 modprobe_r("xt_length");
1423 modprobe_r("xt_web");
1424 modprobe_r("xt_webmon");
1425 modprobe_r("xt_dscp");
1426 #else
1427 modprobe_r("ipt_layer7");
1428 modprobe_r("ipt_recent");
1429 modprobe_r("ipt_TTL");
1430 modprobe_r("ipt_web");
1431 modprobe_r("ipt_webmon");
1432 modprobe_r("ipt_dscp");
1433 #endif
1434 modprobe_r("ipt_ipp2p");
1436 unlink("/var/webmon/domain");
1437 unlink("/var/webmon/search");
1439 #ifdef TCONFIG_OPENVPN
1440 run_vpn_firewall_scripts();
1441 #endif
1442 run_nvscript("script_fire", NULL, 1);
1444 #ifdef LINUX26
1445 allow_fastnat("firewall", can_enable_fastnat);
1446 try_enabling_fastnat();
1447 #endif
1448 start_bwclimon();
1449 simple_unlock("firewall");
1450 return 0;
1453 int stop_firewall(void)
1455 led(LED_DMZ, 0);
1456 return 0;
1459 #ifdef DEBUG_IPTFILE
1460 void create_test_iptfile(void)
1462 debug_only = 1;
1463 start_firewall();
1464 debug_only = 0;
1466 #endif