Add gui for Comcast DSCP fix.
[tomato.git] / release / src / router / rc / firewall.c
blob81a8ae79e80dfa9611ec2ff6b9b937db76fa7cb2
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_VLAN
35 char lan1face[IFNAMSIZ + 1];
36 char lan2face[IFNAMSIZ + 1];
37 char lan3face[IFNAMSIZ + 1];
38 #endif
40 #ifdef TCONFIG_IPV6
41 char wan6face[IFNAMSIZ + 1];
42 #endif
43 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
44 #ifdef LINUX26
45 static int can_enable_fastnat;
46 #endif
48 #ifdef DEBUG_IPTFILE
49 static int debug_only = 0;
50 #endif
52 static int gateway_mode;
53 static int remotemanage;
54 static int wanup;
56 const char *chain_in_drop;
57 const char *chain_in_accept;
58 const char *chain_out_drop;
59 const char *chain_out_accept;
60 const char *chain_out_reject;
62 const char chain_wan_prerouting[] = "WANPREROUTING";
63 const char ipt_fname[] = "/etc/iptables";
64 FILE *ipt_file;
66 #ifdef TCONFIG_IPV6
67 const char ip6t_fname[] = "/etc/ip6tables";
68 FILE *ip6t_file;
70 // RFC-4890, sec. 4.3.1
71 const int allowed_icmpv6[] = { 1, 2, 3, 4, 128, 129 };
72 #endif
74 static int is_sta(int idx, int unit, int subunit, void *param)
76 return (nvram_match(wl_nvname("mode", unit, subunit), "sta") && (nvram_match(wl_nvname("bss_enabled", unit, subunit), "1")));
80 struct {
81 } firewall_data;
84 // -----------------------------------------------------------------------------
86 #ifdef LINUX26
87 static const char *fastnat_run_dir = "/var/run/fastnat";
89 void allow_fastnat(const char *service, int allow)
91 char p[128];
93 snprintf(p, sizeof(p), "%s/%s", fastnat_run_dir, service);
94 if (allow) {
95 unlink(p);
97 else {
98 mkdir_if_none(fastnat_run_dir);
99 f_write_string(p, "", 0, 0);
103 static inline int fastnat_allowed(void)
105 DIR *dir;
106 struct dirent *dp;
107 int enabled;
109 enabled = !nvram_get_int("qos_enable") && !nvram_get_int("fastnat_disable");
111 if (enabled && (dir = opendir(fastnat_run_dir))) {
112 while ((dp = readdir(dir))) {
113 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
114 continue;
115 enabled = 0;
116 break;
118 closedir(dir);
121 return (enabled);
124 void try_enabling_fastnat(void)
126 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_fastnat",
127 fastnat_allowed() ? "1" : "0", 0, 0);
129 #endif
131 void enable_ip_forward(void)
134 ip_forward - BOOLEAN
135 0 - disabled (default)
136 not 0 - enabled
138 Forward Packets between interfaces.
140 This variable is special, its change resets all configuration
141 parameters to their default state (RFC1122 for hosts, RFC1812
142 for routers)
144 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
148 #ifdef TCONFIG_IPV6
149 void enable_ip6_forward(void)
151 if (ipv6_enabled()) {
152 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
153 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
155 else {
156 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "0", 0, 0);
157 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "0", 0, 0);
160 #endif
163 // -----------------------------------------------------------------------------
166 static int ip2cclass(char *ipaddr, char *new, int count)
168 int ip[4];
170 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
171 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
176 static int dmz_dst(char *s)
178 struct in_addr ia;
179 char *p;
180 int n;
182 if (nvram_get_int("dmz_enable") <= 0) return 0;
184 p = nvram_safe_get("dmz_ipaddr");
185 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
186 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
187 if (s) sprintf(s, "%s%d", lan_cclass, n);
188 return 1;
191 if (s) strcpy(s, inet_ntoa(ia));
192 return 1;
195 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
197 char *pre, *post;
199 pre = (name && *name) ? " for \"" : "";
200 post = (name && *name) ? "\"" : "";
202 syslog(LOG_WARNING, "firewall: "
203 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
204 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
207 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
208 int strict, const char *categ, const char *name)
210 char p[INET6_ADDRSTRLEN * 2];
211 int r = 0;
213 if ((s) && (*s) && (*dir))
215 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
216 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
217 r = IPT_V4;
219 #ifdef TCONFIG_IPV6
220 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
221 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
222 r = IPT_V6;
224 #endif
225 else {
226 snprintf(addr, maxlen, "-%c %s", dir[0], s);
227 if (sscanf(s, "%[^/]/", p)) {
228 #ifdef TCONFIG_IPV6
229 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
230 #else
231 r = host_addrtypes(p, IPT_V4);
232 #endif
236 else
238 *addr = 0;
239 r = (IPT_V4 | IPT_V6);
242 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
243 ipt_log_unresolved(s, categ, name,
244 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
247 return (r & af);
250 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
251 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
252 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
255 static void get_src(const char *nv, char *src)
257 char *p;
259 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
260 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
262 else {
263 *src = 0;
268 void ipt_write(const char *format, ...)
270 va_list args;
272 va_start(args, format);
273 vfprintf(ipt_file, format, args);
274 va_end(args);
277 void ip6t_write(const char *format, ...)
279 #ifdef TCONFIG_IPV6
280 va_list args;
282 va_start(args, format);
283 vfprintf(ip6t_file, format, args);
284 va_end(args);
285 #endif
288 // -----------------------------------------------------------------------------
290 int ipt_dscp(const char *v, char *opt)
292 unsigned int n;
294 if (*v == 0) {
295 *opt = 0;
296 return 0;
299 n = strtoul(v, NULL, 0);
300 if (n > 63) n = 63;
301 sprintf(opt, " -m dscp --dscp 0x%02X", n);
303 #ifdef LINUX26
304 modprobe("xt_dscp");
305 #else
306 modprobe("ipt_dscp");
307 #endif
308 return 1;
311 // -----------------------------------------------------------------------------
314 int ipt_ipp2p(const char *v, char *opt)
316 int n = atoi(v);
318 if (n == 0) {
319 *opt = 0;
320 return 0;
323 strcpy(opt, "-m ipp2p ");
324 if ((n & 0xFFF) == 0xFFF) {
325 strcat(opt, "--ipp2p");
327 else {
328 // x12
329 if (n & 0x0001) strcat(opt, "--apple ");
330 if (n & 0x0002) strcat(opt, "--ares ");
331 if (n & 0x0004) strcat(opt, "--bit ");
332 if (n & 0x0008) strcat(opt, "--dc ");
333 if (n & 0x0010) strcat(opt, "--edk ");
334 if (n & 0x0020) strcat(opt, "--gnu ");
335 if (n & 0x0040) strcat(opt, "--kazaa ");
336 if (n & 0x0080) strcat(opt, "--mute ");
337 if (n & 0x0100) strcat(opt, "--soul ");
338 if (n & 0x0200) strcat(opt, "--waste ");
339 if (n & 0x0400) strcat(opt, "--winmx ");
340 if (n & 0x0800) strcat(opt, "--xdcc ");
341 #ifdef LINUX26
342 if (n & 0x1000) strcat(opt, "--pp ");
343 if (n & 0x2000) strcat(opt, "--xunlei ");
344 #endif
347 modprobe("ipt_ipp2p");
348 return 1;
352 // -----------------------------------------------------------------------------
355 char **layer7_in;
357 // This L7 matches inbound traffic, caches the results, then the L7 outbound
358 // should read the cached result and set the appropriate marks -- zzz
359 void ipt_layer7_inbound(void)
361 int en, i;
362 char **p;
364 if (!layer7_in) return;
366 en = nvram_match("nf_l7in", "1");
367 if (en) {
368 ipt_write(":L7in - [0:0]\n");
369 for (i = 0; i < wanfaces.count; ++i) {
370 if (*(wanfaces.iface[i].name)) {
371 ipt_write("-A FORWARD -i %s -j L7in\n",
372 wanfaces.iface[i].name);
377 p = layer7_in;
378 while (*p) {
379 if (en) {
380 ipt_write("-A L7in %s -j RETURN\n", *p);
381 #ifdef LINUX26
382 can_enable_fastnat = 0;
383 #endif
385 free(*p);
386 ++p;
388 free(layer7_in);
389 layer7_in = NULL;
392 int ipt_layer7(const char *v, char *opt)
394 char s[128];
395 char *path;
397 *opt = 0;
398 if (*v == 0) return 0;
399 if (strlen(v) > 32) return -1;
401 path = "/etc/l7-extra";
402 sprintf(s, "%s/%s.pat", path, v);
403 if (!f_exists(s)) {
404 path = "/etc/l7-protocols";
405 sprintf(s, "%s/%s.pat", path, v);
406 if (!f_exists(s)) {
407 syslog(LOG_ERR, "L7 %s was not found", v);
408 return -1;
412 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
414 if (nvram_match("nf_l7in", "1")) {
415 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
416 if (layer7_in) {
417 char **p;
419 p = layer7_in;
420 while (*p) {
421 if (strcmp(*p, opt) == 0) return 1;
422 ++p;
424 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
428 #ifdef LINUX26
429 modprobe("xt_layer7");
430 #else
431 modprobe("ipt_layer7");
432 #endif
433 return 1;
436 // -----------------------------------------------------------------------------
438 static void ipt_account(void) {
439 struct in_addr ipaddr, netmask, network;
440 char lanN_ifname[] = "lanXX_ifname";
441 char lanN_ipaddr[] = "lanXX_ipaddr";
442 char lanN_netmask[] = "lanXX_netmask";
443 char lanN[] = "lanXX";
444 char netaddrnetmask[] = "255.255.255.255/255.255.255.255 ";
445 char br;
447 for(br=0 ; br<=3 ; br++) {
448 char bridge[2] = "0";
449 if (br!=0)
450 bridge[0]+=br;
451 else
452 strcpy(bridge, "");
454 sprintf(lanN_ifname, "lan%s_ifname", bridge);
456 if (strcmp(nvram_safe_get(lanN_ifname), "")!=0) {
458 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
459 sprintf(lanN_netmask, "lan%s_netmask", bridge);
460 sprintf(lanN, "lan%s", bridge);
462 inet_aton(nvram_safe_get(lanN_ipaddr), &ipaddr);
463 inet_aton(nvram_safe_get(lanN_netmask), &netmask);
465 // bitwise AND of ip and netmask gives the network
466 network.s_addr = ipaddr.s_addr & netmask.s_addr;
468 sprintf(netaddrnetmask, "%s/%s", inet_ntoa(network), nvram_safe_get(lanN_netmask));
470 //ipv4 only
471 ipt_write("-A FORWARD -m account --aaddr %s --aname %s\n", netaddrnetmask, lanN);
476 // -----------------------------------------------------------------------------
478 static void save_webmon(void)
480 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
481 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
484 static void ipt_webmon()
486 int wmtype, clear, i;
487 char t[512];
488 char src[128];
489 char *p, *c;
490 int ok;
492 if (!nvram_get_int("log_wm")) return;
494 #ifdef LINUX26
495 can_enable_fastnat = 0;
496 #endif
497 wmtype = nvram_get_int("log_wmtype");
498 clear = nvram_get_int("log_wmclear");
500 ip46t_write(":monitor - [0:0]\n");
502 // include IPs
503 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
504 p = t;
505 do {
506 if ((c = strchr(p, ',')) != NULL) *c = 0;
508 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
509 #ifdef TCONFIG_IPV6
510 if (*wan6face && (ok & IPT_V6))
511 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
512 #endif
513 if (ok & IPT_V4) {
514 for (i = 0; i < wanfaces.count; ++i) {
515 if (*(wanfaces.iface[i].name)) {
516 ipt_write("-A FORWARD -o %s %s -j monitor\n",
517 wanfaces.iface[i].name, src);
523 if (!c) break;
524 p = c + 1;
525 } while (*p);
527 // exclude IPs
528 if (wmtype == 2) {
529 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
530 p = t;
531 do {
532 if ((c = strchr(p, ',')) != NULL) *c = 0;
533 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
534 if (*src)
535 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
537 if (!c) break;
538 p = c + 1;
539 } while (*p);
542 ip46t_write(
543 "-A monitor -p tcp -m webmon "
544 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
545 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
546 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
547 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
549 #ifdef LINUX26
550 modprobe("xt_webmon");
551 #else
552 modprobe("ipt_webmon");
553 #endif
557 // -----------------------------------------------------------------------------
558 // MANGLE
559 // -----------------------------------------------------------------------------
561 static void mangle_table(void)
563 int ttl;
564 char *p, *wanface;
566 ip46t_write(
567 "*mangle\n"
568 ":PREROUTING ACCEPT [0:0]\n"
569 ":OUTPUT ACCEPT [0:0]\n");
571 if (wanup) {
573 ipt_qos();
574 //1 for mangle
575 ipt_qoslimit(1);
577 p = nvram_safe_get("nf_ttl");
578 if (strncmp(p, "c:", 2) == 0) {
579 p += 2;
580 ttl = atoi(p);
581 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
583 else if ((ttl = atoi(p)) != 0) {
584 if (ttl > 0) {
585 p = "inc";
587 else {
588 ttl = -ttl;
589 p = "dec";
591 if (ttl > 255) p = NULL;
593 else p = NULL;
595 if (p) {
596 #ifdef LINUX26
597 modprobe("xt_HL");
598 #else
599 modprobe("ipt_TTL");
600 #endif
601 // set TTL on primary WAN iface only
602 wanface = wanfaces.iface[0].name;
603 ipt_write(
604 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
605 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
606 wanface, p, ttl,
607 wanface, p, ttl);
608 #ifdef TCONFIG_IPV6
609 // FIXME: IPv6 HL should be configurable separately from TTL.
610 // disable it until GUI setting is implemented.
611 #if 0
612 ip6t_write(
613 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
614 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
615 wan6face, p, ttl,
616 wan6face, p, ttl);
617 #endif
618 #endif
620 // Reset Incoming DSCP to 0x00
621 if (nvram_match("DSCP_fix_enable", "1")) {
622 #ifdef LINUX26
623 modprobe("xt_DSCP");
624 #else
625 modprobe("ipt_DSCP");
626 #endif
627 ipt_write("-I PREROUTING -i %s -j DSCP --set-dscp 0\n", wanface);
631 ip46t_write("COMMIT\n");
634 // -----------------------------------------------------------------------------
635 // NAT
636 // -----------------------------------------------------------------------------
638 static void nat_table(void)
640 char lanaddr[32];
641 char lanmask[32];
642 #ifdef TCONFIG_VLAN
643 char lan1addr[32];
644 char lan1mask[32];
645 char lan2addr[32];
646 char lan2mask[32];
647 char lan3addr[32];
648 char lan3mask[32];
649 #endif
650 char dst[64];
651 char src[64];
652 char t[512];
653 char *p, *c;
654 int i;
656 ipt_write("*nat\n"
657 ":PREROUTING ACCEPT [0:0]\n"
658 ":POSTROUTING ACCEPT [0:0]\n"
659 ":OUTPUT ACCEPT [0:0]\n"
660 ":%s - [0:0]\n",
661 chain_wan_prerouting);
663 //2 for nat
664 ipt_qoslimit(2);
666 if (gateway_mode) {
667 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
668 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
669 #ifdef TCONFIG_VLAN
670 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
671 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
672 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
673 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
674 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
675 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
676 #endif
678 for (i = 0; i < wanfaces.count; ++i) {
679 if (*(wanfaces.iface[i].name)) {
680 // Drop incoming packets which destination IP address is to our LAN side directly
681 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
682 wanfaces.iface[i].name,
683 lanaddr, lanmask); // note: ipt will correct lanaddr
684 #ifdef TCONFIG_VLAN
685 if(strcmp(lan1addr,"")!=0)
686 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
687 wanfaces.iface[i].name,
688 lan1addr, lan1mask);
689 if(strcmp(lan2addr,"")!=0)
690 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
691 wanfaces.iface[i].name,
692 lan2addr, lan2mask);
693 if(strcmp(lan3addr,"")!=0)
694 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
695 wanfaces.iface[i].name,
696 lan3addr, lan3mask);
697 #endif
698 // chain_wan_prerouting
699 if (wanup) {
700 ipt_write("-A PREROUTING -d %s -j %s\n",
701 wanfaces.iface[i].ip, chain_wan_prerouting);
706 if (wanup) {
707 if (nvram_match("dns_intcpt", "1")) {
708 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
709 lanaddr, lanmask,
710 lanaddr, lanmask,
711 lanaddr);
712 #ifdef TCONFIG_VLAN
713 if(strcmp(lan1addr,"")!=0)
714 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
715 lan1addr, lan1mask,
716 lan1addr, lan1mask,
717 lan1addr);
718 if(strcmp(lan2addr,"")!=0)
719 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
720 lan2addr, lan2mask,
721 lan2addr, lan2mask,
722 lan2addr);
723 if(strcmp(lan3addr,"")!=0)
724 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
725 lan3addr, lan3mask,
726 lan3addr, lan3mask,
727 lan3addr);
728 #endif
731 // ICMP packets are always redirected to INPUT chains
732 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
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 if (wanup) {
755 if (dmz_dst(dst)) {
756 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
757 p = t;
758 do {
759 if ((c = strchr(p, ',')) != NULL) *c = 0;
760 if (ipt_source_strict(p, src, "dmz", NULL))
761 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
762 if (!c) break;
763 p = c + 1;
764 } while (*p);
768 p = "";
769 #ifdef TCONFIG_IPV6
770 switch (get_ipv6_service()) {
771 case IPV6_6IN4:
772 // avoid NATing proto-41 packets when using 6in4 tunnel
773 p = "-p ! 41";
774 break;
776 #endif
778 char *modem_ipaddr;
779 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
780 && (modem_ipaddr = nvram_safe_get("modem_ipaddr")) && *modem_ipaddr && !nvram_match("modem_ipaddr","0.0.0.0")
781 && (!foreach_wif(1, NULL, is_sta)) )
782 ipt_write("-A POSTROUTING -o %s -d %s -j MASQUERADE\n", nvram_safe_get("wan_ifname"), modem_ipaddr);
784 for (i = 0; i < wanfaces.count; ++i) {
785 if (*(wanfaces.iface[i].name)) {
786 if ((!wanup) || (nvram_get_int("ne_snat") != 1))
787 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
788 else
789 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
793 switch (nvram_get_int("nf_loopback")) {
794 case 1: // 1 = forwarded-only
795 case 2: // 2 = disable
796 break;
797 default: // 0 = all (same as block_loopback=0)
798 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
799 lanface,
800 lanaddr, lanmask,
801 lanaddr, lanmask,
802 lanaddr);
803 #ifdef TCONFIG_VLAN
804 if (strcmp(lan1face,"")!=0)
805 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
806 lan1face,
807 lan1addr, lan1mask,
808 lan1addr, lan1mask,
809 lan1addr);
810 if (strcmp(lan2face,"")!=0)
811 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
812 lan2face,
813 lan2addr, lan2mask,
814 lan2addr, lan2mask,
815 lan2addr);
816 if (strcmp(lan3face,"")!=0)
817 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
818 lan3face,
819 lan3addr, lan3mask,
820 lan3addr, lan3mask,
821 lan3addr);
822 #endif
823 break;
826 ipt_write("COMMIT\n");
829 // -----------------------------------------------------------------------------
830 // FILTER
831 // -----------------------------------------------------------------------------
833 static void filter_input(void)
835 char s[64];
836 char t[512];
837 char *en;
838 char *sec;
839 char *hit;
840 int n;
841 char *p, *c;
843 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
844 for (n = 0; n < wanfaces.count; ++n) {
845 if (*(wanfaces.iface[n].name)) {
846 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
847 #ifdef TCONFIG_VLAN
848 if (strcmp(lan1face,"")!=0)
849 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
850 if (strcmp(lan2face,"")!=0)
851 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
852 if (strcmp(lan3face,"")!=0)
853 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
854 #endif
859 ipt_write(
860 "-A INPUT -m state --state INVALID -j DROP\n"
861 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
863 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
864 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
866 ? what if the user uses the start button in GUI ?
867 if (nvram_get_int("telnetd_eas"))
868 if (nvram_get_int("sshd_eas"))
870 #ifdef LINUX26
871 modprobe("xt_recent");
872 #else
873 modprobe("ipt_recent");
874 #endif
876 ipt_write(
877 "-N shlimit\n"
878 "-A shlimit -m recent --set --name shlimit\n"
879 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
880 atoi(hit) + 1, sec, chain_in_drop);
882 if (n & 1) {
883 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
884 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
885 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
888 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
891 #ifdef TCONFIG_FTP
892 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
893 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
894 #ifdef LINUX26
895 modprobe("xt_recent");
896 #else
897 modprobe("ipt_recent");
898 #endif
900 ipt_write(
901 "-N ftplimit\n"
902 "-A ftplimit -m recent --set --name ftp\n"
903 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
904 atoi(hit) + 1, sec, chain_in_drop);
905 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
907 #endif
909 ipt_write(
910 "-A INPUT -i lo -j ACCEPT\n"
911 "-A INPUT -i %s -j ACCEPT\n",
912 lanface);
913 #ifdef TCONFIG_VLAN
914 if (strcmp(lan1face,"")!=0)
915 ipt_write(
916 "-A INPUT -i %s -j ACCEPT\n",
917 lan1face);
918 if (strcmp(lan2face,"")!=0)
919 ipt_write(
920 "-A INPUT -i %s -j ACCEPT\n",
921 lan2face);
922 if (strcmp(lan3face,"")!=0)
923 ipt_write(
924 "-A INPUT -i %s -j ACCEPT\n",
925 lan3face);
926 #endif
928 #ifdef TCONFIG_IPV6
929 n = get_ipv6_service();
930 switch (n) {
931 case IPV6_ANYCAST_6TO4:
932 case IPV6_6IN4:
933 // Accept ICMP requests from the remote tunnel endpoint
934 if (n == IPV6_ANYCAST_6TO4)
935 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
936 else
937 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
938 if (*s && strcmp(s, "0.0.0.0") != 0)
939 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
940 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
941 break;
943 #endif
945 // ICMP request from WAN interface
946 if (nvram_match("block_wan", "0")) {
947 if (nvram_match("block_wan_limit", "0")) {
948 // allow ICMP packets to be received
949 ipt_write("-A INPUT -p icmp -j %s\n", chain_in_accept);
950 // allow udp traceroute packets
951 ipt_write("-A INPUT -p udp --dport 33434:33534 -j %s\n", chain_in_accept);
952 } else {
953 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
954 ipt_write("-A INPUT -p icmp -m limit --limit %d/second -j %s\n", nvram_get_int("block_wan_limit_icmp"), chain_in_accept);
955 // allow udp traceroute packets, but restrict the flow to avoid ping flood attacks
956 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);
960 /* Accept incoming packets from broken dhcp servers, which are sending replies
961 * from addresses other than used for query. This could lead to a lower level
962 * of security, so allow to disable it via nvram variable.
964 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
965 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
968 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
969 p = t;
970 do {
971 if ((c = strchr(p, ',')) != NULL) *c = 0;
973 if (ipt_source(p, s, "remote management", NULL)) {
975 if (remotemanage) {
976 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
977 s, nvram_safe_get("http_wanport"), chain_in_accept);
980 if (nvram_get_int("sshd_remote")) {
981 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
982 s, nvram_safe_get("sshd_rport"), chain_in_accept);
986 if (!c) break;
987 p = c + 1;
988 } while (*p);
990 #ifdef TCONFIG_FTP // !!TB - FTP Server
991 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
992 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
993 p = t;
994 do {
995 if ((c = strchr(p, ',')) != NULL) *c = 0;
996 if (ipt_source(p, s, "ftp", "remote access")) {
997 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
998 s, nvram_safe_get("ftp_port"), chain_in_accept);
1000 if (!c) break;
1001 p = c + 1;
1002 } while (*p);
1004 #endif
1006 #ifdef TCONFIG_SNMP
1007 if( nvram_match( "snmp_enable", "1" ) && nvram_match("snmp_remote", "1"))
1009 strlcpy(t, nvram_safe_get("snmp_remote_sip"), sizeof(t));
1010 p = t;
1011 do {
1012 if ((c = strchr(p, ',')) != NULL) *c = 0;
1014 if (ipt_source(p, s, "snmp", "remote")) {
1015 ipt_write("-A INPUT -p udp %s --dport %s -j %s\n",
1016 s, nvram_safe_get("snmp_port"), chain_in_accept);
1019 if (!c) break;
1020 p = c + 1;
1021 } while (*p);
1023 #endif
1025 // IGMP query from WAN interface
1026 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1027 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
1028 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
1031 // Routing protocol, RIP, accept
1032 if (nvram_invmatch("dr_wan_rx", "0")) {
1033 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
1036 // if logging
1037 if (*chain_in_drop == 'l') {
1038 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
1041 // default policy: DROP
1044 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
1045 static void clampmss(void)
1047 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
1048 #ifdef TCONFIG_IPV6
1049 switch (get_ipv6_service()) {
1050 case IPV6_ANYCAST_6TO4:
1051 case IPV6_6IN4:
1052 ip6t_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
1053 break;
1055 #endif
1058 static void filter_forward(void)
1060 char dst[64];
1061 char src[64];
1062 char t[512];
1063 char *p, *c;
1064 int i;
1066 if (nvram_match("cstats_enable", "1")) {
1067 ipt_account();
1070 #ifdef TCONFIG_IPV6
1071 ip6t_write(
1072 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
1073 #endif
1075 ip46t_write(
1076 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
1077 lanface, lanface);
1078 #ifdef TCONFIG_VLAN
1079 if (strcmp(lan1face,"")!=0)
1080 ip46t_write(
1081 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1082 lan1face, lan1face);
1083 if (strcmp(lan2face,"")!=0)
1084 ip46t_write(
1085 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1086 lan2face, lan2face);
1087 if (strcmp(lan3face,"")!=0)
1088 ip46t_write(
1089 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1090 lan3face, lan3face);
1092 char lanAccess[17] = "0000000000000000";
1093 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
1094 char *nv, *nvp, *b;
1095 int n;
1096 nvp = nv = strdup(nvram_safe_get("lan_access"));
1097 if (nv) {
1098 while ((b = strsep(&nvp, ">")) != NULL) {
1100 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
1102 1 = enabled
1103 0 = src bridge
1104 1.2.3.4 = src addr
1105 1 = dst bridge
1106 5.6.7.8 = dst addr
1107 desc = desc
1109 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
1110 if (*d != '1')
1111 continue;
1112 if (!ipt_addr(src, sizeof(src), saddr, "src", IPT_V4|IPT_V6, 0, "LAN access", desc))
1113 continue;
1114 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", IPT_V4|IPT_V6, 0, "LAN access", desc))
1115 continue;
1117 //ipv4 only
1118 ipt_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
1119 "br",
1120 sbr,
1121 "br",
1122 dbr,
1123 src,
1124 dst);
1126 if ((strcmp(src,"")==0) && (strcmp(dst,"")==0))
1127 lanAccess[((*sbr-48)+(*dbr-48)*4)] = '1';
1131 free(nv);
1132 #endif
1134 ip46t_write(
1135 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
1137 // clamp tcp mss to pmtu
1138 clampmss();
1140 if (wanup) {
1141 ipt_restrictions();
1143 ipt_layer7_inbound();
1146 ipt_webmon();
1148 ip46t_write(
1149 ":wanin - [0:0]\n"
1150 ":wanout - [0:0]\n"
1151 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1153 #ifdef TCONFIG_VLAN
1154 char lanN_ifname[] = "lanXX_ifname";
1155 char br;
1156 for(br=0 ; br<=3 ; br++) {
1157 char bridge[2] = "0";
1158 if (br!=0)
1159 bridge[0]+=br;
1160 else
1161 strcpy(bridge, "");
1163 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1164 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1165 char lanN_ifname2[] = "lanXX_ifname";
1166 char br2;
1167 for(br2=0 ; br2<=3 ; br2++) {
1168 if (br==br2) continue;
1170 if (lanAccess[((br)+(br2)*4)] == '1') continue;
1172 char bridge2[2] = "0";
1173 if (br2!=0)
1174 bridge2[0]+=br2;
1175 else
1176 strcpy(bridge2, "");
1178 sprintf(lanN_ifname2, "lan%s_ifname", bridge2);
1179 if (strncmp(nvram_safe_get(lanN_ifname2), "br", 2) == 0) {
1180 ip46t_write("-A FORWARD -i %s -o %s -j DROP\n",
1181 nvram_safe_get(lanN_ifname),
1182 nvram_safe_get(lanN_ifname2));
1185 // ipt_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1188 #endif
1190 #ifdef TCONFIG_PPTPD
1191 //Add for pptp server
1192 if (nvram_match("pptpd_enable", "1")) {
1193 ipt_write("-A INPUT -p tcp --dport 1723 -j ACCEPT\n");
1194 ipt_write("-A INPUT -p 47 -j ACCEPT\n");
1196 #endif
1198 #ifdef TCONFIG_IPV6
1199 // Filter out invalid WAN->WAN connections
1200 if (*wan6face)
1201 ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face, lanface, chain_in_drop);
1203 #ifdef LINUX26
1204 modprobe("xt_length");
1205 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1206 #endif
1208 // ICMPv6 rules
1209 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
1210 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
1213 if (*wan6face) {
1214 ip6t_write(
1215 "-A FORWARD -i %s -j wanin\n" // generic from wan
1216 "-A FORWARD -o %s -j wanout\n", // generic to wan
1217 wan6face, wan6face);
1219 #endif
1221 for (i = 0; i < wanfaces.count; ++i) {
1222 if (*(wanfaces.iface[i].name)) {
1223 ipt_write(
1224 "-A FORWARD -i %s -j wanin\n" // generic from wan
1225 "-A FORWARD -o %s -j wanout\n", // generic to wan
1226 wanfaces.iface[i].name, wanfaces.iface[i].name);
1230 #ifdef TCONFIG_VLAN
1231 for(br=0 ; br<=3 ; br++) {
1232 char bridge[2] = "0";
1233 if (br!=0)
1234 bridge[0]+=br;
1235 else
1236 strcpy(bridge, "");
1238 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1239 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1240 ipt_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1243 #else
1244 ipt_write("-A FORWARD -i %s -j %s\n", lanface, chain_out_accept);
1245 #endif
1247 // #ifdef TCONFIG_VLAN
1248 /* for (i = 0; i < wanfaces.count; ++i) {
1249 if (*(wanfaces.iface[i].name)) {
1250 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wanfaces.iface[i].name, chain_out_accept);
1251 if (strcmp(lan1face,"")!=0)
1252 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wanfaces.iface[i].name, chain_out_accept);
1253 if (strcmp(lan2face,"")!=0)
1254 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wanfaces.iface[i].name, chain_out_accept);
1255 if (strcmp(lan3face,"")!=0)
1256 ipt_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wanfaces.iface[i].name, chain_out_accept);
1260 // #else
1261 // ipt_write("-A FORWARD -i %s -j %s\n", lanface, chain_out_accept);
1262 // #endif
1264 #ifdef TCONFIG_IPV6
1265 //IPv6 forward LAN->WAN accept
1266 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wan6face, chain_out_accept);
1267 #ifdef TCONFIG_VLAN
1268 if (strcmp(lan1face,"")!=0)
1269 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wan6face, chain_out_accept);
1270 if (strcmp(lan2face,"")!=0)
1271 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wan6face, chain_out_accept);
1272 if (strcmp(lan3face,"")!=0)
1273 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wan6face, chain_out_accept);
1274 #endif
1275 #endif
1277 if (nvram_get_int("upnp_enable") & 3) {
1278 ipt_write(":upnp - [0:0]\n");
1279 for (i = 0; i < wanfaces.count; ++i) {
1280 if (*(wanfaces.iface[i].name)) {
1281 ipt_write("-A FORWARD -i %s -j upnp\n",
1282 wanfaces.iface[i].name);
1287 if (wanup) {
1288 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1289 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1291 ipt_triggered(IPT_TABLE_FILTER);
1292 ipt_forward(IPT_TABLE_FILTER);
1293 #ifdef TCONFIG_IPV6
1294 ip6t_forward();
1295 #endif
1297 if (dmz_dst(dst)) {
1298 #ifdef TCONFIG_VLAN
1299 char dmz_ifname[IFNAMSIZ+1];
1300 strlcpy(dmz_ifname, nvram_safe_get("dmz_ifname"), sizeof(dmz_ifname));
1301 if(strcmp(dmz_ifname, "") == 0)
1302 strlcpy(dmz_ifname, lanface, sizeof(lanface));
1303 #endif
1304 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1305 p = t;
1306 do {
1307 if ((c = strchr(p, ',')) != NULL) *c = 0;
1308 if (ipt_source_strict(p, src, "dmz", NULL))
1309 #ifdef TCONFIG_VLAN
1310 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", dmz_ifname, src, dst, chain_in_accept);
1311 #else
1312 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
1313 #endif
1314 if (!c) break;
1315 p = c + 1;
1316 } while (*p);
1320 // default policy: DROP
1323 static void filter_log(void)
1325 int n;
1326 char limit[128];
1328 n = nvram_get_int("log_limit");
1329 if ((n >= 1) && (n <= 9999)) {
1330 sprintf(limit, "-m limit --limit %d/m", n);
1332 else {
1333 limit[0] = 0;
1336 #ifdef TCONFIG_IPV6
1337 modprobe("ip6t_LOG");
1338 #endif
1339 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1340 ip46t_write(
1341 ":logdrop - [0:0]\n"
1342 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1343 #ifdef LINUX26
1344 " --log-macdecode"
1345 #endif
1346 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1347 "-A logdrop -j DROP\n"
1348 ":logreject - [0:0]\n"
1349 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1350 #ifdef LINUX26
1351 " --log-macdecode"
1352 #endif
1353 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1354 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1355 limit, limit);
1357 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1358 ip46t_write(
1359 ":logaccept - [0:0]\n"
1360 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1361 #ifdef LINUX26
1362 " --log-macdecode"
1363 #endif
1364 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1365 "-A logaccept -j ACCEPT\n",
1366 limit);
1370 #ifdef TCONFIG_IPV6
1371 static void filter6_input(void)
1373 char s[128];
1374 char t[512];
1375 char *en;
1376 char *sec;
1377 char *hit;
1378 int n;
1379 char *p, *c;
1381 // RFC-4890, sec. 4.4.1
1382 const int allowed_local_icmpv6[] =
1383 { 130, 131, 132, 133, 134, 135, 136,
1384 141, 142, 143,
1385 148, 149, 151, 152, 153 };
1387 ip6t_write(
1388 "-A INPUT -m rt --rt-type 0 -j %s\n"
1389 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1390 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1391 chain_in_drop);
1393 #ifdef LINUX26
1394 modprobe("xt_length");
1395 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1396 #endif
1398 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1399 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1400 #ifdef LINUX26
1401 modprobe("xt_recent");
1402 #else
1403 modprobe("ipt_recent");
1404 #endif
1406 ip6t_write(
1407 "-N shlimit\n"
1408 "-A shlimit -m recent --set --name shlimit\n"
1409 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1410 atoi(hit) + 1, sec, chain_in_drop);
1412 if (n & 1) {
1413 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1414 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1415 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1418 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"));
1421 #ifdef TCONFIG_FTP
1422 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1423 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1424 #ifdef LINUX26
1425 modprobe("xt_recent");
1426 #else
1427 modprobe("ipt_recent");
1428 #endif
1430 ip6t_write(
1431 "-N ftplimit\n"
1432 "-A ftplimit -m recent --set --name ftp\n"
1433 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1434 atoi(hit) + 1, sec, chain_in_drop);
1435 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1437 #endif // TCONFIG_FTP
1439 ip6t_write(
1440 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1441 "-A INPUT -i lo -j ACCEPT\n",
1442 lanface );
1444 switch (get_ipv6_service()) {
1445 case IPV6_ANYCAST_6TO4:
1446 case IPV6_NATIVE_DHCP:
1447 // allow responses from the dhcpv6 server
1448 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1449 break;
1452 // ICMPv6 rules
1453 const int allowed_icmpv6[6] = { 1, 2, 3, 4, 128, 129 };
1454 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1455 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1457 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1458 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1461 // Remote Managment
1462 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1463 p = t;
1464 do {
1465 if ((c = strchr(p, ',')) != NULL) *c = 0;
1467 if (ip6t_source(p, s, "remote management", NULL)) {
1469 if (remotemanage) {
1470 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1471 s, nvram_safe_get("http_wanport"), chain_in_accept);
1474 if (nvram_get_int("sshd_remote")) {
1475 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1476 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1480 if (!c) break;
1481 p = c + 1;
1482 } while (*p);
1484 #ifdef TCONFIG_FTP
1485 // FTP server
1486 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1487 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1488 p = t;
1489 do {
1490 if ((c = strchr(p, ',')) != NULL) *c = 0;
1491 if (ip6t_source(p, s, "ftp", "remote access")) {
1492 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1493 s, nvram_safe_get("ftp_port"), chain_in_accept);
1495 if (!c) break;
1496 p = c + 1;
1497 } while (*p);
1499 #endif
1501 // if logging
1502 if (*chain_in_drop == 'l') {
1503 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1506 // default policy: DROP
1509 #endif
1511 static void filter_table(void)
1513 ip46t_write(
1514 "*filter\n"
1515 ":INPUT DROP [0:0]\n"
1516 ":OUTPUT ACCEPT [0:0]\n"
1519 filter_log();
1521 filter_input();
1522 #ifdef TCONFIG_IPV6
1523 filter6_input();
1524 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1525 #endif
1527 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1528 ip46t_write(":FORWARD DROP [0:0]\n");
1529 filter_forward();
1531 else {
1532 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1533 clampmss();
1535 ip46t_write("COMMIT\n");
1538 // -----------------------------------------------------------------------------
1540 int start_firewall(void)
1542 DIR *dir;
1543 struct dirent *dirent;
1544 char s[256];
1545 char *c, *wanface;
1546 int n;
1547 int wanproto;
1548 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1549 #ifdef TCONFIG_IPV6
1550 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1551 #endif
1553 simple_lock("firewall");
1554 simple_lock("restrictions");
1556 wanproto = get_wan_proto();
1557 wanup = check_wanup();
1559 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1561 /* NAT performance tweaks
1562 * These values can be overriden later if needed via firewall script
1564 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1565 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1566 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1567 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1568 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1569 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1570 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1571 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1572 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1573 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1574 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1575 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1577 /* DoS-related tweaks */
1578 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1579 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1580 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1582 wanproto = get_wan_proto();
1583 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1585 #ifdef TCONFIG_EMF
1586 /* Force IGMPv2 due EMF limitations */
1587 if (nvram_get_int("emf_enable")) {
1588 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1589 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1591 #endif
1593 n = nvram_get_int("log_in");
1594 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1595 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1597 n = nvram_get_int("log_out");
1598 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1599 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1600 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1602 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1604 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1605 #ifdef TCONFIG_VLAN
1606 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1607 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1608 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1609 #endif
1611 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1612 wanface = wanfaces.iface[0].name;
1613 #ifdef TCONFIG_IPV6
1614 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1615 #endif
1617 #ifdef LINUX26
1618 can_enable_fastnat = 1;
1619 #endif
1621 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1622 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1623 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1624 #ifdef TCONFIG_VLAN
1626 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1627 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1628 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1630 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1631 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1632 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1634 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1635 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1636 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1638 #endif
1641 block obviously spoofed IP addresses
1643 rp_filter - BOOLEAN
1644 1 - do source validation by reversed path, as specified in RFC1812
1645 Recommended option for single homed hosts and stub network
1646 routers. Could cause troubles for complicated (not loop free)
1647 networks running a slow unreliable protocol (sort of RIP),
1648 or using static routes.
1649 0 - No source validation.
1651 c = nvram_get("wan_ifname");
1652 /* mcast needs rp filter to be turned off only for non default iface */
1653 if (!(nvram_match("multicast_pass", "1")) || !(nvram_match("udpxy_enable", "1")) || strcmp(wanface, c) == 0) c = NULL;
1655 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1656 while ((dirent = readdir(dir)) != NULL) {
1657 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1658 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1660 closedir(dir);
1663 remotemanage = 0;
1664 gateway_mode = !nvram_match("wk_mode", "router");
1665 if (gateway_mode) {
1666 /* Remote management */
1667 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1668 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1671 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1672 notice_set("iptables", "Unable to create iptables restore file");
1673 simple_unlock("firewall");
1674 return 0;
1677 #ifdef TCONFIG_IPV6
1678 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1679 notice_set("ip6tables", "Unable to create ip6tables restore file");
1680 simple_unlock("firewall");
1681 return 0;
1683 modprobe("nf_conntrack_ipv6");
1684 modprobe("ip6t_REJECT");
1685 #endif
1686 /*Start xt_IMQ and imq */
1687 modprobe("imq");
1688 #ifdef LINUX26
1689 modprobe("xt_IMQ");
1690 #else
1691 modprobe("ipt_IMQ");
1692 #endif
1694 mangle_table();
1695 nat_table();
1696 filter_table();
1698 fclose(ipt_file);
1699 ipt_file = NULL;
1701 #ifdef TCONFIG_IPV6
1702 fclose(ip6t_file);
1703 ip6t_file = NULL;
1704 #endif
1706 #ifdef DEBUG_IPTFILE
1707 if (debug_only) {
1708 simple_unlock("firewall");
1709 simple_unlock("restrictions");
1710 return 0;
1712 #endif
1714 save_webmon();
1716 if (nvram_get_int("upnp_enable") & 3) {
1717 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1718 if (killall("miniupnpd", SIGUSR2) == 0) {
1719 f_wait_notexists("/etc/upnp/save", 5);
1723 notice_set("iptables", "");
1724 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1725 led(LED_DIAG, 0);
1726 notice_set("iptables", "");
1728 else {
1729 sprintf(s, "%s.error", ipt_fname);
1730 rename(ipt_fname, s);
1731 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1732 led(LED_DIAG, 1);
1736 -P INPUT DROP
1737 -F INPUT
1738 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1739 -A INPUT -i br0 -j ACCEPT
1741 -P FORWARD DROP
1742 -F FORWARD
1743 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1744 -A FORWARD -i br0 -j ACCEPT
1749 #ifdef TCONFIG_IPV6
1750 if (ipv6_enabled()) {
1751 notice_set("ip6tables", "");
1752 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1753 notice_set("ip6tables", "");
1755 else {
1756 sprintf(s, "%s.error", ip6t_fname);
1757 rename(ip6t_fname, s);
1758 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1759 led(LED_DIAG, 1);
1762 else {
1763 eval("ip6tables", "-F");
1764 eval("ip6tables", "-t", "mangle", "-F");
1766 #endif
1768 if (nvram_get_int("upnp_enable") & 3) {
1769 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1770 killall("miniupnpd", SIGUSR2);
1773 simple_unlock("restrictions");
1774 sched_restrictions();
1775 enable_ip_forward();
1776 #ifdef TCONFIG_IPV6
1777 if (ipv6_enabled()) enable_ip6_forward();
1778 #endif
1780 led(LED_DMZ, dmz_dst(NULL));
1782 #ifdef TCONFIG_IPV6
1783 modprobe_r("nf_conntrack_ipv6");
1784 modprobe_r("ip6t_LOG");
1785 modprobe_r("ip6t_REJECT");
1786 #endif
1787 #ifdef LINUX26
1788 modprobe_r("xt_layer7");
1789 modprobe_r("xt_recent");
1790 modprobe_r("xt_HL");
1791 modprobe_r("xt_length");
1792 modprobe_r("xt_web");
1793 modprobe_r("xt_webmon");
1794 modprobe_r("xt_dscp");
1795 #else
1796 modprobe_r("ipt_layer7");
1797 modprobe_r("ipt_recent");
1798 modprobe_r("ipt_TTL");
1799 modprobe_r("ipt_web");
1800 modprobe_r("ipt_webmon");
1801 modprobe_r("ipt_dscp");
1802 #endif
1803 modprobe_r("ipt_ipp2p");
1805 unlink("/var/webmon/domain");
1806 unlink("/var/webmon/search");
1808 #ifdef TCONFIG_OPENVPN
1809 run_vpn_firewall_scripts();
1810 #endif
1811 run_nvscript("script_fire", NULL, 1);
1813 start_arpbind();
1815 #ifdef LINUX26
1816 allow_fastnat("firewall", can_enable_fastnat);
1817 try_enabling_fastnat();
1818 #endif
1820 simple_unlock("firewall");
1821 return 0;
1824 int stop_firewall(void)
1826 led(LED_DMZ, 0);
1827 return 0;
1830 #ifdef DEBUG_IPTFILE
1831 void create_test_iptfile(void)
1833 debug_only = 1;
1834 start_firewall();
1835 debug_only = 0;
1837 #endif