fix compilation
[tomato.git] / release / src / router / rc / firewall.c
blob8d11f8fd552d6be57ad5887a79a631651a69e28a
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 char lan1face[IFNAMSIZ + 1];
35 char lan2face[IFNAMSIZ + 1];
36 char lan3face[IFNAMSIZ + 1];
37 #ifdef TCONFIG_IPV6
38 char wan6face[IFNAMSIZ + 1];
39 #endif
40 char lan_cclass[sizeof("xxx.xxx.xxx.") + 1];
41 #ifdef LINUX26
42 static int can_enable_fastnat;
43 #endif
45 #ifdef DEBUG_IPTFILE
46 static int debug_only = 0;
47 #endif
49 static int gateway_mode;
50 static int remotemanage;
51 static int wanup;
53 const char *chain_in_drop;
54 const char *chain_in_accept;
55 const char *chain_out_drop;
56 const char *chain_out_accept;
57 const char *chain_out_reject;
59 const char chain_wan_prerouting[] = "WANPREROUTING";
60 const char ipt_fname[] = "/etc/iptables";
61 FILE *ipt_file;
63 #ifdef TCONFIG_IPV6
64 const char ip6t_fname[] = "/etc/ip6tables";
65 FILE *ip6t_file;
67 // RFC-4890, sec. 4.3.1
68 const int allowed_icmpv6[] = { 1, 2, 3, 4, 128, 129 };
69 #endif
73 struct {
74 } firewall_data;
77 // -----------------------------------------------------------------------------
79 #ifdef LINUX26
80 static const char *fastnat_run_dir = "/var/run/fastnat";
82 void allow_fastnat(const char *service, int allow)
84 char p[128];
86 snprintf(p, sizeof(p), "%s/%s", fastnat_run_dir, service);
87 if (allow) {
88 unlink(p);
90 else {
91 mkdir_if_none(fastnat_run_dir);
92 f_write_string(p, "", 0, 0);
96 static inline int fastnat_allowed(void)
98 DIR *dir;
99 struct dirent *dp;
100 int enabled;
102 enabled = !nvram_get_int("qos_enable") && !nvram_get_int("fastnat_disable");
104 if (enabled && (dir = opendir(fastnat_run_dir))) {
105 while ((dp = readdir(dir))) {
106 if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
107 continue;
108 enabled = 0;
109 break;
111 closedir(dir);
114 return (enabled);
117 void try_enabling_fastnat(void)
119 f_write_string("/proc/sys/net/ipv4/netfilter/ip_conntrack_fastnat",
120 fastnat_allowed() ? "1" : "0", 0, 0);
122 #endif
124 void enable_ip_forward(void)
127 ip_forward - BOOLEAN
128 0 - disabled (default)
129 not 0 - enabled
131 Forward Packets between interfaces.
133 This variable is special, its change resets all configuration
134 parameters to their default state (RFC1122 for hosts, RFC1812
135 for routers)
137 f_write_string("/proc/sys/net/ipv4/ip_forward", "1", 0, 0);
139 #ifdef TCONFIG_IPV6
140 if (ipv6_enabled()) {
141 f_write_string("/proc/sys/net/ipv6/conf/default/forwarding", "1", 0, 0);
142 f_write_string("/proc/sys/net/ipv6/conf/all/forwarding", "1", 0, 0);
144 #endif
148 // -----------------------------------------------------------------------------
151 static int ip2cclass(char *ipaddr, char *new, int count)
153 int ip[4];
155 if (sscanf(ipaddr,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3]) != 4) return 0;
156 return snprintf(new, count, "%d.%d.%d.",ip[0],ip[1],ip[2]);
161 static int dmz_dst(char *s)
163 struct in_addr ia;
164 char *p;
165 int n;
167 if (nvram_get_int("dmz_enable") <= 0) return 0;
169 p = nvram_safe_get("dmz_ipaddr");
170 if ((ia.s_addr = inet_addr(p)) == (in_addr_t)-1) {
171 if (((n = atoi(p)) <= 0) || (n >= 255)) return 0;
172 if (s) sprintf(s, "%s%d", lan_cclass, n);
173 return 1;
176 if (s) strcpy(s, inet_ntoa(ia));
177 return 1;
180 void ipt_log_unresolved(const char *addr, const char *addrtype, const char *categ, const char *name)
182 char *pre, *post;
184 pre = (name && *name) ? " for \"" : "";
185 post = (name && *name) ? "\"" : "";
187 syslog(LOG_WARNING, "firewall: "
188 "%s: not using %s%s%s%s (could not resolve as valid %s address)",
189 categ, addr, pre, (name) ? : "", post, (addrtype) ? : "IP");
192 int ipt_addr(char *addr, int maxlen, const char *s, const char *dir, int af,
193 int strict, const char *categ, const char *name)
195 char p[INET6_ADDRSTRLEN * 2];
196 int r = 0;
198 if ((s) && (*s) && (*dir))
200 if (sscanf(s, "%[0-9.]-%[0-9.]", p, p) == 2) {
201 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
202 r = IPT_V4;
204 #ifdef TCONFIG_IPV6
205 else if (sscanf(s, "%[0-9A-Fa-f:]-%[0-9A-Fa-f:]", p, p) == 2) {
206 snprintf(addr, maxlen, "-m iprange --%s-range %s", dir, s);
207 r = IPT_V6;
209 #endif
210 else {
211 snprintf(addr, maxlen, "-%c %s", dir[0], s);
212 if (sscanf(s, "%[^/]/", p)) {
213 #ifdef TCONFIG_IPV6
214 r = host_addrtypes(p, strict ? af : (IPT_V4 | IPT_V6));
215 #else
216 r = host_addrtypes(p, IPT_V4);
217 #endif
221 else
223 *addr = 0;
224 r = (IPT_V4 | IPT_V6);
227 if ((r == 0 || (strict && ((r & af) != af))) && (categ && *categ)) {
228 ipt_log_unresolved(s, categ, name,
229 (af & IPT_V4 & ~r) ? "IPv4" : ((af & IPT_V6 & ~r) ? "IPv6" : NULL));
232 return (r & af);
235 #define ipt_source_strict(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 1, categ, name)
236 #define ipt_source(s, src, categ, name) ipt_addr(src, 64, s, "src", IPT_V4, 0, categ, name)
237 #define ip6t_source(s, src, categ, name) ipt_addr(src, 128, s, "src", IPT_V6, 0, categ, name)
240 static void get_src(const char *nv, char *src)
242 char *p;
244 if (((p = nvram_get(nv)) != NULL) && (*p) && (strlen(p) < 32)) {
245 sprintf(src, "-%s %s", strchr(p, '-') ? "m iprange --src-range" : "s", p);
247 else {
248 *src = 0;
253 void ipt_write(const char *format, ...)
255 va_list args;
257 va_start(args, format);
258 vfprintf(ipt_file, format, args);
259 va_end(args);
262 void ip6t_write(const char *format, ...)
264 #ifdef TCONFIG_IPV6
265 va_list args;
267 va_start(args, format);
268 vfprintf(ip6t_file, format, args);
269 va_end(args);
270 #endif
273 // -----------------------------------------------------------------------------
275 int ipt_dscp(const char *v, char *opt)
277 unsigned int n;
279 if (*v == 0) {
280 *opt = 0;
281 return 0;
284 n = strtoul(v, NULL, 0);
285 if (n > 63) n = 63;
286 sprintf(opt, " -m dscp --dscp 0x%02X", n);
288 #ifdef LINUX26
289 modprobe("xt_dscp");
290 #else
291 modprobe("ipt_dscp");
292 #endif
293 return 1;
296 // -----------------------------------------------------------------------------
299 int ipt_ipp2p(const char *v, char *opt)
301 int n = atoi(v);
303 if (n == 0) {
304 *opt = 0;
305 return 0;
308 strcpy(opt, "-m ipp2p ");
309 if ((n & 0xFFF) == 0xFFF) {
310 strcat(opt, "--ipp2p");
312 else {
313 // x12
314 if (n & 0x0001) strcat(opt, "--apple ");
315 if (n & 0x0002) strcat(opt, "--ares ");
316 if (n & 0x0004) strcat(opt, "--bit ");
317 if (n & 0x0008) strcat(opt, "--dc ");
318 if (n & 0x0010) strcat(opt, "--edk ");
319 if (n & 0x0020) strcat(opt, "--gnu ");
320 if (n & 0x0040) strcat(opt, "--kazaa ");
321 if (n & 0x0080) strcat(opt, "--mute ");
322 if (n & 0x0100) strcat(opt, "--soul ");
323 if (n & 0x0200) strcat(opt, "--waste ");
324 if (n & 0x0400) strcat(opt, "--winmx ");
325 if (n & 0x0800) strcat(opt, "--xdcc ");
328 modprobe("ipt_ipp2p");
329 return 1;
333 // -----------------------------------------------------------------------------
336 char **layer7_in;
338 // This L7 matches inbound traffic, caches the results, then the L7 outbound
339 // should read the cached result and set the appropriate marks -- zzz
340 void ipt_layer7_inbound(void)
342 int en, i;
343 char **p;
345 if (!layer7_in) return;
347 en = nvram_match("nf_l7in", "1");
348 if (en) {
349 ipt_write(":L7in - [0:0]\n");
350 for (i = 0; i < wanfaces.count; ++i) {
351 if (*(wanfaces.iface[i].name)) {
352 ipt_write("-A FORWARD -i %s -j L7in\n",
353 wanfaces.iface[i].name);
358 p = layer7_in;
359 while (*p) {
360 if (en) {
361 ipt_write("-A L7in %s -j RETURN\n", *p);
362 #ifdef LINUX26
363 can_enable_fastnat = 0;
364 #endif
366 free(*p);
367 ++p;
369 free(layer7_in);
370 layer7_in = NULL;
373 int ipt_layer7(const char *v, char *opt)
375 char s[128];
376 char *path;
378 *opt = 0;
379 if (*v == 0) return 0;
380 if (strlen(v) > 32) return -1;
382 path = "/etc/l7-extra";
383 sprintf(s, "%s/%s.pat", path, v);
384 if (!f_exists(s)) {
385 path = "/etc/l7-protocols";
386 sprintf(s, "%s/%s.pat", path, v);
387 if (!f_exists(s)) {
388 syslog(LOG_ERR, "L7 %s was not found", v);
389 return -1;
393 sprintf(opt, "-m layer7 --l7dir %s --l7proto %s", path, v);
395 if (nvram_match("nf_l7in", "1")) {
396 if (!layer7_in) layer7_in = calloc(51, sizeof(char *));
397 if (layer7_in) {
398 char **p;
400 p = layer7_in;
401 while (*p) {
402 if (strcmp(*p, opt) == 0) return 1;
403 ++p;
405 if (((p - layer7_in) / sizeof(char *)) < 50) *p = strdup(opt);
409 #ifdef LINUX26
410 modprobe("xt_layer7");
411 #else
412 modprobe("ipt_layer7");
413 #endif
414 return 1;
417 // -----------------------------------------------------------------------------
419 static void ipt_account(void) {
420 struct in_addr ipaddr, netmask, network;
421 char lanN_ifname[] = "lanXX_ifname";
422 char lanN_ipaddr[] = "lanXX_ipaddr";
423 char lanN_netmask[] = "lanXX_netmask";
424 char lanN[] = "lanXX";
425 char netaddrnetmask[] = "255.255.255.255/255.255.255.255 ";
426 char br;
428 for(br=0 ; br<=3 ; br++) {
429 char bridge[2] = "0";
430 if (br!=0)
431 bridge[0]+=br;
432 else
433 strcpy(bridge, "");
435 sprintf(lanN_ifname, "lan%s_ifname", bridge);
437 if (strcmp(nvram_safe_get(lanN_ifname), "")!=0) {
439 sprintf(lanN_ipaddr, "lan%s_ipaddr", bridge);
440 sprintf(lanN_netmask, "lan%s_netmask", bridge);
441 sprintf(lanN, "lan%s", bridge);
443 inet_aton(nvram_safe_get(lanN_ipaddr), &ipaddr);
444 inet_aton(nvram_safe_get(lanN_netmask), &netmask);
446 // bitwise AND of ip and netmask gives the network
447 network.s_addr = ipaddr.s_addr & netmask.s_addr;
449 sprintf(netaddrnetmask, "%s/%s", inet_ntoa(network), nvram_safe_get(lanN_netmask));
451 //ipv4 only
452 ipt_write("-A FORWARD -m account --aaddr %s --aname %s\n", netaddrnetmask, lanN);
457 // -----------------------------------------------------------------------------
459 static void save_webmon(void)
461 eval("cp", "/proc/webmon_recent_domains", "/var/webmon/domain");
462 eval("cp", "/proc/webmon_recent_searches", "/var/webmon/search");
465 static void ipt_webmon()
467 int wmtype, clear, i;
468 char t[512];
469 char src[128];
470 char *p, *c;
471 int ok;
473 if (!nvram_get_int("log_wm")) return;
475 #ifdef LINUX26
476 can_enable_fastnat = 0;
477 #endif
478 wmtype = nvram_get_int("log_wmtype");
479 clear = nvram_get_int("log_wmclear");
481 ip46t_write(":monitor - [0:0]\n");
483 // include IPs
484 strlcpy(t, wmtype == 1 ? nvram_safe_get("log_wmip") : "", sizeof(t));
485 p = t;
486 do {
487 if ((c = strchr(p, ',')) != NULL) *c = 0;
489 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
490 #ifdef TCONFIG_IPV6
491 if (*wan6face && (ok & IPT_V6))
492 ip6t_write("-A FORWARD -o %s %s -j monitor\n", wan6face, src);
493 #endif
494 if (ok & IPT_V4) {
495 for (i = 0; i < wanfaces.count; ++i) {
496 if (*(wanfaces.iface[i].name)) {
497 ipt_write("-A FORWARD -o %s %s -j monitor\n",
498 wanfaces.iface[i].name, src);
504 if (!c) break;
505 p = c + 1;
506 } while (*p);
508 // exclude IPs
509 if (wmtype == 2) {
510 strlcpy(t, nvram_safe_get("log_wmip"), sizeof(t));
511 p = t;
512 do {
513 if ((c = strchr(p, ',')) != NULL) *c = 0;
514 if ((ok = ipt_addr(src, sizeof(src), p, "src", IPT_V4|IPT_V6, 0, "webmon", NULL))) {
515 if (*src)
516 ip46t_flagged_write(ok, "-A monitor %s -j RETURN\n", src);
518 if (!c) break;
519 p = c + 1;
520 } while (*p);
523 ip46t_write(
524 "-A monitor -p tcp -m webmon "
525 "--max_domains %d --max_searches %d %s %s -j RETURN\n",
526 nvram_get_int("log_wmdmax") ? : 1, nvram_get_int("log_wmsmax") ? : 1,
527 (clear & 1) == 0 ? "--domain_load_file /var/webmon/domain" : "--clear_domain",
528 (clear & 2) == 0 ? "--search_load_file /var/webmon/search" : "--clear_search");
530 #ifdef LINUX26
531 modprobe("xt_webmon");
532 #else
533 modprobe("ipt_webmon");
534 #endif
538 // -----------------------------------------------------------------------------
539 // MANGLE
540 // -----------------------------------------------------------------------------
542 static void mangle_table(void)
544 int ttl;
545 char *p, *wanface;
547 ip46t_write(
548 "*mangle\n"
549 ":PREROUTING ACCEPT [0:0]\n"
550 ":OUTPUT ACCEPT [0:0]\n");
552 if (wanup) {
554 ipt_qos();
555 //1 for mangle
556 ipt_qoslimit(1);
558 p = nvram_safe_get("nf_ttl");
559 if (strncmp(p, "c:", 2) == 0) {
560 p += 2;
561 ttl = atoi(p);
562 p = (ttl >= 0 && ttl <= 255) ? "set" : NULL;
564 else if ((ttl = atoi(p)) != 0) {
565 if (ttl > 0) {
566 p = "inc";
568 else {
569 ttl = -ttl;
570 p = "dec";
572 if (ttl > 255) p = NULL;
574 else p = NULL;
576 if (p) {
577 #ifdef LINUX26
578 modprobe("xt_HL");
579 #else
580 modprobe("ipt_TTL");
581 #endif
582 // set TTL on primary WAN iface only
583 wanface = wanfaces.iface[0].name;
584 ipt_write(
585 "-I PREROUTING -i %s -j TTL --ttl-%s %d\n"
586 "-I POSTROUTING -o %s -j TTL --ttl-%s %d\n",
587 wanface, p, ttl,
588 wanface, p, ttl);
589 #ifdef TCONFIG_IPV6
590 // FIXME: IPv6 HL should be configurable separately from TTL.
591 // disable it until GUI setting is implemented.
592 #if 0
593 ip6t_write(
594 "-I PREROUTING -i %s -j HL --hl-%s %d\n"
595 "-I POSTROUTING -o %s -j HL --hl-%s %d\n",
596 wan6face, p, ttl,
597 wan6face, p, ttl);
598 #endif
599 #endif
603 ip46t_write("COMMIT\n");
606 // -----------------------------------------------------------------------------
607 // NAT
608 // -----------------------------------------------------------------------------
610 static void nat_table(void)
612 char lanaddr[32];
613 char lanmask[32];
614 char lan1addr[32];
615 char lan1mask[32];
616 char lan2addr[32];
617 char lan2mask[32];
618 char lan3addr[32];
619 char lan3mask[32];
620 char dst[64];
621 char src[64];
622 char t[512];
623 char *p, *c;
624 int i;
626 ipt_write("*nat\n"
627 ":PREROUTING ACCEPT [0:0]\n"
628 ":POSTROUTING ACCEPT [0:0]\n"
629 ":OUTPUT ACCEPT [0:0]\n"
630 ":%s - [0:0]\n",
631 chain_wan_prerouting);
633 //2 for nat
634 ipt_qoslimit(2);
636 if (gateway_mode) {
637 strlcpy(lanaddr, nvram_safe_get("lan_ipaddr"), sizeof(lanaddr));
638 strlcpy(lanmask, nvram_safe_get("lan_netmask"), sizeof(lanmask));
639 strlcpy(lan1addr, nvram_safe_get("lan1_ipaddr"), sizeof(lan1addr));
640 strlcpy(lan1mask, nvram_safe_get("lan1_netmask"), sizeof(lan1mask));
641 strlcpy(lan2addr, nvram_safe_get("lan2_ipaddr"), sizeof(lan2addr));
642 strlcpy(lan2mask, nvram_safe_get("lan2_netmask"), sizeof(lan2mask));
643 strlcpy(lan3addr, nvram_safe_get("lan3_ipaddr"), sizeof(lan3addr));
644 strlcpy(lan3mask, nvram_safe_get("lan3_netmask"), sizeof(lan3mask));
647 for (i = 0; i < wanfaces.count; ++i) {
648 if (*(wanfaces.iface[i].name)) {
649 // chain_wan_prerouting
650 if (wanup) {
651 ipt_write("-A PREROUTING -d %s -j %s\n",
652 wanfaces.iface[i].ip, chain_wan_prerouting);
655 // Drop incoming packets which destination IP address is to our LAN side directly
656 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
657 wanfaces.iface[i].name,
658 lanaddr, lanmask); // note: ipt will correct lanaddr
659 if(strcmp(lan1addr,"")!=0)
660 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
661 wanfaces.iface[i].name,
662 lan1addr, lan1mask);
663 if(strcmp(lan2addr,"")!=0)
664 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
665 wanfaces.iface[i].name,
666 lan2addr, lan2mask);
667 if(strcmp(lan3addr,"")!=0)
668 ipt_write("-A PREROUTING -i %s -d %s/%s -j DROP\n",
669 wanfaces.iface[i].name,
670 lan3addr, lan3mask);
674 if (wanup) {
675 if (nvram_match("dns_intcpt", "1")) {
676 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
677 lanaddr, lanmask,
678 lanaddr, lanmask,
679 lanaddr);
680 if(strcmp(lan1addr,"")!=0)
681 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
682 lan1addr, lan1mask,
683 lan1addr, lan1mask,
684 lan1addr);
685 if(strcmp(lan2addr,"")!=0)
686 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
687 lan2addr, lan2mask,
688 lan2addr, lan2mask,
689 lan2addr);
690 if(strcmp(lan3addr,"")!=0)
691 ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
692 lan3addr, lan3mask,
693 lan3addr, lan3mask,
694 lan3addr);
697 // ICMP packets are always redirected to INPUT chains
698 ipt_write("-A %s -p icmp -j DNAT --to-destination %s\n", chain_wan_prerouting, lanaddr);
700 ipt_forward(IPT_TABLE_NAT);
701 ipt_triggered(IPT_TABLE_NAT);
704 if (nvram_get_int("upnp_enable") & 3) {
705 ipt_write(":upnp - [0:0]\n");
707 for (i = 0; i < wanfaces.count; ++i) {
708 if (*(wanfaces.iface[i].name)) {
709 if (wanup) {
710 // ! for loopback (all) to work
711 ipt_write("-A PREROUTING -d %s -j upnp\n", wanfaces.iface[i].ip);
713 else {
714 ipt_write("-A PREROUTING -i %s -j upnp\n", wanfaces.iface[i].name);
720 if (wanup) {
721 if (dmz_dst(dst)) {
722 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
723 p = t;
724 do {
725 if ((c = strchr(p, ',')) != NULL) *c = 0;
726 if (ipt_source_strict(p, src, "dmz", NULL))
727 ipt_write("-A %s %s -j DNAT --to-destination %s\n", chain_wan_prerouting, src, dst);
728 if (!c) break;
729 p = c + 1;
730 } while (*p);
734 p = "";
735 #ifdef TCONFIG_IPV6
736 switch (get_ipv6_service()) {
737 case IPV6_6IN4:
738 // avoid NATing proto-41 packets when using 6in4 tunnel
739 p = "-p ! 41";
740 break;
742 #endif
744 for (i = 0; i < wanfaces.count; ++i) {
745 if (*(wanfaces.iface[i].name)) {
746 if ((!wanup) || (nvram_get_int("net_snat") != 1))
747 ipt_write("-A POSTROUTING %s -o %s -j MASQUERADE\n", p, wanfaces.iface[i].name);
748 else
749 ipt_write("-A POSTROUTING %s -o %s -j SNAT --to-source %s\n", p, wanfaces.iface[i].name, wanfaces.iface[i].ip);
753 char *modem_ipaddr;
754 if ( (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "dhcp") || nvram_match("wan_proto", "static") )
755 && (modem_ipaddr = nvram_safe_get("modem_ipaddr")) && *modem_ipaddr && !nvram_match("modem_ipaddr","0.0.0.0") )
756 ipt_write("-A POSTROUTING -o %s -d %s -j MASQUERADE\n", nvram_safe_get("wan_ifname"), modem_ipaddr);
758 switch (nvram_get_int("nf_loopback")) {
759 case 1: // 1 = forwarded-only
760 case 2: // 2 = disable
761 break;
762 default: // 0 = all (same as block_loopback=0)
763 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
764 lanface,
765 lanaddr, lanmask,
766 lanaddr, lanmask,
767 lanaddr);
768 if (strcmp(lan1face,"")!=0)
769 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
770 lan1face,
771 lan1addr, lan1mask,
772 lan1addr, lan1mask,
773 lan1addr);
774 if (strcmp(lan2face,"")!=0)
775 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
776 lan2face,
777 lan2addr, lan2mask,
778 lan2addr, lan2mask,
779 lan2addr);
780 if (strcmp(lan3face,"")!=0)
781 ipt_write("-A POSTROUTING -o %s -s %s/%s -d %s/%s -j SNAT --to-source %s\n",
782 lan3face,
783 lan3addr, lan3mask,
784 lan3addr, lan3mask,
785 lan3addr);
786 break;
789 ipt_write("COMMIT\n");
792 // -----------------------------------------------------------------------------
793 // FILTER
794 // -----------------------------------------------------------------------------
796 static void filter_input(void)
798 char s[64];
799 char t[512];
800 char *en;
801 char *sec;
802 char *hit;
803 int n;
804 char *p, *c;
806 if ((nvram_get_int("nf_loopback") != 0) && (wanup)) { // 0 = all
807 for (n = 0; n < wanfaces.count; ++n) {
808 if (*(wanfaces.iface[n].name)) {
809 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lanface, wanfaces.iface[n].ip);
810 if (strcmp(lan1face,"")!=0)
811 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan1face, wanfaces.iface[n].ip);
812 if (strcmp(lan2face,"")!=0)
813 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan2face, wanfaces.iface[n].ip);
814 if (strcmp(lan3face,"")!=0)
815 ipt_write("-A INPUT -i %s -d %s -j DROP\n", lan3face, wanfaces.iface[n].ip);
820 ipt_write(
821 "-A INPUT -m state --state INVALID -j DROP\n"
822 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n");
824 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
825 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
827 ? what if the user uses the start button in GUI ?
828 if (nvram_get_int("telnetd_eas"))
829 if (nvram_get_int("sshd_eas"))
831 #ifdef LINUX26
832 modprobe("xt_recent");
833 #else
834 modprobe("ipt_recent");
835 #endif
837 ipt_write(
838 "-N shlimit\n"
839 "-A shlimit -m recent --set --name shlimit\n"
840 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
841 atoi(hit) + 1, sec, chain_in_drop);
843 if (n & 1) {
844 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_port"));
845 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
846 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
849 if (n & 2) ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("telnetd_port"));
852 #ifdef TCONFIG_FTP
853 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
854 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
855 #ifdef LINUX26
856 modprobe("xt_recent");
857 #else
858 modprobe("ipt_recent");
859 #endif
861 ipt_write(
862 "-N ftplimit\n"
863 "-A ftplimit -m recent --set --name ftp\n"
864 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
865 atoi(hit) + 1, sec, chain_in_drop);
866 ipt_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
868 #endif
870 ipt_write(
871 "-A INPUT -i lo -j ACCEPT\n"
872 "-A INPUT -i %s -j ACCEPT\n",
873 lanface);
874 if (strcmp(lan1face,"")!=0)
875 ipt_write(
876 "-A INPUT -i %s -j ACCEPT\n",
877 lan1face);
878 if (strcmp(lan2face,"")!=0)
879 ipt_write(
880 "-A INPUT -i %s -j ACCEPT\n",
881 lan2face);
882 if (strcmp(lan3face,"")!=0)
883 ipt_write(
884 "-A INPUT -i %s -j ACCEPT\n",
885 lan3face);
887 #ifdef TCONFIG_IPV6
888 n = get_ipv6_service();
889 switch (n) {
890 case IPV6_ANYCAST_6TO4:
891 case IPV6_6IN4:
892 // Accept ICMP requests from the remote tunnel endpoint
893 if (n == IPV6_ANYCAST_6TO4)
894 sprintf(s, "192.88.99.%d", nvram_get_int("ipv6_relay"));
895 else
896 strlcpy(s, nvram_safe_get("ipv6_tun_v4end"), sizeof(s));
897 if (*s && strcmp(s, "0.0.0.0") != 0)
898 ipt_write("-A INPUT -p icmp -s %s -j %s\n", s, chain_in_accept);
899 ipt_write("-A INPUT -p 41 -j %s\n", chain_in_accept);
900 break;
902 #endif
904 // ICMP request from WAN interface
905 if (nvram_match("block_wan", "0")) {
906 // allow ICMP packets to be received, but restrict the flow to avoid ping flood attacks
907 ipt_write("-A INPUT -p icmp -m limit --limit 1/second -j %s\n", chain_in_accept);
908 // allow udp traceroute packets
909 ipt_write("-A INPUT -p udp --dport 33434:33534 -m limit --limit 5/second -j %s\n", chain_in_accept);
912 /* Accept incoming packets from broken dhcp servers, which are sending replies
913 * from addresses other than used for query. This could lead to a lower level
914 * of security, so allow to disable it via nvram variable.
916 if (nvram_invmatch("dhcp_pass", "0") && using_dhcpc()) {
917 ipt_write("-A INPUT -p udp --sport 67 --dport 68 -j %s\n", chain_in_accept);
920 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
921 p = t;
922 do {
923 if ((c = strchr(p, ',')) != NULL) *c = 0;
925 if (ipt_source(p, s, "remote management", NULL)) {
927 if (remotemanage) {
928 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
929 s, nvram_safe_get("http_wanport"), chain_in_accept);
932 if (nvram_get_int("sshd_remote")) {
933 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
934 s, nvram_safe_get("sshd_rport"), chain_in_accept);
938 if (!c) break;
939 p = c + 1;
940 } while (*p);
942 #ifdef TCONFIG_FTP // !!TB - FTP Server
943 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
944 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
945 p = t;
946 do {
947 if ((c = strchr(p, ',')) != NULL) *c = 0;
948 if (ipt_source(p, s, "ftp", "remote access")) {
949 ipt_write("-A INPUT -p tcp %s --dport %s -j %s\n",
950 s, nvram_safe_get("ftp_port"), chain_in_accept);
952 if (!c) break;
953 p = c + 1;
954 } while (*p);
956 #endif
958 #ifdef TCONFIG_SNMP
959 if( nvram_match( "snmp_enable", "1" ) && nvram_match("snmp_remote", "1"))
961 strlcpy(t, nvram_safe_get("snmp_remote_sip"), sizeof(t));
962 p = t;
963 do {
964 if ((c = strchr(p, ',')) != NULL) *c = 0;
966 if (ipt_source(p, s, "snmp", "remote")) {
967 ipt_write("-A INPUT -p udp %s --dport %s -j %s\n",
968 s, nvram_safe_get("snmp_port"), chain_in_accept);
971 if (!c) break;
972 p = c + 1;
973 } while (*p);
975 #endif
977 // IGMP query from WAN interface
978 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
979 ipt_write("-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT\n");
980 ipt_write("-A INPUT -p udp -d 224.0.0.0/4 ! --dport 1900 -j ACCEPT\n");
983 // Routing protocol, RIP, accept
984 if (nvram_invmatch("dr_wan_rx", "0")) {
985 ipt_write("-A INPUT -p udp --dport 520 -j ACCEPT\n");
988 //BT Client ports from WAN interface
989 if (nvram_match("bt_enable", "1")) {
990 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port" ) );
991 if (nvram_match( "bt_rpc_wan", "1") )
993 ipt_write( "-A INPUT -p tcp --dport %s -j ACCEPT\n", nvram_safe_get( "bt_port_gui" ) );
997 // if logging
998 if (*chain_in_drop == 'l') {
999 ipt_write( "-A INPUT -j %s\n", chain_in_drop);
1002 // default policy: DROP
1005 // clamp TCP MSS to PMTU of WAN interface (IPv4 only?)
1006 static void clampmss(void)
1008 #if 1
1009 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
1010 #else
1011 int rmtu = nvram_get_int("wan_run_mtu");
1012 ipt_write("-A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss %d: -j TCPMSS ", rmtu - 39);
1013 if (rmtu < 576) {
1014 ipt_write("--clamp-mss-to-pmtu\n");
1016 else {
1017 ipt_write("--set-mss %d\n", rmtu - 40);
1019 #endif
1022 static void filter_forward(void)
1024 char dst[64];
1025 char src[64];
1026 char t[512];
1027 char *p, *c;
1028 int i;
1030 #ifdef TCONFIG_IPV6
1031 ip6t_write(
1032 "-A FORWARD -m rt --rt-type 0 -j DROP\n");
1033 #endif
1035 if (nvram_match("cstats_enable", "1")) {
1036 ipt_account();
1039 ip46t_write(
1040 "-A FORWARD -i %s -o %s -j ACCEPT\n", // accept all lan to lan
1041 lanface, lanface);
1042 if (strcmp(lan1face,"")!=0)
1043 ip46t_write(
1044 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1045 lan1face, lan1face);
1046 if (strcmp(lan2face,"")!=0)
1047 ip46t_write(
1048 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1049 lan2face, lan2face);
1050 if (strcmp(lan3face,"")!=0)
1051 ip46t_write(
1052 "-A FORWARD -i %s -o %s -j ACCEPT\n",
1053 lan3face, lan3face);
1055 char lanAccess[17] = "0000000000000000";
1057 const char *d, *sbr, *saddr, *dbr, *daddr, *desc;
1058 char *nv, *nvp, *b;
1059 int n;
1060 nvp = nv = strdup(nvram_safe_get("lan_access"));
1061 if (nv) {
1062 while ((b = strsep(&nvp, ">")) != NULL) {
1064 1<0<1.2.3.4<1<5.6.7.8<30,45-50<desc
1066 1 = enabled
1067 0 = src bridge
1068 1.2.3.4 = src addr
1069 1 = dst bridge
1070 5.6.7.8 = dst addr
1071 desc = desc
1073 n = vstrsep(b, "<", &d, &sbr, &saddr, &dbr, &daddr, &desc);
1074 if (*d != '1')
1075 continue;
1076 if (!ipt_addr(src, sizeof(src), saddr, "src", IPT_V4|IPT_V6, 0, "LAN access", desc))
1077 continue;
1078 if (!ipt_addr(dst, sizeof(dst), daddr, "dst", IPT_V4|IPT_V6, 0, "LAN access", desc))
1079 continue;
1081 //ipv4 only
1082 ipt_write("-A FORWARD -i %s%s -o %s%s %s %s -j ACCEPT\n",
1083 "br",
1084 sbr,
1085 "br",
1086 dbr,
1087 src,
1088 dst);
1090 if ((strcmp(src,"")==0) && (strcmp(dst,"")==0))
1091 lanAccess[((*sbr-48)+(*dbr-48)*4)] = '1';
1095 free(nv);
1097 ip46t_write(
1098 "-A FORWARD -m state --state INVALID -j DROP\n"); // drop if INVALID state
1100 // clamp tcp mss to pmtu
1101 clampmss();
1103 if (wanup) {
1104 ipt_restrictions();
1106 ipt_layer7_inbound();
1109 ipt_webmon();
1111 ip46t_write(
1112 ":wanin - [0:0]\n"
1113 ":wanout - [0:0]\n"
1114 "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n"); // already established or related (via helper)
1116 char lanN_ifname[] = "lanXX_ifname";
1117 char br;
1118 for(br=0 ; br<=3 ; br++) {
1119 char bridge[2] = "0";
1120 if (br!=0)
1121 bridge[0]+=br;
1122 else
1123 strcpy(bridge, "");
1125 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1126 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1127 char lanN_ifname2[] = "lanXX_ifname";
1128 char br2;
1129 for(br2=0 ; br2<=3 ; br2++) {
1130 if (br==br2) continue;
1132 if (lanAccess[((br)+(br2)*4)] == '1') continue;
1134 char bridge2[2] = "0";
1135 if (br2!=0)
1136 bridge2[0]+=br2;
1137 else
1138 strcpy(bridge2, "");
1140 sprintf(lanN_ifname2, "lan%s_ifname", bridge2);
1141 if (strncmp(nvram_safe_get(lanN_ifname2), "br", 2) == 0) {
1142 ipt_write("-A FORWARD -i %s -o %s -j DROP\n",
1143 nvram_safe_get(lanN_ifname),
1144 nvram_safe_get(lanN_ifname2));
1147 // ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1151 #ifdef TCONFIG_PPTPD
1152 //Add for pptp server
1153 if (nvram_match("pptpd_enable", "1")) {
1154 ipt_write("-A INPUT -p tcp --dport 1723 -j ACCEPT\n");
1155 ipt_write("-A INPUT -p 47 -j ACCEPT\n");
1157 #endif
1159 #ifdef TCONFIG_IPV6
1160 // Filter out invalid WAN->WAN connections
1161 if (*wan6face)
1162 // ip6t_write("-A FORWARD -o %s ! -i %s -j %s\n", wan6face, lanface, chain_in_drop); //shibby - we cant drop connections from WAN to LAN1-3
1163 ip6t_write("-A FORWARD -o %s -i %s -j %s\n", wan6face, wan6face, chain_in_drop); //shibby - drop connection from WAN -> WAN only
1165 #ifdef LINUX26
1166 modprobe("xt_length");
1167 ip6t_write("-A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1168 #endif
1170 // ICMPv6 rules
1171 for (i = 0; i < sizeof(allowed_icmpv6)/sizeof(int); ++i) {
1172 ip6t_write("-A FORWARD -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[i], chain_in_accept);
1175 //IPv6
1176 if (*wan6face) {
1177 ip6t_write(
1178 "-A FORWARD -i %s -j wanin\n" // generic from wan
1179 "-A FORWARD -o %s -j wanout\n", // generic to wan
1180 wan6face, wan6face);
1182 #endif
1184 //IPv4
1185 for (i = 0; i < wanfaces.count; ++i) {
1186 if (*(wanfaces.iface[i].name)) {
1187 ipt_write(
1188 "-A FORWARD -i %s -j wanin\n" // generic from wan
1189 "-A FORWARD -o %s -j wanout\n", // generic to wan
1190 wanfaces.iface[i].name, wanfaces.iface[i].name);
1194 for(br=0 ; br<=3 ; br++) {
1195 char bridge[2] = "0";
1196 if (br!=0)
1197 bridge[0]+=br;
1198 else
1199 strcpy(bridge, "");
1201 sprintf(lanN_ifname, "lan%s_ifname", bridge);
1202 if (strncmp(nvram_safe_get(lanN_ifname), "br", 2) == 0) {
1203 ip46t_write("-A FORWARD -i %s -j %s\n", nvram_safe_get(lanN_ifname), chain_out_accept);
1207 #ifdef TCONFIG_IPV6
1208 //IPv6 forward LAN->WAN accept
1209 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lanface, wan6face, chain_out_accept);
1211 if (strcmp(lan1face,"")!=0)
1212 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan1face, wan6face, chain_out_accept);
1213 if (strcmp(lan2face,"")!=0)
1214 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan2face, wan6face, chain_out_accept);
1215 if (strcmp(lan3face,"")!=0)
1216 ip6t_write("-A FORWARD -i %s -o %s -j %s\n", lan3face, wan6face, chain_out_accept);
1217 #endif
1219 // IPv4 only
1220 if (nvram_get_int("upnp_enable") & 3) {
1221 ipt_write(":upnp - [0:0]\n");
1222 for (i = 0; i < wanfaces.count; ++i) {
1223 if (*(wanfaces.iface[i].name)) {
1224 ipt_write("-A FORWARD -i %s -j upnp\n",
1225 wanfaces.iface[i].name);
1230 if (wanup) {
1231 if ((nvram_match("multicast_pass", "1")) || (nvram_match("udpxy_enable", "1"))) {
1232 ipt_write("-A wanin -p udp -d 224.0.0.0/4 -j %s\n", chain_in_accept);
1234 ipt_triggered(IPT_TABLE_FILTER);
1235 ipt_forward(IPT_TABLE_FILTER);
1236 #ifdef TCONFIG_IPV6
1237 ip6t_forward();
1238 #endif
1240 if (dmz_dst(dst)) {
1241 strlcpy(t, nvram_safe_get("dmz_sip"), sizeof(t));
1242 p = t;
1243 do {
1244 if ((c = strchr(p, ',')) != NULL) *c = 0;
1245 if (ipt_source_strict(p, src, "dmz", NULL))
1246 ipt_write("-A FORWARD -o %s %s -d %s -j %s\n", lanface, src, dst, chain_in_accept);
1247 if (!c) break;
1248 p = c + 1;
1249 } while (*p);
1253 // default policy: DROP
1256 static void filter_log(void)
1258 int n;
1259 char limit[128];
1261 n = nvram_get_int("log_limit");
1262 if ((n >= 1) && (n <= 9999)) {
1263 sprintf(limit, "-m limit --limit %d/m", n);
1265 else {
1266 limit[0] = 0;
1269 #ifdef TCONFIG_IPV6
1270 modprobe("ip6t_LOG");
1271 #endif
1272 if ((*chain_in_drop == 'l') || (*chain_out_drop == 'l')) {
1273 ip46t_write(
1274 ":logdrop - [0:0]\n"
1275 "-A logdrop -m state --state NEW %s -j LOG --log-prefix \"DROP \""
1276 #ifdef LINUX26
1277 " --log-macdecode"
1278 #endif
1279 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1280 "-A logdrop -j DROP\n"
1281 ":logreject - [0:0]\n"
1282 "-A logreject %s -j LOG --log-prefix \"REJECT \""
1283 #ifdef LINUX26
1284 " --log-macdecode"
1285 #endif
1286 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1287 "-A logreject -p tcp -j REJECT --reject-with tcp-reset\n",
1288 limit, limit);
1290 if ((*chain_in_accept == 'l') || (*chain_out_accept == 'l')) {
1291 ip46t_write(
1292 ":logaccept - [0:0]\n"
1293 "-A logaccept -m state --state NEW %s -j LOG --log-prefix \"ACCEPT \""
1294 #ifdef LINUX26
1295 " --log-macdecode"
1296 #endif
1297 " --log-tcp-sequence --log-tcp-options --log-ip-options\n"
1298 "-A logaccept -j ACCEPT\n",
1299 limit);
1303 #ifdef TCONFIG_IPV6
1304 static void filter6_input(void)
1306 char s[128];
1307 char t[512];
1308 char *en;
1309 char *sec;
1310 char *hit;
1311 int n;
1312 char *p, *c;
1314 // RFC-4890, sec. 4.4.1
1315 const int allowed_local_icmpv6[] =
1316 { 130, 131, 132, 133, 134, 135, 136,
1317 141, 142, 143,
1318 148, 149, 151, 152, 153 };
1320 ip6t_write(
1321 "-A INPUT -m rt --rt-type 0 -j %s\n"
1322 /* "-A INPUT -m state --state INVALID -j DROP\n" */
1323 "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n",
1324 chain_in_drop);
1326 #ifdef LINUX26
1327 modprobe("xt_length");
1328 ip6t_write("-A INPUT -p ipv6-nonxt -m length --length 40 -j ACCEPT\n");
1329 #endif
1331 strlcpy(s, nvram_safe_get("ne_shlimit"), sizeof(s));
1332 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && ((n = atoi(en) & 3) != 0)) {
1333 #ifdef LINUX26
1334 modprobe("xt_recent");
1335 #else
1336 modprobe("ipt_recent");
1337 #endif
1339 ip6t_write(
1340 "-N shlimit\n"
1341 "-A shlimit -m recent --set --name shlimit\n"
1342 "-A shlimit -m recent --update --hitcount %d --seconds %s --name shlimit -j %s\n",
1343 atoi(hit) + 1, sec, chain_in_drop);
1345 if (n & 1) {
1346 ip6t_write("-A INPUT -i %s -p tcp --dport %s -m state --state NEW -j shlimit\n", lanface, nvram_safe_get("sshd_port"));
1347 if (nvram_get_int("sshd_remote") && nvram_invmatch("sshd_rport", nvram_safe_get("sshd_port"))) {
1348 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j shlimit\n", nvram_safe_get("sshd_rport"));
1351 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"));
1354 #ifdef TCONFIG_FTP
1355 strlcpy(s, nvram_safe_get("ftp_limit"), sizeof(s));
1356 if ((vstrsep(s, ",", &en, &hit, &sec) == 3) && (atoi(en)) && (nvram_get_int("ftp_enable") == 1)) {
1357 #ifdef LINUX26
1358 modprobe("xt_recent");
1359 #else
1360 modprobe("ipt_recent");
1361 #endif
1363 ip6t_write(
1364 "-N ftplimit\n"
1365 "-A ftplimit -m recent --set --name ftp\n"
1366 "-A ftplimit -m recent --update --hitcount %d --seconds %s --name ftp -j %s\n",
1367 atoi(hit) + 1, sec, chain_in_drop);
1368 ip6t_write("-A INPUT -p tcp --dport %s -m state --state NEW -j ftplimit\n", nvram_safe_get("ftp_port"));
1370 #endif // TCONFIG_FTP
1372 ip6t_write(
1373 "-A INPUT -i %s -j ACCEPT\n" // anything coming from LAN
1374 "-A INPUT -i lo -j ACCEPT\n",
1375 lanface );
1377 switch (get_ipv6_service()) {
1378 case IPV6_ANYCAST_6TO4:
1379 case IPV6_NATIVE_DHCP:
1380 // allow responses from the dhcpv6 server
1381 ip6t_write("-A INPUT -p udp --dport 546 -j %s\n", chain_in_accept);
1382 break;
1385 // ICMPv6 rules
1386 for (n = 0; n < sizeof(allowed_icmpv6)/sizeof(int); n++) {
1387 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_icmpv6[n], chain_in_accept);
1389 for (n = 0; n < sizeof(allowed_local_icmpv6)/sizeof(int); n++) {
1390 ip6t_write("-A INPUT -p ipv6-icmp --icmpv6-type %i -j %s\n", allowed_local_icmpv6[n], chain_in_accept);
1393 // Remote Managment
1394 strlcpy(t, nvram_safe_get("rmgt_sip"), sizeof(t));
1395 p = t;
1396 do {
1397 if ((c = strchr(p, ',')) != NULL) *c = 0;
1399 if (ip6t_source(p, s, "remote management", NULL)) {
1401 if (remotemanage) {
1402 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1403 s, nvram_safe_get("http_wanport"), chain_in_accept);
1406 if (nvram_get_int("sshd_remote")) {
1407 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1408 s, nvram_safe_get("sshd_rport"), chain_in_accept);
1412 if (!c) break;
1413 p = c + 1;
1414 } while (*p);
1416 #ifdef TCONFIG_FTP
1417 // FTP server
1418 if (nvram_match("ftp_enable", "1")) { // FTP WAN access enabled
1419 strlcpy(t, nvram_safe_get("ftp_sip"), sizeof(t));
1420 p = t;
1421 do {
1422 if ((c = strchr(p, ',')) != NULL) *c = 0;
1423 if (ip6t_source(p, s, "ftp", "remote access")) {
1424 ip6t_write("-A INPUT -p tcp %s --dport %s -j %s\n",
1425 s, nvram_safe_get("ftp_port"), chain_in_accept);
1427 if (!c) break;
1428 p = c + 1;
1429 } while (*p);
1431 #endif
1433 // if logging
1434 if (*chain_in_drop == 'l') {
1435 ip6t_write( "-A INPUT -j %s\n", chain_in_drop);
1438 // default policy: DROP
1441 #endif
1443 static void filter_table(void)
1445 ip46t_write(
1446 "*filter\n"
1447 ":INPUT DROP [0:0]\n"
1448 ":OUTPUT ACCEPT [0:0]\n"
1451 filter_log();
1453 filter_input();
1454 #ifdef TCONFIG_IPV6
1455 filter6_input();
1456 ip6t_write("-A OUTPUT -m rt --rt-type 0 -j %s\n", chain_in_drop);
1457 #endif
1459 if ((gateway_mode) || (nvram_match("wk_mode_x", "1"))) {
1460 ip46t_write(":FORWARD DROP [0:0]\n");
1461 filter_forward();
1463 else {
1464 ip46t_write(":FORWARD ACCEPT [0:0]\n");
1465 clampmss();
1467 ip46t_write("COMMIT\n");
1470 // -----------------------------------------------------------------------------
1472 int start_firewall(void)
1474 DIR *dir;
1475 struct dirent *dirent;
1476 char s[256];
1477 char *c, *wanface;
1478 int n;
1479 int wanproto;
1480 char *iptrestore_argv[] = { "iptables-restore", (char *)ipt_fname, NULL };
1481 #ifdef TCONFIG_IPV6
1482 char *ip6trestore_argv[] = { "ip6tables-restore", (char *)ip6t_fname, NULL };
1483 #endif
1485 simple_lock("firewall");
1486 simple_lock("restrictions");
1488 wanup = check_wanup();
1490 f_write_string("/proc/sys/net/ipv4/tcp_syncookies", nvram_get_int("ne_syncookies") ? "1" : "0", 0, 0);
1492 /* NAT performance tweaks
1493 * These values can be overriden later if needed via firewall script
1495 f_write_string("/proc/sys/net/core/netdev_max_backlog", "3072", 0, 0);
1496 f_write_string("/proc/sys/net/core/somaxconn", "3072", 0, 0);
1497 f_write_string("/proc/sys/net/ipv4/tcp_max_syn_backlog", "8192", 0, 0);
1498 f_write_string("/proc/sys/net/ipv4/tcp_fin_timeout", "30", 0, 0);
1499 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_intvl", "24", 0, 0);
1500 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_probes", "3", 0, 0);
1501 f_write_string("/proc/sys/net/ipv4/tcp_keepalive_time", "1800", 0, 0);
1502 f_write_string("/proc/sys/net/ipv4/tcp_retries2", "5", 0, 0);
1503 f_write_string("/proc/sys/net/ipv4/tcp_syn_retries", "3", 0, 0);
1504 f_write_string("/proc/sys/net/ipv4/tcp_synack_retries", "3", 0, 0);
1505 f_write_string("/proc/sys/net/ipv4/tcp_tw_recycle", "1", 0, 0);
1506 f_write_string("/proc/sys/net/ipv4/tcp_tw_reuse", "1", 0, 0);
1508 /* DoS-related tweaks */
1509 f_write_string("/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses", "1", 0, 0);
1510 f_write_string("/proc/sys/net/ipv4/tcp_rfc1337", "1", 0, 0);
1511 f_write_string("/proc/sys/net/ipv4/ip_local_port_range", "1024 65535", 0, 0);
1513 wanproto = get_wan_proto();
1514 f_write_string("/proc/sys/net/ipv4/ip_dynaddr", (wanproto == WP_DISABLED || wanproto == WP_STATIC) ? "0" : "1", 0, 0);
1516 #ifdef TCONFIG_EMF
1517 /* Force IGMPv2 due EMF limitations */
1518 if (nvram_get_int("emf_enable")) {
1519 f_write_string("/proc/sys/net/ipv4/conf/default/force_igmp_version", "2", 0, 0);
1520 f_write_string("/proc/sys/net/ipv4/conf/all/force_igmp_version", "2", 0, 0);
1522 #endif
1524 n = nvram_get_int("log_in");
1525 chain_in_drop = (n & 1) ? "logdrop" : "DROP";
1526 chain_in_accept = (n & 2) ? "logaccept" : "ACCEPT";
1528 n = nvram_get_int("log_out");
1529 chain_out_drop = (n & 1) ? "logdrop" : "DROP";
1530 chain_out_reject = (n & 1) ? "logreject" : "REJECT --reject-with tcp-reset";
1531 chain_out_accept = (n & 2) ? "logaccept" : "ACCEPT";
1533 // if (nvram_match("nf_drop_reset", "1")) chain_out_drop = chain_out_reject;
1535 strlcpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1536 strlcpy(lan1face, nvram_safe_get("lan1_ifname"), IFNAMSIZ);
1537 strlcpy(lan2face, nvram_safe_get("lan2_ifname"), IFNAMSIZ);
1538 strlcpy(lan3face, nvram_safe_get("lan3_ifname"), IFNAMSIZ);
1540 memcpy(&wanfaces, get_wanfaces(), sizeof(wanfaces));
1541 wanface = wanfaces.iface[0].name;
1542 #ifdef TCONFIG_IPV6
1543 strlcpy(wan6face, get_wan6face(), sizeof(wan6face));
1544 #endif
1546 #ifdef LINUX26
1547 can_enable_fastnat = 1;
1548 #endif
1550 strlcpy(s, nvram_safe_get("lan_ipaddr"), sizeof(s));
1551 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1552 strlcpy(lan_cclass, s, sizeof(lan_cclass));
1554 strlcpy(s, nvram_safe_get("lan1_ipaddr"), sizeof(s));
1555 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1556 strlcpy(lan1_cclass, s, sizeof(lan1_cclass));
1558 strlcpy(s, nvram_safe_get("lan2_ipaddr"), sizeof(s));
1559 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1560 strlcpy(lan2_cclass, s, sizeof(lan2_cclass));
1562 strlcpy(s, nvram_safe_get("lan3_ipaddr"), sizeof(s));
1563 if ((c = strrchr(s, '.')) != NULL) *(c + 1) = 0;
1564 strlcpy(lan3_cclass, s, sizeof(lan3_cclass));
1568 block obviously spoofed IP addresses
1570 rp_filter - BOOLEAN
1571 1 - do source validation by reversed path, as specified in RFC1812
1572 Recommended option for single homed hosts and stub network
1573 routers. Could cause troubles for complicated (not loop free)
1574 networks running a slow unreliable protocol (sort of RIP),
1575 or using static routes.
1576 0 - No source validation.
1578 c = nvram_get("wan_ifname");
1579 /* mcast needs rp filter to be turned off only for non default iface */
1580 if (!(nvram_match("multicast_pass", "1")) || !(nvram_match("udpxy_enable", "1")) || strcmp(wanface, c) == 0) c = NULL;
1582 if ((dir = opendir("/proc/sys/net/ipv4/conf")) != NULL) {
1583 while ((dirent = readdir(dir)) != NULL) {
1584 sprintf(s, "/proc/sys/net/ipv4/conf/%s/rp_filter", dirent->d_name);
1585 f_write_string(s, (c && strcmp(dirent->d_name, c) == 0) ? "0" : "1", 0, 0);
1587 closedir(dir);
1590 remotemanage = 0;
1591 gateway_mode = !nvram_match("wk_mode", "router");
1592 if (gateway_mode) {
1593 /* Remote management */
1594 if (nvram_match("remote_management", "1") && nvram_invmatch("http_wanport", "") &&
1595 nvram_invmatch("http_wanport", "0")) remotemanage = 1;
1598 if ((ipt_file = fopen(ipt_fname, "w")) == NULL) {
1599 notice_set("iptables", "Unable to create iptables restore file");
1600 simple_unlock("firewall");
1601 return 0;
1604 #ifdef TCONFIG_IPV6
1605 if ((ip6t_file = fopen(ip6t_fname, "w")) == NULL) {
1606 notice_set("ip6tables", "Unable to create ip6tables restore file");
1607 simple_unlock("firewall");
1608 return 0;
1610 modprobe("nf_conntrack_ipv6");
1611 modprobe("ip6t_REJECT");
1612 #endif
1614 /* shibby
1615 if (nvram_match("imq_enable", "1")) {
1616 char numdevs[10];
1617 sprintf(numdevs, "numdevs=%d", nvram_get_int("imq_numdevs"));
1618 modprobe("imq", numdevs );
1619 #ifdef LINUX26
1620 modprobe("xt_IMQ");
1621 #else
1622 modprobe("ipt_IMQ");
1623 #endif
1627 mangle_table();
1628 nat_table();
1629 filter_table();
1631 fclose(ipt_file);
1632 ipt_file = NULL;
1634 #ifdef TCONFIG_IPV6
1635 fclose(ip6t_file);
1636 ip6t_file = NULL;
1637 #endif
1639 #ifdef DEBUG_IPTFILE
1640 if (debug_only) {
1641 simple_unlock("firewall");
1642 simple_unlock("restrictions");
1643 return 0;
1645 #endif
1647 save_webmon();
1649 if (nvram_get_int("upnp_enable") & 3) {
1650 f_write("/etc/upnp/save", NULL, 0, 0, 0);
1651 if (killall("miniupnpd", SIGUSR2) == 0) {
1652 f_wait_notexists("/etc/upnp/save", 5);
1656 notice_set("iptables", "");
1657 if (_eval(iptrestore_argv, ">/var/notice/iptables", 0, NULL) == 0) {
1658 led(LED_DIAG, 0);
1659 notice_set("iptables", "");
1661 else {
1662 sprintf(s, "%s.error", ipt_fname);
1663 rename(ipt_fname, s);
1664 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1665 led(LED_DIAG, 1);
1669 -P INPUT DROP
1670 -F INPUT
1671 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
1672 -A INPUT -i br0 -j ACCEPT
1674 -P FORWARD DROP
1675 -F FORWARD
1676 -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
1677 -A FORWARD -i br0 -j ACCEPT
1682 #ifdef TCONFIG_IPV6
1683 if (ipv6_enabled()) {
1684 notice_set("ip6tables", "");
1685 if (_eval(ip6trestore_argv, ">/var/notice/ip6tables", 0, NULL) == 0) {
1686 notice_set("ip6tables", "");
1688 else {
1689 sprintf(s, "%s.error", ip6t_fname);
1690 rename(ip6t_fname, s);
1691 syslog(LOG_CRIT, "Error while loading rules. See %s file.", s);
1692 led(LED_DIAG, 1);
1695 else {
1696 eval("ip6tables", "-F");
1697 eval("ip6tables", "-t", "mangle", "-F");
1699 #endif
1701 if (nvram_get_int("upnp_enable") & 3) {
1702 f_write("/etc/upnp/load", NULL, 0, 0, 0);
1703 killall("miniupnpd", SIGUSR2);
1706 simple_unlock("restrictions");
1707 sched_restrictions();
1708 enable_ip_forward();
1710 led(LED_DMZ, dmz_dst(NULL));
1712 #ifdef TCONFIG_IPV6
1713 modprobe_r("nf_conntrack_ipv6");
1714 modprobe_r("ip6t_LOG");
1715 modprobe_r("ip6t_REJECT");
1716 #endif
1717 #ifdef LINUX26
1718 modprobe_r("xt_layer7");
1719 modprobe_r("xt_recent");
1720 modprobe_r("xt_HL");
1721 modprobe_r("xt_length");
1722 modprobe_r("xt_web");
1723 modprobe_r("xt_webmon");
1724 modprobe_r("xt_dscp");
1725 #else
1726 modprobe_r("ipt_layer7");
1727 modprobe_r("ipt_recent");
1728 modprobe_r("ipt_TTL");
1729 modprobe_r("ipt_web");
1730 modprobe_r("ipt_webmon");
1731 modprobe_r("ipt_dscp");
1732 #endif
1733 modprobe_r("ipt_ipp2p");
1735 unlink("/var/webmon/domain");
1736 unlink("/var/webmon/search");
1738 #ifdef TCONFIG_OPENVPN
1739 run_vpn_firewall_scripts();
1740 #endif
1741 run_nvscript("script_fire", NULL, 1);
1743 #ifdef LINUX26
1744 allow_fastnat("firewall", can_enable_fastnat);
1745 try_enabling_fastnat();
1746 #endif
1747 simple_unlock("firewall");
1748 return 0;
1751 int stop_firewall(void)
1753 led(LED_DMZ, 0);
1754 return 0;
1757 #ifdef DEBUG_IPTFILE
1758 void create_test_iptfile(void)
1760 debug_only = 1;
1761 start_firewall();
1762 debug_only = 0;
1764 #endif