source: src/router/services/networking/firewall.c @ 32652

Last change on this file since 32652 was 32652, checked in by brainslayer, 10 days ago

disable shortpath if wshaper is enabled

File size: 90.2 KB
Line 
1/*
2 * firewall.c
3 *
4 * Copyright (C) 2007 Sebastian Gottschall <gottschall@dd-wrt.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * $Id:
21 */
22
23// #define DEVELOPE_ENV
24// #define XBOX_SUPPORT /* Define Microsoft XBox, game machine, support */
25#define AOL_SUPPORT             /* Define AOL support */
26// #define FLOOD_PROTECT /* Define flooding protection */
27// #define REVERSE_RULE_ORDER /* If it needs to reverse the rule's
28// sequential. It is used
29// when the MARK match/target be using. */
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <signal.h>
35#include <sys/socket.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38#include <sys/types.h>
39#include <dirent.h>
40#include <time.h>
41#include <net/if.h>
42#include <sys/stat.h>
43#include <unistd.h>
44#include <stdarg.h>
45#include <ctype.h>
46#include <limits.h>
47#include <l7protocols.h>
48
49#ifndef DEVELOPE_ENV
50#include <bcmnvram.h>
51#include <shutils.h>
52#include <rc.h>
53#include <code_pattern.h>
54#include <utils.h>
55#include <wlutils.h>
56#include <cy_conf.h>
57#endif                          /* DEVELOPE_ENV */
58#include <services.h>
59
60/*
61 * Same as the file "linux/netfilter_ipv4/ipt_webstr.h"
62 */
63#define BLK_JAVA                                0x01
64#define BLK_ACTIVE                              0x02
65#define BLK_COOKIE                              0x04
66#define BLK_PROXY                               0x08
67
68/*
69 * possible files path
70 */
71#define IPTABLES_SAVE_FILE              "/tmp/.ipt"
72#define CRONTAB                         "/tmp/crontab"
73#define IPTABLES_RULE_STAT              "/tmp/.rule"
74
75/*
76 * Known port
77 */
78#define DNS_PORT                53      /* UDP */
79#define TFTP_PORT               69      /* UDP */
80#define ISAKMP_PORT     500     /* UDP */
81#define RIP_PORT                520     /* UDP */
82#define L2TP_PORT               1701    /* UDP */
83
84#define HTTP_PORT               80      /* TCP */
85#define IDENT_PORT              113     /* TCP */
86#define HTTPS_PORT              443     /* TCP */
87#define PPTP_PORT               1723    /* TCP */
88
89#define IP_MULTICAST                    "224.0.0.0/4"
90
91/*
92 * Limitation definition
93 */
94#define NR_RULES                10
95#define NR_IPGROUPS     5
96#define NR_MACGROUPS    5
97
98/*
99 * MARK number in mangle table
100 */
101#define MARK_OFFSET     0x10
102// #define MARK_MASK 0xf0
103#define MARK_DROP               0x1e
104// #define MARK_ACCEPT 0x1f
105// #define MARK_HTTP 0x30
106#define MARK_LAN2WAN    0x100   /* For HotSpot */
107
108#ifdef FLOOD_PROTECT
109#define FLOOD_RATE              200
110#define TARG_PASS               "limaccept"     /* limited of accepting chain
111                                                 */
112#define TARG_RST                "logreject"
113#else
114#define TARG_PASS               "ACCEPT"
115#define TARG_RST                "REJECT --reject-with tcp-reset"
116#endif
117
118#if 0
119#define DEBUG printf
120#else
121#define DEBUG(format, args...)
122#endif
123
124static char *suspense;
125static unsigned int count = 0;
126static char log_accept[15];
127static char log_drop[15];
128static char log_reject[64];
129static char wanface[IFNAMSIZ];
130static char lanface[IFNAMSIZ];
131static char lan_cclass[] = "xxx.xxx.xxx.";
132static char wanaddr[] = "xxx.xxx.xxx.xxx";
133static int web_lanport = HTTP_PORT;
134
135static FILE *ifd;               /* /tmp/.rule */
136static FILE *cfd;               /* /tmp/crontab */
137
138static unsigned int now_wday, now_hrmin;
139static int webfilter = 0;
140static int dmzenable = 0;
141static int remotemanage = 0;
142
143#ifdef HAVE_SSHD
144static int remotessh = 0;       /* Botho 03-05-2006 */
145#endif
146
147#ifdef HAVE_TELNET
148static int remotetelnet = 0;
149#endif
150static void save2file(const char *fmt, ...)
151{
152        char buf[10240];
153        va_list args;
154        FILE *fp;
155
156        if ((fp = fopen(IPTABLES_SAVE_FILE, "a")) == NULL) {
157                printf("Can't open /tmp/.ipt\n");
158                exit(1);
159        }
160
161        va_start(args, fmt);
162        vsnprintf(buf, sizeof(buf), fmt, args);
163        va_end(args);
164        va_start(args, fmt);
165        fprintf(fp, "%s", buf);
166        va_end(args);
167
168        fclose(fp);
169}
170
171static int isstandalone(char *name)
172{
173        return (nvram_nmatch("0", "%s_bridged", name) || isbridge(name)) ? 1 : 0;
174}
175
176#if 0
177#define DEBUG printf
178#else
179#define DEBUG(format, args...)
180#endif
181
182#define IPTABLES_RULE_STAT      "/tmp/.rule"
183
184/****************** Below is for 'filter' command *******************/
185
186/*
187 * update_bitmap:
188 *
189 * Update bitmap file for activative rule when we insert/delete
190 * rule. This file is for tracking the status of filter setting.
191 *
192 * PARAM - mode 0 : delete
193 *                              1 : insert
194 *
195 * RETURN - The rule order.
196 *
197 * Example:
198 *      mode = 1, seq = 7
199 *      before = 0,1,1,0,1,0,0,0,1,1,
200 *      after  = 0,1,1,0,1,0,1,0,1,1,
201 *      return = 3
202 */
203static int update_bitmap(int mode, int seq)
204{
205        FILE *fd;
206        char buf[100];
207        char sep[] = ",";
208        char *token;
209
210        int k, i = 1, order = 0;
211        int array[100];
212
213#if defined(REVERSE_RULE_ORDER)
214        seq = (NR_RULES + 1) - seq;
215#endif
216        /*
217         * Read active-rule bitmap
218         */
219        if ((fd = fopen(IPTABLES_RULE_STAT, "r")) == NULL) {
220                cprintf("Can't open %s\n", IPTABLES_RULE_STAT);
221                exit(1);
222        }
223        fgets(buf, sizeof(buf), fd);
224
225        token = strtok(buf, sep);
226        while (token != NULL) {
227                if (*token != '0' && *token != '1')
228                        break;
229
230                array[i] = atoi(token);
231
232                if (i < seq)
233                        order += array[i];
234                i++;
235                token = strtok(NULL, sep);
236        }
237
238        fclose(fd);
239
240        /*
241         * Modify setting
242         */
243        if (mode == 1) {        /* add */
244                if (array[seq] == 1)
245                        return -1;
246                array[seq] = 1;
247        } else {                /* delete */
248                if (array[seq] == 0)
249                        return -1;
250                array[seq] = 0;
251        }
252
253        /*
254         * Write back active-rule bitmap
255         */
256        if ((fd = fopen(IPTABLES_RULE_STAT, "w")) == NULL) {
257                cprintf("Can't open %s\n", IPTABLES_RULE_STAT);
258                exit(1);
259        }
260        for (k = 1; k < i; k++)
261                fprintf(fd, "%d,", array[k]);
262
263        fclose(fd);
264
265        return order;
266}
267
268static int ip2cclass(char *ipaddr, char *new, int count)
269{
270        int ip[4];
271
272        if (sscanf(ipaddr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) != 4)
273                return 0;
274
275        return snprintf(new, count, "%d.%d.%d.", ip[0], ip[1], ip[2]);
276}
277
278static void parse_port_forward(char *wordlist)
279{
280        char var[256], *next;
281        char *name, *enable, *proto, *port, *ip;
282        char buff[256], ip2[16];
283        int flag_dis = 0;
284#if defined (HAVE_PPTP) || defined (HAVE_L2TP) || defined (HAVE_PPPOEDUAL)
285        char *wan_proto = nvram_safe_get("wan_proto");
286        char *wan_iface = nvram_safe_get("wan_ifname");
287        if (!strlen(wan_iface))
288                wan_iface = nvram_safe_get("wan_ifname2");
289#endif
290
291        /*
292         * name:enable:proto:port>ip name:enable:proto:port>ip
293         */
294        foreach(var, wordlist, next) {
295                enable = var;
296                name = strsep(&enable, ":");
297                if (!name || !enable)
298                        continue;
299                proto = enable;
300                enable = strsep(&proto, ":");
301                if (!enable || !proto)
302                        continue;
303                port = proto;
304                proto = strsep(&port, ":");
305                if (!proto || !port)
306                        continue;
307                ip = port;
308                port = strsep(&ip, ">");
309                if (!port || !ip)
310                        continue;
311
312                /*
313                 * skip if it's disabled
314                 */
315                if (strcmp(enable, "off") == 0)
316                        flag_dis = 1;
317                else
318                        flag_dis = 0;
319
320                /*
321                 * Sveasoft fix for old single number format
322                 */
323                if (!sv_valid_ipaddr(ip) && sv_valid_range(ip, 1, 254)) {
324                        snprintf(ip2, 15, "%s%s", lan_cclass, ip);
325                        ip = ip2;
326                }
327
328                /*
329                 * -A PREROUTING -i eth1 -p tcp --dport 8899:88 -j DNAT
330                 * --to-destination 192.168.1.88:0 -A PREROUTING -i eth1 -p tcp -m
331                 * tcp --dport 9955:99 -j DNAT --to-destination 192.168.1.99:0
332                 */
333                if (!strcmp(proto, "tcp") || !strcmp(proto, "both")) {
334                        bzero(buff, sizeof(buff));
335
336                        if (flag_dis == 0) {
337                                save2file("-A PREROUTING -p tcp -d %s --dport %s -j DNAT --to-destination %s\n", wanaddr, port, ip);
338#if defined (HAVE_PPTP) || defined (HAVE_L2TP) || defined (HAVE_PPPOEDUAL)
339                                if (!strcmp(wan_proto, "pppoe_dual") || (!strcmp(wan_proto, "pptp") && nvram_matchi("wan_dualaccess", 1)) || (!strcmp(wan_proto, "l2tp") && nvram_matchi("wan_dualaccess", 1))
340                                    )
341                                        save2file("-A PREROUTING -i %s -p tcp --dport %s -j DNAT --to-destination %s\n", wan_iface, port, ip);
342#endif
343                                snprintf(buff, sizeof(buff), "-A FORWARD -p tcp -m tcp -d %s --dport %s -j %s\n", ip, port, log_accept);
344                        } else {
345                                if ((!dmzenable)
346                                    || (dmzenable && strcmp(ip, nvram_safe_get("dmz_ipaddr")))) {
347                                        snprintf(buff, sizeof(buff), "-A FORWARD -p tcp -m tcp -d %s --sport %s -j %s\n", ip, port, log_drop);
348                                }
349                        }
350
351                        count += strlen(buff) + 1;
352                        suspense = realloc(suspense, count);
353                        strcat(suspense, buff);
354                }
355
356                if (!strcmp(proto, "udp") || !strcmp(proto, "both")) {
357                        bzero(buff, sizeof(buff));
358                        if (flag_dis == 0) {
359                                save2file("-A PREROUTING -p udp -d %s --dport %s -j DNAT --to-destination %s\n", wanaddr, port, ip);
360#if defined (HAVE_PPTP) || defined (HAVE_L2TP) || defined (HAVE_PPPOEDUAL)
361                                if (!strcmp(wan_proto, "pppoe_dual") || (!strcmp(wan_proto, "pptp") && nvram_matchi("wan_dualaccess", 1)) || (!strcmp(wan_proto, "l2tp") && nvram_matchi("wan_dualaccess", 1))
362                                    )
363                                        save2file("-A PREROUTING -i %s -p udp -m udp --dport %s -j DNAT --to-destination %s\n", wan_iface, port, ip);
364#endif
365                                snprintf(buff, sizeof(buff), "-A FORWARD -p udp -m udp -d %s --dport %s -j %s\n", ip, port, log_accept);
366                        } else {
367                                if ((!dmzenable)
368                                    || (dmzenable && strcmp(ip, nvram_safe_get("dmz_ipaddr")))) {
369                                        snprintf(buff, sizeof(buff), "-A FORWARD -p udp -m udp -d %s --dport %s -j %s\n", ip, port, log_drop);
370
371                                }
372                        }
373                        count += strlen(buff) + 1;
374                        suspense = realloc(suspense, count);
375                        strcat(suspense, buff);
376                }
377        }
378}
379
380#ifdef HAVE_UPNP
381static void parse_upnp_forward()
382{
383        char name[32];          // = "forward_portXXXXXXXXXX";
384        char value[1000];
385        char *wan_port0, *wan_port1, *lan_ipaddr, *lan_port0, *lan_port1, *proto;
386        char *enable, *desc;
387        char buff[256];
388        int i;
389
390        if (nvram_invmatchi("upnp_enable", 1))
391                return;
392
393        if (nvram_matchi("upnp_clear", 1)) {    // tofu10
394                nvram_unset("upnp_clear");
395                for (i = 0; i < 1000; ++i) {
396                        sprintf(name, "forward_port%d", i);
397                        nvram_unset(name);
398                }
399                nvram_seti("forward_cur", 0);
400                return;
401        }
402
403        /*
404         * Set
405         * wan_port0-wan_port1>lan_ipaddr:lan_port0-lan_port1,proto,enable,desc
406         */
407        for (i = 0; i < 50; i++) {
408                snprintf(name, sizeof(name), "forward_port%d", i);
409
410                strncpy(value, nvram_safe_get(name), sizeof(value));
411
412                /*
413                 * Check for LAN IP address specification
414                 */
415                lan_ipaddr = value;
416                wan_port0 = strsep(&lan_ipaddr, ">");
417                if (!lan_ipaddr)
418                        continue;
419
420                /*
421                 * Check for LAN destination port specification
422                 */
423                lan_port0 = lan_ipaddr;
424                lan_ipaddr = strsep(&lan_port0, ":");
425                if (!lan_port0)
426                        continue;
427
428                /*
429                 * Check for protocol specification
430                 */
431                proto = lan_port0;
432                lan_port0 = strsep(&proto, ":,");
433                if (!proto)
434                        continue;
435
436                /*
437                 * Check for enable specification
438                 */
439                enable = proto;
440                proto = strsep(&enable, ":,");
441                if (!enable)
442                        continue;
443
444                /*
445                 * Check for description specification (optional)
446                 */
447                desc = enable;
448                enable = strsep(&desc, ":,");
449
450                /*
451                 * Check for WAN destination port range (optional)
452                 */
453                wan_port1 = wan_port0;
454                wan_port0 = strsep(&wan_port1, "-");
455                if (!wan_port1)
456                        wan_port1 = wan_port0;
457
458                /*
459                 * Check for LAN destination port range (optional)
460                 */
461                lan_port1 = lan_port0;
462                lan_port0 = strsep(&lan_port1, "-");
463                if (!lan_port1)
464                        lan_port1 = lan_port0;
465
466                /*
467                 * skip if it's disabled
468                 */
469                if (strcmp(enable, "off") == 0)
470                        continue;
471
472                /*
473                 * skip if it's illegal ip
474                 */
475                if (get_single_ip(lan_ipaddr, 3) == 0 || get_single_ip(lan_ipaddr, 3) == 255)
476                        continue;
477
478                /*
479                 * -A PREROUTING -p tcp --dport 823 -j DNAT --to-destination
480                 * 192.168.1.88:23
481                 */
482                char *wan = wanface;
483                if (!strlen(wan)) {
484                        wan = "br0";
485                }
486
487                if (!strcmp(proto, "tcp") || !strcmp(proto, "both")) {
488                        save2file("-A PREROUTING -i %s -p tcp -d %s --dport %s -j DNAT --to-destination %s%d:%s\n", wan, wanaddr, wan_port0, lan_cclass, get_single_ip(lan_ipaddr, 3), lan_port0);
489
490                        snprintf(buff, sizeof(buff), "-A FORWARD -p tcp -m tcp -d %s%d --dport %s -j %s\n", lan_cclass, get_single_ip(lan_ipaddr, 3), lan_port0, log_accept);
491
492                        count += strlen(buff) + 1;
493                        suspense = realloc(suspense, count);
494                        strcat(suspense, buff);
495                }
496                if (!strcmp(proto, "udp") || !strcmp(proto, "both")) {
497                        save2file("-A PREROUTING -i %s -p udp -d %s --dport %s -j DNAT --to-destination %s%d:%s\n", wan, wanaddr, wan_port0, lan_cclass, get_single_ip(lan_ipaddr, 3), lan_port0);
498
499                        snprintf(buff, sizeof(buff), "-A FORWARD -p udp -m udp -d %s%d --dport %s -j %s\n", lan_cclass, get_single_ip(lan_ipaddr, 3), lan_port0, log_accept);
500
501                        count += strlen(buff) + 1;
502                        suspense = realloc(suspense, count);
503                        strcat(suspense, buff);
504                }
505        }
506}
507#endif
508static void create_spec_forward(char *proto, char *src, char *wanaddr, char *from, char *ip, char *to)
509{
510        char buff[256];
511#if defined (HAVE_PPTP) || defined (HAVE_L2TP) || defined (HAVE_PPPOEDUAL)
512        char *wan_proto = nvram_safe_get("wan_proto");
513        char *wan_iface = nvram_safe_get("wan_ifname");
514        if (!strlen(wan_iface))
515                wan_iface = nvram_safe_get("wan_ifname2");
516#endif
517        if (src && strlen(src) > 0) {
518                save2file("-A PREROUTING -p %s -m %s -s %s -d %s --dport %s -j DNAT --to-destination %s:%s\n", proto, proto, src, wanaddr, from, ip, to);
519#if defined (HAVE_PPTP) || defined (HAVE_L2TP) || defined (HAVE_PPPOEDUAL)
520                if (!strcmp(wan_proto, "pppoe_dual") || (!strcmp(wan_proto, "pptp") && nvram_matchi("wan_dualaccess", 1)) || (!strcmp(wan_proto, "l2tp") && nvram_matchi("wan_dualaccess", 1))
521                    )
522                        save2file("-A PREROUTING -i %s -p %s -m %s --dport %s -j DNAT --to-destination %s:%s\n", wan_iface, proto, proto, from, ip, to);
523#endif
524                if (!strcmp(nvram_get("lan_ipaddr"), ip)) {
525                        snprintf(buff, sizeof(buff), "-I INPUT -p %s -m %s -s %s -d %s --dport %s -j %s\n", proto, proto, src, ip, to, log_accept);
526                } else {
527                        snprintf(buff, sizeof(buff), "-A FORWARD -p %s -m %s -s %s -d %s --dport %s -j %s\n", proto, proto, src, ip, to, log_accept);
528                }
529        } else {
530                save2file("-A PREROUTING -p %s -m %s -d %s --dport %s -j DNAT --to-destination %s:%s\n", proto, proto, wanaddr, from, ip, to);
531#if defined (HAVE_PPTP) || defined (HAVE_L2TP) || defined (HAVE_PPPOEDUAL)
532                if (!strcmp(wan_proto, "pppoe_dual") || (!strcmp(wan_proto, "pptp") && nvram_matchi("wan_dualaccess", 1)) || (!strcmp(wan_proto, "l2tp") && nvram_matchi("wan_dualaccess", 1))
533                    )
534                        save2file("-A PREROUTING -i %s -p %s -m %s --dport %s -j DNAT --to-destination %s:%s\n", wan_iface, proto, proto, from, ip, to);
535#endif
536                if (!strcmp(nvram_get("lan_ipaddr"), ip)) {
537                        snprintf(buff, sizeof(buff), "-I INPUT -p %s -m %s -d %s --dport %s -j %s\n", proto, proto, ip, to, log_accept);
538                } else {
539                        snprintf(buff, sizeof(buff), "-A FORWARD -p %s -m %s -d %s --dport %s -j %s\n", proto, proto, ip, to, log_accept);
540                }
541        }
542        count += strlen(buff) + 1;
543        suspense = realloc(suspense, count);
544        strcat(suspense, buff);
545
546}
547
548static void parse_spec_forward(char *wordlist)
549{
550        char var[256], *next;
551        char *name, *enable, *proto, *from, *to, *ip, *src;
552        char buff[256];
553
554        /*
555         * name:enable:proto:ext_port>ip:int_port
556         * name:enable:proto:ext_port>ip:int_port
557         */
558        foreach(var, wordlist, next) {
559                enable = var;
560                name = strsep(&enable, ":");
561                if (!name || !enable)
562                        continue;
563                proto = enable;
564                enable = strsep(&proto, ":");
565                if (!enable || !proto)
566                        continue;
567                from = proto;
568                proto = strsep(&from, ":");
569                if (!proto || !from)
570                        continue;
571                ip = from;
572                from = strsep(&ip, ">");
573                if (!from || !ip)
574                        continue;
575                to = ip;
576                ip = strsep(&to, ":");
577                if (!ip || !to)
578                        continue;
579
580                src = to;
581                to = strsep(&src, "<");
582                if (!to) {
583                        to = src;
584                        src = NULL;
585                }
586                // cprintf("%s %s %s %s %s\n",enable,proto,from,ip,to);
587
588                /*
589                 * skip if it's disabled
590                 */
591                if (strcmp(enable, "off") == 0)
592                        continue;
593
594                /*
595                 * -A PREROUTING -i eth1 -p tcp -d 192.168.88.11 --dport 823
596                 * -j DNAT --to-destination 192.168.1.88:23
597                 */
598
599                if (!strcmp(proto, "tcp") || !strcmp(proto, "both")) {
600                        create_spec_forward("tcp", src, wanaddr, from, ip, to);
601                }
602                if (!strcmp(proto, "udp") || !strcmp(proto, "both")) {
603                        create_spec_forward("udp", src, wanaddr, from, ip, to);
604                }
605        }
606}
607
608static void nat_prerouting(void)
609{
610        char var[256], *wordlist, *next;
611        char from[100], to[100];
612        char *remote_ip_any = nvram_default_get("remote_ip_any", "1");
613        char *remote_ip = nvram_default_get("remote_ip", "0.0.0.0 0");
614        char *lan_ip = nvram_safe_get("lan_ipaddr");
615        int remote_any = 0;
616
617        char vifs[256];
618
619        if (!strcmp(remote_ip_any, "1") || !strncmp(remote_ip, "0.0.0.0", 7))
620                remote_any = 1;
621
622        getIfLists(vifs, 256);
623
624        if (nvram_matchi("dns_redirect", 1) && nvram_matchi("dnsmasq_enable", 1)) {
625                save2file("-A PREROUTING -i %s -p udp --dport 53 -j DNAT --to %s\n", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_ipaddr"));
626                save2file("-A PREROUTING -i %s -p tcp --dport 53 -j DNAT --to %s\n", nvram_safe_get("lan_ifname"), nvram_safe_get("lan_ipaddr"));
627        }
628        foreach(var, vifs, next) {
629                if (strcmp(get_wan_face(), var)
630                    && strcmp(nvram_safe_get("lan_ifname"), var)) {
631                        if (nvram_nmatch("1", "%s_dns_redirect", var)) {
632                                char *target = nvram_nget("%s_dns_ipaddr", var);
633                                if (target && strlen(target) && sv_valid_ipaddr(target) && strcmp(target, "0.0.0.0")) {
634                                        save2file("-A PREROUTING -i %s -p udp --dport 53 -j DNAT --to %s\n", var, target);
635                                        save2file("-A PREROUTING -i %s -p tcp --dport 53 -j DNAT --to %s\n", var, target);
636                                } else {
637                                        save2file("-A PREROUTING -i %s -p udp --dport 53 -j DNAT --to %s\n", var, nvram_safe_get("lan_ipaddr"));
638                                        save2file("-A PREROUTING -i %s -p tcp --dport 53 -j DNAT --to %s\n", var, nvram_safe_get("lan_ipaddr"));
639                                }
640                        }
641                }
642        }
643
644        /*
645         * Block ads on all http requests
646         */
647#ifdef HAVE_PRIVOXY
648        if (nvram_matchi("privoxy_transp_enable", 1) && nvram_matchi("privoxy_enable", 1)) {
649
650                char vif_ip[32];
651                foreach(var, vifs, next) {
652                        if (strcmp(get_wan_face(), var)
653                            && strcmp(nvram_safe_get("lan_ifname"), var)) {
654                                if (nvram_nmatch("1", "%s_isolation", var)) {
655                                        save2file("-A PREROUTING -i %s -d %s/%s -j RETURN\n", var, lan_ip, nvram_safe_get("lan_netmask"));
656                                        sprintf(vif_ip, "%s_ipaddr", var);
657                                        save2file("-A PREROUTING -i %s -d %s -j RETURN\n", var, nvram_safe_get(vif_ip));
658                                }
659                        }
660                }
661
662                /* no gui setting yet - redirect all except this IP */
663                if (strlen(nvram_safe_get("privoxy_transp_exclude"))) {
664                        save2file("-A PREROUTING -p tcp -s %s --dport 80 -j ACCEPT \n", nvram_safe_get("privoxy_transp_exclude"));
665                }
666                /* block access from privoxy to webif */
667                save2file("-A PREROUTING -p tcp -s %s -d %s --dport %d -j DROP\n", lan_ip, lan_ip, web_lanport);
668                /* do not filter access to the webif from lan */
669                save2file("-A PREROUTING -p tcp -s %s/%s -d %s --dport %d -j ACCEPT\n", lan_ip, nvram_safe_get("lan_netmask"), lan_ip, web_lanport);
670                /* go through proxy */
671                save2file("-A PREROUTING -p tcp -d ! %s --dport 80 -j DNAT --to %s:8118\n", wanaddr, lan_ip);
672        }
673#endif
674#ifdef HAVE_TOR
675        if (nvram_matchi("tor_transparent", 1) && nvram_matchi("tor_enable", 1)) {
676                save2file("-A PREROUTING -i br0 -p udp --dport 53 -j DNAT --to %s:53\n", lan_ip);
677                save2file("-A PREROUTING -i br0 -p tcp --syn -j DNAT --to %s:9040\n", lan_ip);
678        }
679#endif
680
681        /*
682         * Enable remote Web GUI management
683         */
684        char tmp[1024];
685        if (remotemanage) {
686                if (remote_any) {
687                        save2file("-A PREROUTING -p tcp -d %s --dport %s -j DNAT --to-destination %s:%d\n", wanaddr, nvram_safe_get("http_wanport"), lan_ip, web_lanport);
688                } else {
689                        sscanf(remote_ip, "%s %s", from, to);
690                        wordlist = range(from, get_complete_ip(from, to), tmp);
691
692                        foreach(var, wordlist, next) {
693                                save2file("-A PREROUTING -p tcp -s %s -d %s --dport %s -j DNAT --to-destination %s:%d\n", var, wanaddr, nvram_safe_get("http_wanport"), lan_ip, web_lanport);
694                        }
695                }
696        }
697#ifdef HAVE_SSHD
698        /*
699         * Enable remote ssh management : Botho 03-05-2006
700         */
701        if (remotessh) {
702                if (remote_any) {
703                        save2file("-A PREROUTING -p tcp -d %s --dport %s -j DNAT --to-destination %s:%s\n", wanaddr, nvram_safe_get("sshd_wanport"), lan_ip, nvram_safe_get("sshd_port"));
704                } else {
705                        sscanf(remote_ip, "%s %s", from, to);
706
707                        wordlist = range(from, get_complete_ip(from, to), tmp);
708
709                        foreach(var, wordlist, next) {
710                                save2file("-A PREROUTING -p tcp -s %s -d %s --dport %s -j DNAT --to-destination %s:%s\n", var, wanaddr, nvram_safe_get("sshd_wanport"), lan_ip, nvram_safe_get("sshd_port"));
711                        }
712                }
713        }
714#endif
715
716#ifdef HAVE_TELNET
717        /*
718         * Enable remote telnet management
719         */
720        if (remotetelnet) {
721                if (remote_any) {
722                        save2file("-A PREROUTING -p tcp -d %s --dport %s -j DNAT --to-destination %s:23\n", wanaddr, nvram_safe_get("telnet_wanport"), lan_ip);
723                } else {
724                        sscanf(remote_ip, "%s %s", from, to);
725
726                        wordlist = range(from, get_complete_ip(from, to), tmp);
727
728                        foreach(var, wordlist, next) {
729                                save2file("-A PREROUTING -p tcp -s %s -d %s --dport %s -j DNAT --to-destination %s:23\n", var, wanaddr, nvram_safe_get("telnet_wanport"), lan_ip);
730                        }
731                }
732        }
733#endif
734
735        /*
736         * ICMP packets are always redirected to INPUT chains
737         */
738        save2file("-A PREROUTING -p icmp -d %s -j DNAT --to-destination %s\n", wanaddr, lan_ip);
739
740#ifdef HAVE_TFTP
741        /*
742         * Enable remote upgrade
743         */
744        if (nvram_matchi("remote_upgrade", 1))
745                save2file("-A PREROUTING -p udp -d %s --dport %d -j DNAT --to-destination %s\n", wanaddr, TFTP_PORT, lan_ip);
746#endif
747
748        /*
749         * Initiate suspense string for parse_port_forward()
750         */
751        suspense = malloc(1);
752        *suspense = 0;
753        count = 1;
754
755        if (has_gateway()) {
756                writeprocsysnet("netfilter/nf_conntrack_helper", "1");  // kerne 4.7 uses 0 as new default which disables several nat helpers
757
758                /*
759                 * Port forwarding
760                 */
761#ifdef HAVE_UPNP
762                parse_upnp_forward();
763#endif
764                parse_spec_forward(nvram_safe_get("forward_spec"));
765                parse_port_forward(nvram_safe_get("forward_port"));
766                /*
767                 * DD-WRT addition by Eric Sauvageau
768                 */
769                save2file("-A PREROUTING -d %s -j TRIGGER --trigger-type dnat\n", wanaddr);
770                /*
771                 * DD-WRT addition end
772                 */
773        }
774
775        /*
776         * DMZ forwarding
777         */
778        if (dmzenable)
779                save2file("-A PREROUTING -d %s -j DNAT --to-destination %s%s\n", wanaddr, lan_cclass, nvram_safe_get("dmz_ipaddr"));
780
781}
782
783static int wanactive(void)
784{
785        return (!nvram_match("wan_proto", "disabled") && strcmp(wanaddr, "0.0.0.0") && check_wan_link(0));
786}
787
788static void nat_postrouting(void)
789{
790        if (has_gateway()) {
791
792                // added for logic test
793                int loopmask = 0;
794                char *nmask = nvram_safe_get("lan_netmask");    // assuming
795                loopmask = getmask(nmask);
796
797                // if (strlen (wanface) > 0)
798                // save2file
799                // ("-A POSTROUTING -p udp -o %s --sport 5060:5070 -j
800                // MASQUERADE "
801                // "--to-ports 5056-5071\n", wanface);
802                if (nvram_matchi("dtag_vlan8", 1) && nvram_matchi("wan_vdsl", 1)) {
803                        save2file("-A POSTROUTING -o %s -j SNAT --to-source %s\n", nvram_safe_get("tvnicfrom"), nvram_safe_get("tvnicaddr"));
804                }
805                if (strlen(wanface) > 0 && wanactive()
806                    && !nvram_matchi("br0_nat", 0))
807                        save2file("-A POSTROUTING -s %s/%d -o %s -j SNAT --to-source %s\n", nvram_safe_get("lan_ipaddr"), loopmask, wanface, wanaddr);
808
809                char *wan_ifname_tun = nvram_safe_get("wan_ifname");
810                if (isClient()) {
811                        wan_ifname_tun = getSTA();
812                }
813#if defined (HAVE_PPTP) || defined (HAVE_L2TP) || defined (HAVE_PPPOEDUAL)
814                char *wan_proto = nvram_safe_get("wan_proto");
815                if (!strcmp(wan_proto, "pppoe_dual") || (!strcmp(wan_proto, "pptp") && nvram_matchi("wan_dualaccess", 1)) || (!strcmp(wan_proto, "l2tp") && nvram_matchi("wan_dualaccess", 1))) {
816                        struct in_addr ifaddr;
817                        osl_ifaddr(wan_ifname_tun, &ifaddr);
818                        save2file("-A POSTROUTING -o %s -j SNAT --to-source %s\n", wan_ifname_tun, inet_ntoa(ifaddr));
819                }
820#endif
821/*
822                if (nvram_match("wan_proto", "pptp")) {
823                        struct in_addr ifaddr;
824                        osl_ifaddr(nvram_safe_get("pptp_ifname"), &ifaddr);
825                        save2file("-A POSTROUTING -o %s -j SNAT --to-source %s\n", nvram_safe_get("pptp_ifname"), inet_ntoa(ifaddr));
826                }
827                if (nvram_match("wan_proto", "l2tp")) {
828                        struct in_addr ifaddr;
829                        osl_ifaddr(wan_ifname_tun, &ifaddr);
830                        save2file("-A POSTROUTING -o %s -j SNAT --to-source %s\n", wan_ifname_tun, inet_ntoa(ifaddr));
831                }
832                if (nvram_match("wan_proto", "pppoe_dual")) {
833                        struct in_addr ifaddr;
834                        osl_ifaddr(wan_ifname_tun, &ifaddr);
835                        save2file("-A POSTROUTING -o %s -j SNAT --to-source %s\n", wan_ifname_tun, inet_ntoa(ifaddr));
836                }
837*/
838                if (nvram_matchi("block_loopback", 0) || nvram_match("filter", "off")) {
839                        save2file("-A POSTROUTING -m mark --mark %s -j MASQUERADE\n", get_NFServiceMark("FORWARD", 1));
840                }
841
842                char *next;
843                char dev[16];
844                char var[80];
845
846                char vifs[256];
847
848                getIfLists(vifs, 256);
849                // char *vifs = nvram_safe_get ("lan_ifnames");
850                // if (vifs != NULL)
851                foreach(var, vifs, next) {
852                        if (strcmp(get_wan_face(), var)
853                            && strcmp(nvram_safe_get("lan_ifname"), var)) {
854                                if (isstandalone(var)) {
855
856                                        char nat[32];
857                                        sprintf(nat, "%s_nat", var);
858                                        nvram_default_get(nat, "1");
859                                        if (nvram_matchi(nat, 1)) {
860                                                save2file("-A POSTROUTING -s %s/%d -o %s -j SNAT --to-source %s\n", nvram_nget("%s_ipaddr", var), getmask(nvram_nget("%s_netmask", var)), wanface, wanaddr);
861                                        }
862
863                                }
864                        }
865                }
866                if (nvram_matchi("block_loopback", 0) || nvram_match("filter", "off"))
867                        writeprocsysnet("ipv4/conf/br0/loop", "1");
868
869                if (!nvram_match("wan_proto", "pptp") && !nvram_match("wan_proto", "l2tp") && nvram_matchi("wshaper_enable", 0)) {
870                        //eval("iptables", "-t", "raw", "-A", "PREROUTING", "-p", "tcp", "-j", "CT", "--helper", "ddtb");       //this speeds up networking alot on slow systems
871                        //eval("iptables", "-t", "raw", "-A", "PREROUTING", "-p", "udp", "-j", "CT", "--helper", "ddtb");       //this speeds up networking alot on slow systems
872                }
873        } else {
874                if (!nvram_match("wan_proto", "pptp") && !nvram_match("wan_proto", "l2tp") && nvram_matchi("wshaper_enable", 0)) {
875                        //eval("iptables", "-t", "raw", "-A", "PREROUTING", "-p", "tcp", "-j", "CT", "--helper", "ddtb");       //this speeds up networking alot on slow systems
876                        //eval("iptables", "-t", "raw", "-A", "PREROUTING", "-p", "udp", "-j", "CT", "--helper", "ddtb");       //this speeds up networking alot on slow systems
877                }
878                eval("iptables", "-t", "raw", "-A", "PREROUTING", "-j", "NOTRACK");     //this speeds up networking alot on slow systems
879                /* the following code must be used in future kernel versions, not yet used. we still need to test it */
880//              eval("iptables", "-t", "raw", "-A", "PREROUTING", "-j", "CT","--notrack");      //this speeds up networking alot on slow systems
881                if (strlen(wanface) > 0 && wanactive())
882                        if (nvram_matchi("wl_br1_enable", 1))
883                                save2file("-A POSTROUTING -o %s -j SNAT --to-source %s\n", wanface, wanaddr);
884        }
885}
886
887static void parse_port_filter(char *wordlist)
888{
889        char var[256], *next;
890        char *protocol, *lan_port0, *lan_port1;
891
892        /*
893         * Parse protocol:lan_port0-lan_port1 ...
894         */
895        foreach(var, wordlist, next) {
896                lan_port0 = var;
897                protocol = strsep(&lan_port0, ":");
898                if (!protocol || !lan_port0)
899                        continue;
900                lan_port1 = lan_port0;
901                lan_port0 = strsep(&lan_port1, "-");
902                if (!lan_port0 || !lan_port1)
903                        continue;
904
905                if (!strcmp(protocol, "disable"))
906                        continue;
907
908                /*
909                 * -A FORWARD -i br0 -p tcp --dport 0:655 -j logdrop -A
910                 * FORWARD -i br0 -p udp --dport 0:655 -j logdrop
911                 */
912                if (!strcmp(protocol, "tcp") || !strcmp(protocol, "both")) {
913                        save2file("-A FORWARD -i %s -p tcp --dport %s:%s -j %s\n", lanface, lan_port0, lan_port1, log_drop);
914                }
915                if (!strcmp(protocol, "udp") || !strcmp(protocol, "both")) {
916                        save2file("-A FORWARD -i %s -p udp --dport %s:%s -j %s\n", lanface, lan_port0, lan_port1, log_drop);
917                }
918        }
919}
920
921/*
922 * Return 1 for match, 0 for accept, -1 for partial.
923 */
924static int find_pattern(const char *data, size_t dlen, const char *pattern, size_t plen, char term, unsigned int *numoff, unsigned int *numlen)
925{
926        size_t i, j, k;
927
928        // DEBUGP("find_pattern `%s': dlen = %u\n", pattern, dlen);
929        if (dlen == 0)
930                return 0;
931
932        if (dlen <= plen) {
933                /*
934                 * Short packet: try for partial?
935                 */
936                if (strncmp(data, pattern, dlen) == 0)
937                        return -1;
938                else
939                        return 0;
940        }
941
942        for (i = 0; i <= (dlen - plen); i++) {
943                if (memcmp(data + i, pattern, plen) != 0)
944                        continue;
945
946                /*
947                 * patten match !!
948                 */
949                *numoff = i + plen;
950                for (j = *numoff, k = 0; data[j] != term; j++, k++)
951                        if (j > dlen)
952                                return -1;      /* no terminal char */
953
954                *numlen = k;
955                return 1;
956        }
957
958        return 0;
959}
960
961static int match_wday(char *wday)
962{
963        int wd[7] = { 0, 0, 0, 0, 0, 0, 0 };
964        char sep[] = ",";
965        char *token;
966        int st, end;
967        int i;
968
969        token = strtok(wday, sep);
970        while (token != NULL) {
971                if (sscanf(token, "%d-%d", &st, &end) == 2)
972                        for (i = st; i <= end; i++)
973                                wd[i] = 1;
974                else
975                        wd[atoi(token)] = 1;
976
977                token = strtok(NULL, sep);
978        }
979
980        DEBUG("week map=%d%d%d%d%d%d%d\n", wd[0], wd[1], wd[2], wd[3], wd[4], wd[5], wd[6]);
981        DEBUG("now_wday=%d, match_wday()=%d\n", now_wday, wd[now_wday]);
982        return wd[now_wday];
983}
984
985static int match_hrmin(int hr_st, int mi_st, int hr_end, int mi_end)
986{
987        unsigned int hm_st, hm_end;
988
989        /*
990         * convert into %d%2d format
991         */
992        hm_st = hr_st * 100 + mi_st;
993        hm_end = hr_end * 100 + mi_end;
994
995        if (hm_st < hm_end) {
996                if (now_hrmin < hm_st || now_hrmin > hm_end)
997                        return 0;
998        } else {                // time rotate
999                if (now_hrmin < hm_st && now_hrmin > hm_end)
1000                        return 0;
1001        }
1002
1003        return 1;
1004}
1005
1006/*
1007 * PARAM - seq : Seqence number.
1008 *
1009 * RETURN - 0 : Data error or be disabled until in scheduled time.
1010 *                      1 : Enabled.
1011 */
1012static int schedule_by_tod(int seq)
1013{
1014        char *todvalue;
1015        int sched = 0, allday = 0;
1016        int hr_st, hr_end;      /* hour */
1017        int mi_st, mi_end;      /* minute */
1018        char wday[128];
1019        int intime = 0;
1020
1021        /*
1022         * Get the NVRAM data
1023         */
1024        todvalue = nvram_nget("filter_tod%d", seq);
1025
1026        if (strcmp(todvalue, "") == 0)
1027                return 0;
1028
1029        /*
1030         * Is it anytime or scheduled ?
1031         */
1032        if (strcmp(todvalue, "0:0 23:59 0-0") == 0 || strcmp(todvalue, "0:0 23:59 0-6") == 0) {
1033                sched = 0;
1034        } else {
1035                sched = 1;
1036                if (strcmp(todvalue, "0:0 23:59") == 0)
1037                        allday = 1;
1038                if (sscanf(todvalue, "%d:%d %d:%d %s", &hr_st, &mi_st, &hr_end, &mi_end, wday) != 5)
1039                        return 0;       /* error format */
1040        }
1041
1042        DEBUG("sched=%d, allday=%d\n", sched, allday);
1043        /*
1044         * Anytime
1045         */
1046        if (!sched) {
1047                save2file("-A lan2wan -j grp_%d\n", seq);
1048                return 1;
1049        }
1050
1051        /*
1052         * Scheduled
1053         */
1054        if (allday) {           /* 24-hour, but not everyday */
1055                char wday_st[64], wday_end[64]; /* for crontab */
1056                int rotate = 0; /* wday continugoue */
1057                char sep[] = ",";       /* wday seperate character */
1058                char *token;
1059                int st, end;
1060
1061                /*
1062                 * If its format looks like as "0-1,3,5-6"
1063                 */
1064                if (*wday == '0')
1065                        if (*(wday + strlen(wday) - 1) == '6')
1066                                rotate = 1;
1067
1068                /*
1069                 * Parse the 'wday' format for crontab
1070                 */
1071                token = strtok(wday, sep);
1072                while (token != NULL) {
1073                        /*
1074                         * which type of 'wday' ?
1075                         */
1076                        if (sscanf(token, "%d-%d", &st, &end) != 2)
1077                                st = end = atoi(token);
1078
1079                        if (rotate == 1 && st == 0)
1080                                sprintf(wday_end + strlen(wday_end), ",%d", end);
1081                        else if (rotate == 1 && end == 6)
1082                                sprintf(wday_st + strlen(wday_st), ",%d", st);
1083                        else {
1084                                sprintf(wday_st + strlen(wday_st), ",%d", st);
1085                                sprintf(wday_end + strlen(wday_end), ",%d", end);
1086                        }
1087
1088                        token = strtok(NULL, sep);
1089                }
1090
1091                /*
1092                 * Write to crontab for triggering the event
1093                 */
1094                /*
1095                 * "wday_xx + 1" can ignor the first character ','
1096                 */
1097                fprintf(cfd, "%02d %2d * * %s root /sbin/filter add %d\n", mi_st, hr_st, wday_st + 1, seq);
1098                fprintf(cfd, "%02d %2d * * %s root /sbin/filter del %d\n", mi_end, hr_end, wday_end + 1, seq);
1099                if (match_wday(wday))
1100                        intime = 1;
1101        } else {                /* Nither 24-hour, nor everyday */
1102                /*
1103                 * Write to crontab for triggering the event
1104                 */
1105                fprintf(cfd, "%02d %2d * * %s root /sbin/filter add %d\n", mi_st, hr_st, wday, seq);
1106                fprintf(cfd, "%02d %2d * * %s root /sbin/filter del %d\n", mi_end, hr_end, wday, seq);
1107                if (match_wday(wday)
1108                    && match_hrmin(hr_st, mi_st, hr_end, mi_end))
1109                        intime = 1;
1110        }
1111
1112        /*
1113         * Would it be enabled now ?
1114         */
1115        DEBUG("intime=%d\n", intime);
1116        if (intime) {
1117                save2file("-A lan2wan -j grp_%d\n", seq);
1118                return 1;
1119        }
1120
1121        return 0;
1122}
1123
1124static void macgrp_chain(int seq, unsigned int mark, int urlenable)
1125{
1126        char var[256], *next;
1127        char *wordlist;
1128
1129        wordlist = nvram_nget("filter_mac_grp%d", seq);
1130        if (strcmp(wordlist, "") == 0)
1131                return;
1132
1133        insmod("ipt_mac xt_mac");
1134
1135        if (mark == MARK_DROP) {
1136                foreach(var, wordlist, next) {
1137                        save2file("-A grp_%d -m mac --mac-source %s -j %s\n", seq, var, log_drop);
1138                        save2file("-A grp_%d -m mac --mac-destination %s -j %s\n", seq, var, log_drop);
1139                }
1140        } else {
1141                foreach(var, wordlist, next) {
1142                        save2file("-A grp_%d -m mac --mac-source %s -j advgrp_%d\n", seq, var, seq);
1143                        save2file("-A grp_%d -m mac --mac-destination %s -j advgrp_%d\n", seq, var, seq);
1144
1145                        /*
1146                         * mark = urlenable ? mark : webfilter ? MARK_HTTP : 0; if (mark)
1147                         * { save2file("-A macgrp_%d -p tcp --dport %d -m mac "
1148                         * "--mac-source %s -j MARK --set-mark %d\n" , seq, HTTP_PORT,
1149                         * var, mark); }
1150                         */
1151                }
1152        }
1153}
1154
1155static void ipgrp_chain(int seq, unsigned int mark, int urlenable)
1156{
1157        char buf[256];
1158        char var1[256], *wordlist1, *next1;
1159        char var2[256], *wordlist2, *next2;
1160        char from[100], to[100];
1161        char tmp[1024];
1162        int a1 = 0, a2 = 0;
1163        char s1[32], s2[32];
1164
1165        wordlist1 = nvram_nget("filter_ip_grp%d", seq);
1166        if (strcmp(wordlist1, "") == 0)
1167                return;
1168
1169        foreach(var1, wordlist1, next1) {
1170                if (contains(var1, '-')) {
1171                        char *end = var1;
1172                        char *start = strsep(&end, "-");
1173                        if (!contains(start, '.') || !contains(end, '.')) {
1174                                if (atoi(start) == 0 && atoi(end) == 0)
1175                                        continue;
1176                                //convert old style
1177                                char newstart[32];
1178                                sprintf(newstart, "%s%s", lan_cclass, start);
1179                                start = newstart;
1180                                char newend[32];
1181                                sprintf(newend, "%s%s", lan_cclass, end);
1182                                end = newend;
1183                        }
1184                        if (!strcmp(start, "0.0.0.0")
1185                            && !strcmp(end, "0.0.0.0"))
1186                                continue;
1187                        // if(a1 == 0) /* from 1 */
1188                        // a1 = 1;
1189
1190                        snprintf(from, sizeof(from), "%s", start);
1191                        snprintf(to, sizeof(to), "%s", end);
1192                        /*
1193                         * The return value of range() is global string array
1194                         */
1195                        wordlist2 = range(from, to, tmp);
1196                } else if (sscanf(var1, "%d", &a1) == 1) {
1197                        if (a1 == 0)    /* unset */
1198                                continue;
1199
1200                        snprintf(buf, sizeof(buf), "%s%d", lan_cclass, a1);
1201                        wordlist2 = buf;
1202                } else
1203                        continue;
1204
1205                DEBUG("range=%s\n", wordlist2);
1206
1207                if (mark == MARK_DROP) {
1208                        foreach(var2, wordlist2, next2) {
1209                                save2file("-A grp_%d -s %s -j %s\n", seq, var2, log_drop);
1210                        }
1211                } else {
1212                        foreach(var2, wordlist2, next2) {
1213                                save2file("-A grp_%d -s %s -j advgrp_%d\n", seq, var2, seq);
1214                                save2file("-A grp_%d -d %s -j advgrp_%d\n", seq, var2, seq);
1215
1216                                /*
1217                                 * mark = urlenable ? mark : webfilter ? MARK_HTTP : 0; if
1218                                 * (mark){ save2file("-A ipgrp_%d -p tcp --dport %d -s
1219                                 * %s " "-j MARK --set-mark %d\n", seq, HTTP_PORT, var2,
1220                                 * mark); }
1221                                 */
1222                        }
1223                }
1224        }
1225}
1226
1227static void portgrp_chain(int seq, unsigned int mark, int urlenable)
1228{
1229        char var[256], *next;
1230        char *wordlist;
1231        char target[100];
1232        char *protocol, *lan_port0, *lan_port1;
1233
1234        wordlist = nvram_nget("filter_dport_grp%d", seq);
1235        if (strcmp(wordlist, "") == 0)
1236                return;
1237
1238        /*
1239         * Determine the filter target
1240         */
1241        if (mark == MARK_DROP)
1242                strncpy(target, log_drop, sizeof(log_drop));
1243        else
1244                sprintf(target, "advgrp_%d", seq);
1245
1246        /*
1247         * Parse protocol:lan_port0-lan_port1 ...
1248         */
1249        foreach(var, wordlist, next) {
1250                lan_port0 = var;
1251                protocol = strsep(&lan_port0, ":");
1252                if (!protocol || !lan_port0)
1253                        continue;
1254                lan_port1 = lan_port0;
1255                lan_port0 = strsep(&lan_port1, "-");
1256                if (!lan_port0 || !lan_port1)
1257                        continue;
1258
1259                if (!strcmp(protocol, "disable"))
1260                        continue;
1261
1262                /*
1263                 * -A grp_* -p tcp --dport 0:655 -j logdrop -A grp_* -p udp -m
1264                 * udp --dport 0:655 -j logdrop
1265                 */
1266                if (!strcmp(protocol, "tcp") || !strcmp(protocol, "both")) {
1267                        save2file("-A grp_%d -p tcp --dport %s:%s -j %s\n", seq, lan_port0, lan_port1, target);
1268                }
1269                if (!strcmp(protocol, "udp") || !strcmp(protocol, "both")) {
1270                        save2file("-A grp_%d -p udp --dport %s:%s -j %s\n", seq, lan_port0, lan_port1, target);
1271                }
1272        }
1273}
1274
1275char *fw_get_filter_services(void)
1276{
1277
1278        l7filters *filters = filters_list;
1279        char temp[128] = "";
1280        char *proto[] = { "l7", "p2p", "dpi" };
1281        char *services = NULL;
1282
1283        while (filters->name)   // add l7 and p2p filters
1284        {
1285                sprintf(temp, "$NAME:%03d:%s$PROT:%03d:%s$PORT:003:0:0<&nbsp;>", strlen(filters->name), filters->name, filters->protocol == 0 ? 2 : 3, proto[filters->protocol]);
1286                if (!services) {
1287                        services = malloc(strlen(temp) + 1);
1288                        services[0] = 0;
1289                } else
1290                        services = realloc(services, strlen(services) + strlen(temp) + 1);
1291                strcat(services, temp);
1292                filters++;
1293        }
1294        services = realloc(services, strlen(services) + strlen(nvram_safe_get("filter_services")) + 1);
1295        strcat(services, nvram_safe_get("filter_services"));    // this is
1296        // user
1297        // defined
1298        // filters
1299        services = realloc(services, strlen(services) + strlen(nvram_safe_get("filter_services_1")) + 1);
1300        strcat(services, nvram_safe_get("filter_services_1"));
1301
1302        return services;
1303}
1304
1305/*
1306 * char * fw_get_filter_services (void) { static char services[8192] = "",
1307 * svcs_var[31] = "filter_services0"; int index = 0;
1308 *
1309 * while (strlen (nvram_safe_get (svcs_var)) > 0 && index < 8) { snprintf
1310 * (svcs_var, 31, "filter_services%d", index); strcat (services,
1311 * nvram_safe_get (svcs_var)); index++;
1312 *
1313 *
1314 * }
1315 *
1316 * return services; }
1317 */
1318static void advgrp_chain(int seq, unsigned int mark, int urlenable)
1319{
1320        char *wordlist, word[1024], *next;
1321        char *services, srv[1024], *next2;
1322        char delim[] = "<&nbsp;>";
1323
1324        cprintf("add advgrp_chain\n");
1325
1326        /*
1327         * filter_services=$NAME:006:My
1328         * ICQ$PROT:002:17$PORT:009:5000:5010<&nbsp;>..
1329         */
1330        // services = fw_get_filter_services ();
1331        // //nvram_safe_get("filter_services");
1332
1333        services = fw_get_filter_services();
1334
1335        /*
1336         * filter_port_grp5=My ICQ<&nbsp;>Game boy
1337         */
1338        wordlist = nvram_nget("filter_port_grp%d", seq);
1339        split(word, wordlist, next, delim) {
1340
1341                split(srv, services, next2, delim) {
1342                        int len = 0;
1343                        char *name, *prot, *port;
1344                        char protocol[100], ports[100], realname[100];
1345
1346                        if ((name = strstr(srv, "$NAME:")) == NULL || (prot = strstr(srv, "$PROT:")) == NULL || (port = strstr(srv, "$PORT:")) == NULL)
1347                                continue;
1348
1349                        /*
1350                         * $NAME
1351                         */
1352                        if (sscanf(name, "$NAME:%3d:", &len) != 1 || strlen(word) != len)
1353                                continue;
1354                        if (memcmp(name + sizeof("$NAME:nnn:") - 1, word, len)
1355                            != 0)
1356                                continue;
1357
1358                        strncpy(realname, name + sizeof("$NAME:nnn:") - 1, len);
1359                        realname[len] = '\0';
1360
1361                        /*
1362                         * $PROT
1363                         */
1364                        if (sscanf(prot, "$PROT:%3d:", &len) != 1)
1365                                continue;
1366                        strncpy(protocol, prot + sizeof("$PROT:nnn:") - 1, len);
1367                        protocol[len] = '\0';
1368
1369                        /*
1370                         * $PORT
1371                         */
1372                        if (sscanf(port, "$PORT:%3d:", &len) != 1)
1373                                continue;
1374                        strncpy(ports, port + sizeof("$PORT:nnn:") - 1, len);
1375                        ports[len] = '\0';
1376
1377                        cprintf("match:: name=%s, protocol=%s, ports=%s\n", word, protocol, ports);
1378                        if (!strcmp(protocol, "tcp")
1379                            || !strcmp(protocol, "both"))
1380                                save2file("-A advgrp_%d -p tcp --dport %s -j %s\n", seq, ports, log_drop);
1381                        if (!strcmp(protocol, "udp")
1382                            || !strcmp(protocol, "both"))
1383                                save2file("-A advgrp_%d -p udp --dport %s -j %s\n", seq, ports, log_drop);
1384                        if (!strcmp(protocol, "icmp"))
1385                                save2file("-A advgrp_%d -p icmp -j %s\n", seq, log_drop);
1386                        if (!strcmp(protocol, "l7")) {
1387                                int i;
1388
1389                                for (i = 0; i < strlen(realname); i++)
1390                                        realname[i] = tolower(realname[i]);
1391                                insmod("ipt_layer7 xt_layer7");
1392
1393                                save2file("-A advgrp_%d -m layer7 --l7proto %s -j %s\n", seq, realname, log_drop);
1394                        }
1395#ifdef HAVE_OPENDPI
1396                        if (!strcmp(protocol, "dpi")) {
1397                                insmod("xt_opendpi");
1398                                save2file("-A advgrp_%d -m ndpi --%s -j %s\n", seq, realname, log_drop);
1399                        }
1400#endif
1401                        if (!strcmp(protocol, "p2p")) {
1402                                char *proto = NULL;
1403                                /*commonly used protocols, decending */
1404                                if (!strcasecmp(realname, "bittorrent"))
1405                                        proto = "bit";
1406                                if (!strcasecmp(realname, "edonkey"))
1407                                        proto = "edk";
1408                                if (!strcasecmp(realname, "gnutella"))
1409                                        proto = "gnu";
1410                                if (!strcasecmp(realname, "ares"))
1411                                        proto = "ares";
1412                                /*atm rarly used protocols */
1413                                if (!strcasecmp(realname, "applejuice"))
1414                                        proto = "apple";
1415                                if (!strcasecmp(realname, "bearshare"))
1416                                        proto = "gnu";
1417                                if (!strcasecmp(realname, "directconnect"))
1418                                        proto = "dc";
1419                                if (!strcasecmp(realname, "kazaa"))
1420                                        proto = "kazaa";
1421                                if (!strcasecmp(realname, "mute"))
1422                                        proto = "mute";
1423                                if (!strcasecmp(realname, "soulseek"))
1424                                        proto = "soul";
1425                                if (!strcasecmp(realname, "waste"))
1426                                        proto = "waste";
1427                                if (!strcasecmp(realname, "winmx"))
1428                                        proto = "winmx";
1429                                if (!strcasecmp(realname, "xdcc"))
1430                                        proto = "xdcc";
1431                                if (proto)      //avoid null pointer, if realname isnt matched
1432                                {
1433                                        insmod("ipt_ipp2p xt_ipp2p");
1434                                        save2file("-A advgrp_%d -m ipp2p --%s -j %s\n", seq, proto, log_drop);
1435                                        if (!strcmp(proto, "bit")) {
1436                                                /* bittorrent detection enhanced */
1437#ifdef HAVE_OPENDPI
1438                                                insmod("xt_opendpi");
1439                                                save2file("-A advgrp_%d -m ndpi --bittorrent -j %s\n", seq, log_drop);
1440#else
1441                                                insmod("ipt_layer7 xt_layer7");
1442#ifdef HAVE_MICRO
1443                                                save2file("-A advgrp_%d -m layer7 --l7proto bt -j %s\n", seq, log_drop);
1444#else
1445                                                save2file("-A advgrp_%d -m length --length 0:550 -m layer7 --l7proto bt -j %s\n", seq, log_drop);
1446#endif
1447                                                save2file("-A advgrp_%d -m layer7 --l7proto bt1 -j %s\n", seq, log_drop);
1448                                                save2file("-A advgrp_%d -m layer7 --l7proto bt2 -j %s\n", seq, log_drop);
1449#endif
1450                                        }
1451                                }
1452                        }
1453
1454                }
1455        }
1456        /*
1457         * p2p catchall
1458         */
1459        if (nvram_nmatch("1", "filter_p2p_grp%d", seq)) {
1460                insmod("ipt_layer7 xt_layer7 ipt_ipp2p xt_ipp2p");
1461                save2file("-A advgrp_%d -m ipp2p --edk -j %s\n", seq, log_drop);
1462                save2file("-A advgrp_%d -m ipp2p --dc -j %s\n", seq, log_drop);
1463                save2file("-A advgrp_%d -m ipp2p --gnu -j %s\n", seq, log_drop);
1464                save2file("-A advgrp_%d -m ipp2p --kazaa -j %s\n", seq, log_drop);
1465                save2file("-A advgrp_%d -m ipp2p --bit -j %s\n", seq, log_drop);
1466                save2file("-A advgrp_%d -m ipp2p --apple -j %s\n", seq, log_drop);
1467                save2file("-A advgrp_%d -m ipp2p --soul -j %s\n", seq, log_drop);
1468                save2file("-A advgrp_%d -m ipp2p --winmx -j %s\n", seq, log_drop);
1469                save2file("-A advgrp_%d -m ipp2p --ares -j %s\n", seq, log_drop);
1470                save2file("-A advgrp_%d -m ipp2p --mute -j %s\n", seq, log_drop);
1471                save2file("-A advgrp_%d -m ipp2p --waste -j %s\n", seq, log_drop);
1472                save2file("-A advgrp_%d -m ipp2p --xdcc -j %s\n", seq, log_drop);
1473
1474                /* p2p detection enhanced */
1475#ifdef HAVE_OPENDPI
1476                insmod("xt_opendpi");
1477                /*commonly used protocols, decending */
1478                save2file("-A advgrp_%d -m ndpi --bittorrent -j %s\n", seq, log_drop);
1479/*  disable till pattern works
1480                save2file
1481                    ("-A advgrp_%d -m ndpi --edonkey -j %s\n",
1482                     seq, log_drop); */
1483                /*atm rarly used protocols */
1484                save2file("-A advgrp_%d -m ndpi --apple -j %s\n", seq, log_drop);
1485                save2file("-A advgrp_%d -p tcp -m ndpi --directconnect -j %s\n", seq, log_drop);
1486                save2file("-A advgrp_%d -m ndpi --fasttrack -j %s\n", seq, log_drop);
1487                save2file("-A advgrp_%d -m ndpi --filetopia -j %s\n", seq, log_drop);
1488                save2file("-A advgrp_%d -p tcp -m ndpi --gnutella -j %s\n", seq, log_drop);
1489                save2file("-A advgrp_%d -m ndpi --imesh -j %s\n", seq, log_drop);
1490                save2file("-A advgrp_%d -p tcp -m ndpi --openft -j %s\n", seq, log_drop);
1491                save2file("-A advgrp_%d -p tcp -m ndpi --pando -j %s\n", seq, log_drop);
1492                save2file("-A advgrp_%d -p tcp -m ndpi --soulseek -j %s\n", seq, log_drop);
1493                save2file("-A advgrp_%d -p tcp -m ndpi --winmx -j %s\n", seq, log_drop);
1494#else
1495#ifdef HAVE_MICRO
1496                save2file("-A advgrp_%d -m layer7 --l7proto bt -j %s\n", seq, log_drop);
1497#else
1498                save2file("-A advgrp_%d -m length --length 0:550 -m layer7 --l7proto bt -j %s\n", seq, log_drop);
1499#endif
1500#endif
1501                /* commonly used protocols, decending */
1502/*              save2file("-A advgrp_%d -m layer7 --l7proto bt -j %s\n", seq, log_drop); */
1503                save2file("-A advgrp_%d  -p tcp -m layer7 --l7proto ares -j %s\n", seq, log_drop);
1504#ifndef HAVE_OPENDPI
1505                save2file("-A advgrp_%d -m layer7 --l7proto bt4 -j %s\n", seq, log_drop);
1506                save2file("-A advgrp_%d -m layer7 --l7proto bt1 -j %s\n", seq, log_drop);
1507                save2file("-A advgrp_%d -m layer7 --l7proto bittorrent -j %s\n", seq, log_drop);
1508                save2file("-A advgrp_%d -m layer7 --l7proto bt2 -j %s\n", seq, log_drop);
1509                save2file("-A advgrp_%d -p tcp -m layer7 --l7proto gnutella -j %s\n", seq, log_drop);
1510                save2file("-A advgrp_%d -m layer7 --l7proto applejuice -j %s\n", seq, log_drop);
1511                save2file("-A advgrp_%d -p tcp -m layer7 --l7proto directconnect -j %s\n", seq, log_drop);
1512                save2file("-A advgrp_%d -p tcp -m layer7 --l7proto soulseek -j %s\n", seq, log_drop);
1513                save2file("-A advgrp_%d -p tcp -m layer7 --l7proto openft -j %s\n", seq, log_drop);
1514                save2file("-A advgrp_%d -m layer7 --l7proto fasttrack -j %s\n", seq, log_drop);
1515                save2file("-A advgrp_%d -m layer7 --l7proto imesh -j %s\n", seq, log_drop);
1516#endif
1517                save2file("-A advgrp_%d -m layer7 --l7proto audiogalaxy -j %s\n", seq, log_drop);
1518                save2file("-A advgrp_%d -p tcp -m layer7 --l7proto bearshare -j %s\n", seq, log_drop);
1519                /* atm rarly used protocols */
1520                save2file("-A advgrp_%d -m layer7 --l7proto edonkey -j %s\n", seq, log_drop);
1521                save2file("-A advgrp_%d -m layer7 --l7proto freenet -j %s\n", seq, log_drop);
1522                save2file("-A advgrp_%d -m layer7 --l7proto gnucleuslan -j %s\n", seq, log_drop);
1523                save2file("-A advgrp_%d -m layer7 --l7proto goboogy -j %s\n", seq, log_drop);
1524                save2file("-A advgrp_%d -m layer7 --l7proto hotline -j %s\n", seq, log_drop);
1525/*              save2file("-A advgrp_%d -m layer7 --l7proto kugoo -j %s\n", seq, log_drop);// xunlei, kugoo, winmx block websurfing */
1526                save2file("-A advgrp_%d -p tcp -m layer7 --l7proto mute -j %s\n", seq, log_drop);
1527                save2file("-A advgrp_%d -p tcp -m layer7 --l7proto napster -j %s\n", seq, log_drop);
1528                save2file("-A advgrp_%d -p tcp -m layer7 --l7proto soribada -j %s\n", seq, log_drop);
1529                save2file("-A advgrp_%d -m layer7 --l7proto tesla -j %s\n", seq, log_drop);
1530/*              save2file("-A advgrp_%d -p tcp -m layer7 --l7proto winmx -j %s\n", seq, log_drop);
1531                save2file("-A advgrp_%d -m layer7 --l7proto xunlei -j %s\n", seq, log_drop); */
1532        }
1533        free(services);
1534        /*
1535         * filter_web_host2=hello<&nbsp;>world<&nbsp;>friend
1536         */
1537        wordlist = nvram_nget("filter_web_host%d", seq);
1538        if (wordlist && strcmp(wordlist, "")) {
1539                insmod("ipt_webstr");
1540                save2file("-A advgrp_%d -p tcp -m webstr --host \"%s\" -j %s\n", seq, wordlist, log_reject);
1541#if !defined(ARCH_broadcom) && !defined(HAVE_RTG32) || defined(HAVE_BCMMODERN)
1542                char var[256];
1543                char *next;
1544                char *pos = wordlist;
1545                int len = strlen(wordlist);
1546                while ((wordlist - pos) < len && (next = strstr(wordlist, "<&nbsp;>"))) {
1547                        bzero(var, 256);
1548                        strncpy(var, wordlist, (next - wordlist));
1549                        int offset = 0;
1550                        if (strstr(var, "https://"))
1551                                offset = 8;
1552                        save2file("-A advgrp_%d -p tcp -m string --string \"%s\" --algo bm --from 1 --to 600 -j %s\n", seq, &var[offset], log_reject);
1553                        wordlist = next + 8;
1554                }
1555
1556#endif
1557
1558        }
1559        /*
1560         * filter_web_url3=hello<&nbsp;>world<&nbsp;>friend
1561         */
1562        wordlist = nvram_nget("filter_web_url%d", seq);
1563        if (wordlist && strcmp(wordlist, "")) {
1564                insmod("ipt_webstr");
1565                save2file("-A advgrp_%d -p tcp -m webstr --url \"%s\" -j %s\n", seq, wordlist, log_reject);
1566#if !defined(ARCH_broadcom) || defined(HAVE_BCMMODERN) && !defined(HAVE_RTG32)
1567                char var[256];
1568                char *next;
1569                char *pos = wordlist;
1570                int len = strlen(wordlist);
1571                while ((wordlist - pos) < len && (next = strstr(wordlist, "<&nbsp;>"))) {
1572                        bzero(var, 256);
1573                        strncpy(var, wordlist, (next - wordlist));
1574                        int offset = 0;
1575                        if (strstr(var, "https://"))
1576                                offset = 8;
1577                        save2file("-A advgrp_%d -p tcp -m string --string \"%s\" --algo bm --from 1 --to 600 -j %s\n", seq, &var[offset], log_reject);
1578                        wordlist = next + 8;
1579                }
1580#endif
1581
1582        }
1583        /*
1584         * Others will be accepted
1585         */
1586        // save2file ("-A advgrp_%d -j %s\n", seq, log_accept);
1587}
1588
1589static void lan2wan_chains(void)
1590{
1591        time_t ct;              /* Calendar time */
1592        struct tm *bt;          /* Broken time */
1593        int seq;
1594        char buf[] = "filter_rulexxx";
1595        char *data;
1596        int offset, len;
1597        unsigned int mark = 0;
1598        int up = 0;
1599        int urlfilter = 1;
1600
1601        // char urlhost[] ="filter_url_hostxxx";
1602        // char urlkeywd[]="filter_url_keywdxxx";
1603
1604        /*
1605         * Get local calendar time
1606         */
1607        time(&ct);
1608        bt = localtime(&ct);
1609
1610        /*
1611         * Convert to 3-digital format
1612         */
1613        now_hrmin = bt->tm_hour * 100 + bt->tm_min;
1614        now_wday = bt->tm_wday;
1615
1616        /*
1617         * keep the status using bitmap
1618         */
1619        if ((ifd = fopen(IPTABLES_RULE_STAT, "w")) == NULL) {
1620                cprintf("Can't open %s\n", IPTABLES_RULE_STAT);
1621                exit(1);
1622        }
1623
1624        /*
1625         * Open the crontab file for modification
1626         */
1627        if ((cfd = fopen(CRONTAB, "w")) == NULL) {
1628                cprintf("Can't open %s\n", CRONTAB);
1629                exit(1);
1630        }
1631        // fprintf (cfd, "PATH=/sbin:/bin:/usr/sbin:/usr/bin\n\n");
1632
1633#if defined(REVERSE_RULE_ORDER)
1634        for (seq = NR_RULES; seq >= 1; seq--) {
1635#else
1636        for (seq = 1; seq <= NR_RULES; seq++) {
1637#endif
1638                data = nvram_nget("filter_rule%d", seq);
1639
1640                if (strcmp(data, "") == 0)
1641                        up = 0;
1642                else
1643                        up = schedule_by_tod(seq);
1644
1645                fprintf(ifd, "%d,", up);
1646        }
1647
1648        fclose(cfd);
1649        fclose(ifd);
1650
1651        for (seq = 1; seq <= NR_RULES; seq++) {
1652                data = nvram_nget("filter_rule%d", seq);
1653                if (data && strcmp(data, "") == 0)
1654                        continue;
1655
1656                /*
1657                 * Check if it is enabled
1658                 */
1659                find_pattern(data, strlen(data), "$STAT:", sizeof("$STAT:") - 1, '$', &offset, &len);
1660
1661                if (len < 1)
1662                        continue;       /* error format */
1663
1664                strncpy(buf, data + offset, len);
1665                *(buf + len) = 0;
1666                DEBUG("STAT: %s\n", buf);
1667
1668                switch (atoi(buf)) {
1669                case 1: /* Drop it */
1670                        mark = MARK_DROP;
1671                        break;
1672                case 2: /* URL checking */
1673                        mark = MARK_OFFSET + seq;
1674                        break;
1675                default:        /* jump to next iteration */
1676                        continue;
1677                }
1678
1679                /*
1680                 * sprintf(urlhost, "filter_url_host%d", seq); sprintf(urlkeywd,
1681                 * "filter_url_keywd%d", seq); if (nvram_match(urlhost, "") &&
1682                 * nvram_match(urlkeywd, "")) urlfilter = 0;
1683                 *
1684                 * DEBUG("host=%s, keywd=%s\n", urlhost, urlkeywd);
1685                 */
1686                macgrp_chain(seq, mark, urlfilter);
1687                ipgrp_chain(seq, mark, urlfilter);
1688                portgrp_chain(seq, mark, urlfilter);
1689                advgrp_chain(seq, mark, urlfilter);
1690        }
1691}
1692
1693/*
1694 *
1695 * mode 0 : delete
1696 *              1 : insert
1697 */
1698static int update_filter(int mode, int seq)
1699{
1700        char target_ip[20];
1701        char order[10];
1702        int ord;
1703
1704        if ((ord = update_bitmap(mode, seq)) < 0)
1705                return -1;
1706
1707        sprintf(target_ip, "grp_%d", seq);
1708        sprintf(order, "%d", ord * 1 + 1);
1709        DEBUG("order=%s\n", order);
1710
1711        /*
1712         * iptables -t mangle -I lan2wan 3 -j macgrp_9
1713         */
1714        if (mode == 1) {        /* insert */
1715                DEBUG("iptables -I lan2wan %s -j %s\n", order, target_ip);
1716                eval("iptables", "-I", "lan2wan", order, "-j", target_ip);
1717        } else {                /* delete */
1718                DEBUG("iptables -D lan2wan %s\n", order);
1719                eval("iptables", "-D", "lan2wan", order);
1720        }
1721
1722        cprintf("done\n");
1723        return 0;
1724}
1725
1726void start_filter_add(int seq)
1727{
1728        DEBUG("filter_add:\n");
1729        update_filter(1, seq);
1730
1731}
1732
1733void start_filter_del(int seq)
1734{
1735        DEBUG("filter_del:\n");
1736        update_filter(0, seq);
1737}
1738
1739void stop_filtersync(void)
1740{
1741}
1742
1743void start_filtersync(void)
1744{
1745        time_t ct;              /* Calendar time */
1746        struct tm *bt;          /* Broken time */
1747        int seq;
1748        int ret;
1749
1750        /*
1751         * Get local calendar time
1752         */
1753        time(&ct);
1754        bt = localtime(&ct);
1755        /*
1756         * Convert to 3-digital format
1757         */
1758        now_hrmin = bt->tm_hour * 100 + bt->tm_min;
1759        now_wday = bt->tm_wday;
1760
1761        for (seq = 1; seq <= NR_RULES; seq++) {
1762                if (if_tod_intime(seq) > 0)
1763                        start_filter_add(seq);
1764                else
1765                        start_filter_del(seq);
1766                DEBUG("seq=%d, ret=%d\n", seq, ret);
1767        }
1768}
1769
1770static void parse_trigger_out(char *wordlist)
1771{
1772        char var[256], *next;
1773        char *name, *enable, *proto;
1774        char *wport0, *wport1, *lport0, *lport1;
1775
1776        /*
1777         * port_trigger=name:[on|off]:[tcp|udp|both]:wport0-wport1>lport0-lport1
1778         */
1779        foreach(var, wordlist, next) {
1780                enable = var;
1781                name = strsep(&enable, ":");
1782                if (!name || !enable)
1783                        continue;
1784                proto = enable;
1785                enable = strsep(&proto, ":");
1786                if (!enable || !proto)
1787                        continue;
1788                wport0 = proto;
1789                proto = strsep(&wport0, ":");
1790                if (!proto || !wport0)
1791                        continue;
1792                wport1 = wport0;
1793                wport0 = strsep(&wport1, "-");
1794                if (!wport0 || !wport1)
1795                        continue;
1796                lport0 = wport1;
1797                wport1 = strsep(&lport0, ">");
1798                if (!wport1 || !lport0)
1799                        continue;
1800                lport1 = lport0;
1801                lport0 = strsep(&lport1, "-");
1802                if (!lport0 || !lport1)
1803                        continue;
1804
1805                /*
1806                 * skip if it's disabled
1807                 */
1808                if (strcmp(enable, "off") == 0)
1809                        continue;
1810
1811                if (!strcmp(proto, "tcp") || !strcmp(proto, "udp")) {
1812                        save2file("-A trigger_out -p %s -m %s --dport %s:%s "
1813                                  "-j TRIGGER --trigger-type out --trigger-proto %s --trigger-match %s-%s --trigger-relate %s-%s\n", proto, proto, wport0, wport1, proto, wport0, wport1, lport0, lport1);
1814                } else if (!strcmp(proto, "both")) {
1815                        save2file("-A trigger_out -p tcp --dport %s:%s "
1816                                  "-j TRIGGER --trigger-type out --trigger-proto all --trigger-match %s-%s --trigger-relate %s-%s\n", wport0, wport1, wport0, wport1, lport0, lport1);
1817                        save2file("-A trigger_out -p udp --dport %s:%s "
1818                                  "-j TRIGGER --trigger-type out --trigger-proto all --trigger-match %s-%s --trigger-relate %s-%s\n", wport0, wport1, wport0, wport1, lport0, lport1);
1819                }
1820        }
1821}
1822
1823#ifdef HAVE_VLANTAGGING
1824static void add_bridges(char *chain, int forward)
1825{
1826        char word[256];
1827        char *next, *wordlist;
1828        char *wan = get_wan_face();
1829        wordlist = nvram_safe_get("bridges");
1830        foreach(word, wordlist, next) {
1831                char *port = word;
1832                char *tag = strsep(&port, ">");
1833                char *prio = port;
1834
1835                strsep(&prio, ">");
1836                if (!tag || !port)
1837                        break;
1838                char ipaddr[32];
1839
1840                sprintf(ipaddr, "%s_ipaddr", tag);
1841                char netmask[32];
1842
1843                sprintf(netmask, "%s_netmask", tag);
1844                if (ifexists(tag)) {
1845                        if (nvram_get(ipaddr) && nvram_get(netmask)
1846                            && !nvram_match(ipaddr, "0.0.0.0")
1847                            && !nvram_match(netmask, "0.0.0.0")) {
1848                                eval("ifconfig", tag, nvram_safe_get(ipaddr), "netmask", nvram_safe_get(netmask), "up");
1849                        } else {
1850                                eval("ifconfig", tag, "up");
1851
1852                        }
1853                        if (forward && wan && strlen(wan))
1854                                save2file("-A FORWARD -i %s -o %s -j %s\n", tag, wan, log_accept);
1855                        else {
1856                                if (!strcmp(chain, "OUTPUT"))
1857                                        save2file("-A %s -o %s -j %s\n", chain, tag, log_accept);
1858                                else
1859                                        save2file("-A %s -i %s -j %s\n", chain, tag, log_accept);
1860                        }
1861                }
1862        }
1863
1864}
1865
1866#endif
1867static void filter_input(void)
1868{
1869
1870        char *next, *iflist, buff[16];
1871
1872        /*
1873         * Filter known SPI state
1874         */
1875        /*
1876         * most of what was here has been moved to the end
1877         */
1878        save2file("-A INPUT -m state --state RELATED,ESTABLISHED -j %s\n", log_accept);
1879        if (nvram_matchi("dtag_vlan8", 1) && nvram_matchi("wan_vdsl", 1)) {
1880                save2file("-A INPUT -i %s -j %s\n", nvram_safe_get("tvnicfrom"), log_accept);
1881        }
1882#ifdef HAVE_PPTP
1883        /*
1884         * Impede DoS/Bruteforce, redcuce possilbe bruteforce on pptp server
1885         */
1886#ifndef HAVE_MICRO
1887        if (nvram_matchi("pptpd_enable", 1)) {
1888                if (nvram_matchi("limit_pptp", 1)) {
1889                        save2file("-A INPUT -i %s -p tcp --dport %d -j logbrute\n", wanface, PPTP_PORT);
1890                        save2file("-A INPUT -i %s -p tcp --dport %d -j %s\n", wanface, PPTP_PORT, log_accept);
1891                } else {
1892                        save2file("-A INPUT -i %s -p tcp --dport %d -j %s\n", wanface, PPTP_PORT, log_accept);
1893                }
1894        }
1895#endif
1896        if (nvram_match("wan_proto", "dhcp"))
1897                save2file("-A INPUT -i %s -p udp --sport 67 --dport 68 -j %s\n", wanface, log_accept);
1898        if (nvram_matchi("pptpd_enable", 1)
1899            || nvram_matchi("pptpd_client_enable", 1)
1900            || nvram_match("wan_proto", "pptp")) {
1901                save2file("-A INPUT -p tcp --dport %d -j %s\n", PPTP_PORT, log_accept);
1902                save2file("-A INPUT -p 47 -j %s\n", log_accept);
1903                if (nvram_matchi("pptpd_lockdown", 1)) {
1904                        save2file("-A INPUT -i %s -p udp --sport 67 --dport 68 -j %s\n", lanface, log_accept);
1905                        save2file("-A INPUT -i %s -j %s\n", lanface, log_drop);
1906                }
1907        }
1908#endif
1909#ifdef HAVE_FTP
1910        if (nvram_matchi("proftpd_enable", 1)
1911            && nvram_matchi("proftpd_wan", 1)) {
1912                if (nvram_matchi("limit_ftp", 1)) {
1913                        save2file("-A INPUT -i %s -p tcp --dport %s -j logbrute\n", wanface, nvram_safe_get("proftpd_port"));
1914                        save2file("-A INPUT -i %s -p tcp --dport %s -j %s\n", wanface, nvram_safe_get("proftpd_port"), log_accept);
1915                } else {
1916                        save2file("-A INPUT -i %s -p tcp --dport %s -j %s\n", wanface, nvram_safe_get("proftpd_port"), log_accept);
1917                }
1918        }
1919#endif
1920#ifdef HAVE_WEBSERVER
1921        if (nvram_matchi("lighttpd_enable", 1) && nvram_matchi("lighttpd_wan", 1)) {
1922                save2file("-A INPUT -i %s -p tcp --dport %s -j %s\n", wanface, nvram_safe_get("lighttpd_port"), log_accept);
1923                save2file("-A INPUT -i %s -p tcp --dport %s -j %s\n", wanface, nvram_safe_get("lighttpd_sslport"), log_accept);
1924        }
1925#endif
1926/*#ifdef HAVE_AP_SERV
1927        save2file("-A INPUT -i %s -p udp --dport 22359 -j ACCEPT\n",lanface);
1928        save2file("-A INPUT -i %s -p udp --sport 22359 -j ACCEPT\n",lanface);
1929        save2file("-A OUTPUT -p udp --sport 22359 -j ACCEPT\n");
1930#endif*/
1931        /*
1932         * Routing protocol, RIP, accept
1933         */
1934        /*
1935         * lonewolf mods for multiple VLANs / interfaces
1936         */
1937#ifdef HAVE_OPENVPN
1938        //check if ovpn server is running
1939        if (nvram_matchi("openvpn_enable", 1)) {
1940                save2file("-A INPUT -p %s --dport %s -j %s\n", nvram_match("openvpn_proto", "udp") ? "udp" : "tcp", nvram_safe_get("openvpn_port"), log_accept);
1941                if (nvram_match("openvpn_tuntap", "tun")) {
1942//                      if (strlen(nvram_safe_get("openvpn_ccddef")) = 0) {
1943                        save2file("-A INPUT -i %s2 -j %s\n", nvram_safe_get("openvpn_tuntap"), log_accept);
1944                        save2file("-A FORWARD -i %s2 -j %s\n", nvram_safe_get("openvpn_tuntap"), log_accept);
1945                        save2file("-A FORWARD -o %s2 -j %s\n", nvram_safe_get("openvpn_tuntap"), log_accept);
1946//                      }
1947                }
1948        }
1949#endif
1950        if (wanactive()) {
1951                if (nvram_invmatchi("dr_wan_rx", 0))
1952                        save2file("-A INPUT -p udp -i %s --dport %d -j %s\n", wanface, RIP_PORT, log_accept);
1953                else
1954                        save2file("-A INPUT -p udp -i %s --dport %d -j %s\n", wanface, RIP_PORT, log_drop);
1955        }
1956        if (nvram_invmatchi("dr_lan_rx", 0))
1957                save2file("-A INPUT -p udp -i %s --dport %d -j %s\n", lanface, RIP_PORT, log_accept);
1958        else
1959                save2file("-A INPUT -p udp -i %s --dport %d -j %s\n", lanface, RIP_PORT, log_drop);
1960
1961        iflist = nvram_safe_get("no_route_if");
1962        foreach(buff, iflist, next) {
1963                save2file("-A INPUT -p udp -i %s --dport %d -j %s\n", buff, RIP_PORT, log_drop);
1964        }
1965
1966        save2file("-A INPUT -p udp --dport %d -j %s\n", RIP_PORT, log_accept);
1967
1968        /*
1969         * end lonewolf mods
1970         */
1971
1972        /*
1973         * Wolf mod - accept protocol 41 for IPv6 tunneling
1974         */
1975#ifdef HAVE_IPV6
1976        if (nvram_matchi("ipv6_enable", 1))
1977                save2file("-A INPUT -p 41 -j %s\n", log_accept);
1978#endif
1979        /*
1980         * Sveasoft mod - accept OSPF protocol broadcasts
1981         */
1982        if (nvram_match("wk_mode", "ospf"))
1983                save2file("-A INPUT -p ospf -j %s\n", log_accept);
1984        if (nvram_match("wk_mode", "bgp"))
1985                save2file("-A INPUT -p tcp --dport 179 -j %s\n", log_accept);
1986#ifdef HAVE_OLSRD
1987        if (nvram_match("wk_mode", "olsr"))
1988                save2file("-A INPUT -p udp --dport 698 -j %s\n", log_accept);
1989#endif
1990        /*
1991         * Sveasoft mod - default for br1/separate subnet WDS type
1992         */
1993        if (nvram_matchi("wl0_br1_enable", 1)
1994            && nvram_invmatchi("wl0_br1_nat", 1)
1995            && nvram_invmatchi("wl0_br1_nat", 2))
1996                save2file("-A INPUT -i br1 -j %s\n", log_accept);
1997        if (nvram_matchi("wl1_br1_enable", 1)
1998            && nvram_invmatchi("wl1_br1_nat", 1)
1999            && nvram_invmatchi("wl1_br1_nat", 2))
2000                save2file("-A INPUT -i br1 -j %s\n", log_accept);
2001#ifdef HAVE_VLANTAGGING
2002        add_bridges("INPUT", 0);
2003#endif
2004
2005        /*
2006         * Remote Web GUI Management Use interface name, destination address, and
2007         * port to make sure that it's redirected from WAN
2008         */
2009        if (remotemanage) {
2010                save2file("-A INPUT -p tcp -d %s --dport %d -j %s\n", nvram_safe_get("lan_ipaddr"), web_lanport, log_accept);
2011        }
2012#ifdef HAVE_SSHD
2013        /*
2014         * Impede DoS/Bruteforce, reduce load on ssh
2015         */
2016#ifndef HAVE_MICRO
2017        if (remotessh) {
2018
2019                if (nvram_matchi("limit_ssh", 1))
2020                        save2file("-A INPUT -i %s -p tcp -d %s --dport %s -j logbrute\n", wanface, nvram_safe_get("lan_ipaddr"), nvram_safe_get("sshd_port"));
2021        }
2022#endif
2023        /*
2024         * Remote Web GUI Management Botho 03-05-2006 : remote ssh & remote GUI
2025         * management are not linked anymore
2026         */
2027        if (remotessh) {
2028                save2file("-A INPUT -i %s -p tcp -d %s --dport %s -j %s\n", wanface, nvram_safe_get("lan_ipaddr"), nvram_safe_get("sshd_port"), log_accept);
2029        }
2030#endif
2031
2032#ifdef HAVE_TELNET
2033        /*
2034         * Impede DoS/Bruteforce, reduce load on Telnet
2035         */
2036#ifndef HAVE_MICRO
2037        if (remotetelnet) {
2038                if (nvram_matchi("limit_telnet", 1))
2039                        save2file("-A INPUT -i %s -p tcp -d %s --dport 23 -j logbrute\n", wanface, nvram_safe_get("lan_ipaddr"));
2040        }
2041#endif
2042        if (remotetelnet) {
2043                save2file("-A INPUT -i %s -p tcp -d %s --dport 23 -j %s\n", wanface, nvram_safe_get("lan_ipaddr"), log_accept);
2044        }
2045#endif
2046        /*
2047         * ICMP request from WAN interface
2048         */
2049        if (wanactive()) {
2050                if (nvram_invmatch("filter", "off"))
2051                        save2file("-A INPUT -i %s -p icmp -j %s\n", wanface, nvram_matchi("block_wan", 1) ? log_drop : log_accept);
2052                else
2053                        save2file("-A INPUT -i %s -p icmp -j %s\n", wanface, log_accept);
2054        }
2055        /*
2056         * IGMP query from WAN interface
2057         */
2058        save2file("-A INPUT -p igmp -j %s\n", doMultiCast() == 0 ? log_drop : log_accept);
2059
2060#ifdef HAVE_UDPXY
2061        if (wanactive() && nvram_matchi("udpxy_enable", 1) && nvram_get("tvnicfrom"))
2062                save2file("-A INPUT -i %s -p udp -d %s -j %s\n", nvram_safe_get("tvnicfrom"), IP_MULTICAST, log_accept);
2063#endif
2064
2065#ifndef HAVE_MICRO
2066        /*
2067         * SNMP access from WAN interface
2068         */
2069        if (nvram_matchi("snmpd_enable", 1) && (nvram_matchi("block_snmp", 0) || nvram_match("filter", "off"))) {
2070                save2file("-A INPUT -i %s -p udp --dport 161 -j %s\n", wanface, log_accept);
2071        }
2072#endif
2073
2074#ifdef HAVE_TFTP
2075        /*
2076         * Remote Upgrade
2077         */
2078        if (nvram_matchi("remote_upgrade", 1))
2079                save2file("-A INPUT -p udp --dport %d -j %s\n", TFTP_PORT, log_accept);
2080#endif
2081
2082#ifdef HAVE_MILKFISH
2083        if (strlen(wanface) && nvram_matchi("milkfish_enabled", 1))
2084                save2file("-A INPUT -p udp -i %s --dport 5060 -j %s\n", wanface, log_accept);
2085        // save2file ("-A INPUT -m udp -p udp -i %s --dport 35000 36000 -j
2086        // ACCEPT\n", wanface);
2087#endif
2088#ifdef HAVE_VNCREPEATER
2089        if (nvram_matchi("vncr_enable", 1) && strlen(wanface)) {
2090                save2file("-A INPUT -p tcp -i %s --dport 5900 -j %s\n", wanface, log_accept);
2091                save2file("-A INPUT -p tcp -i %s --dport 5500 -j %s\n", wanface, log_accept);
2092        }
2093#endif
2094#ifdef HAVE_TOR
2095        if (nvram_matchi("tor_enable", 1)) {
2096                if (nvram_matchi("tor_relay", 1))
2097                        save2file("-A INPUT -p tcp -i %s --dport 9001 -j %s\n", wanface, log_accept);
2098                if (nvram_matchi("tor_dir", 1))
2099                        save2file("-A INPUT -p tcp -i %s --dport 9030 -j %s\n", wanface, log_accept);
2100        }
2101#endif
2102        /*
2103         * Ident request backs by telnet or IRC server
2104         */
2105        if (nvram_matchi("block_ident", 0) || nvram_match("filter", "off"))
2106                save2file("-A INPUT -p tcp --dport %d -j %s\n", IDENT_PORT, log_accept);
2107
2108        /*
2109         * Filter known SPI state
2110         */
2111        // removed first rule: -A INPUT -m state --state INVALID -j DROP
2112        // (wolfiR)
2113        save2file("-A INPUT -i lo -m state --state NEW -j ACCEPT\n");
2114        save2file("-A INPUT -i %s -m state --state NEW -j %s\n", lanface, log_accept);
2115
2116        /*
2117         * lonewolf mods for extra VLANs / interfaces
2118         */
2119        iflist = nvram_safe_get("no_firewall_if");
2120        foreach(buff, iflist, next) {
2121                save2file("-A INPUT -i %s -m state --state NEW -j %s\n", buff, log_accept);
2122        }
2123        char dev[16];
2124        char var[80];
2125
2126        char vifs[256];
2127
2128        getIfLists(vifs, 256);
2129
2130        // char *vifs = nvram_safe_get ("lan_ifnames");
2131        // if (vifs != NULL)
2132        foreach(var, vifs, next) {
2133                if (strcmp(get_wan_face(), var)
2134                    && strcmp(nvram_safe_get("lan_ifname"), var)) {
2135                        if (nvram_nmatch("1", "%s_isolation", var)) {
2136                                save2file("-A INPUT -i %s -p udp --dport 67 -j %s\n", var, log_accept);
2137                                save2file("-A INPUT -i %s -p udp --dport 53 -j %s\n", var, log_accept);
2138                                save2file("-A INPUT -i %s -p tcp --dport 53 -j %s\n", var, log_accept);
2139                                save2file("-A INPUT -i %s -m state --state NEW -j %s\n", var, log_drop);
2140                        }
2141                        if (isstandalone(var)) {
2142                                save2file("-A INPUT -i %s -j %s\n", var, log_accept);
2143                        }
2144
2145                }
2146        }
2147
2148        /*
2149         * end lonewolf mods
2150         */
2151
2152        /*
2153         * Drop those packets we are NOT recognizable
2154         */
2155        save2file("-A INPUT -j %s\n", log_drop);
2156}
2157
2158void filter_output(void)
2159{
2160        /*
2161         * Sveasoft mod - default for br1/separate subnet WDS type
2162         */
2163        if (nvram_matchi("wl0_br1_enable", 1)
2164            && nvram_invmatchi("wl0_br1_nat", 1)
2165            && nvram_invmatchi("wl_br1_nat", 2))
2166                save2file("-A OUTPUT -o br1 -j %s\n", log_accept);
2167        if (nvram_matchi("wl1_br1_enable", 1)
2168            && nvram_invmatchi("wl1_br1_nat", 1)
2169            && nvram_invmatchi("wl_br1_nat", 2))
2170                save2file("-A OUTPUT -o br1 -j %s\n", log_accept);
2171#ifdef HAVE_VLANTAGGING
2172        add_bridges("OUTPUT", 0);
2173#endif
2174}
2175
2176static void filter_forward(void)
2177{
2178        char *filter_web_hosts, *filter_web_urls, *filter_rule;
2179        char *next;
2180        char dev[16];
2181        char var[80];
2182
2183        char vifs[256];         //
2184
2185        int i = 0;
2186        int filter_host_url = 0;
2187
2188        while (i < 15 && filter_host_url == 0) {
2189                i++;
2190
2191                filter_web_hosts = nvram_nget("filter_web_host%d", i);
2192                filter_web_urls = nvram_nget("filter_web_url%d", i);
2193                filter_rule = nvram_nget("filter_rule%d", i);
2194
2195                if (filter_web_hosts && strcmp(filter_web_hosts, "")
2196                    || (filter_web_urls && strcmp(filter_web_urls, ""))
2197                    || (filter_rule && !strncmp(filter_rule, "$STAT:1", 7))
2198                    || (filter_rule && !strncmp(filter_rule, "$STAT:2", 7))) {
2199                        filter_host_url = 1;
2200                }
2201        }
2202
2203        if (nvram_matchi("dtag_vlan8", 1) && nvram_matchi("wan_vdsl", 1)) {
2204                save2file("-A FORWARD -i %s -j %s\n", nvram_safe_get("tvnicfrom"), log_accept);
2205                save2file("-A FORWARD -o %s -j %s\n", nvram_safe_get("tvnicfrom"), log_accept);
2206        }
2207
2208        getIfLists(vifs, 256);
2209        // = nvram_safe_get ("lan_ifnames");
2210        // if (vifs != NULL)
2211        foreach(var, vifs, next) {
2212                if (strcmp(get_wan_face(), var)
2213                    && strcmp(nvram_safe_get("lan_ifname"), var)) {
2214                        if (isstandalone(var) && nvram_nmatch("1", "%s_nat", var)) {
2215                                save2file("-A FORWARD -i %s -j %s\n", var, log_accept);
2216                        }
2217                }
2218        }
2219
2220        /*
2221         * Drop the wrong state, INVALID, packets
2222         */
2223        // save2file("-A FORWARD -m state --state INVALID -j DROP\n");
2224
2225        /*
2226         * Sveasoft add - log invalid packets
2227         */
2228        if (!has_gateway())
2229                save2file("-A FORWARD -m state --state INVALID -j %s\n", log_drop);
2230
2231        /*
2232         * Filter setting by user definition
2233         */
2234        // save2file ("-A FORWARD -i %s -j lan2wan\n", lanface);
2235        save2file("-A FORWARD -j lan2wan\n");
2236
2237        /*
2238         * Filter Web application
2239         */
2240        // if (webfilter)
2241        // save2file ("-A FORWARD -i %s -o %s -p tcp --dport %d "
2242        // "-m webstr --content %d -j %s\n",
2243        // lanface, wanface, HTTP_PORT, webfilter, log_reject);
2244        if (nvram_invmatch("filter", "off") && webfilter && strlen(wanface)) {
2245                insmod("ipt_webstr");
2246                save2file("-A FORWARD -i %s -o %s -p tcp -m webstr --content %d -j %s\n", lanface, wanface, webfilter, log_reject);
2247        }
2248
2249        /*
2250         * If webfilter is used this rule must be evaluated after webstr rule
2251         */
2252        if (filter_host_url)
2253                save2file("-A FORWARD -m state --state RELATED,ESTABLISHED -j %s\n", log_accept);
2254
2255        /*
2256         * Accept the redirect, might be seen as INVALID, packets
2257         */
2258        save2file("-A FORWARD -i %s -o %s -j %s\n", lanface, lanface, log_accept);
2259
2260        /*
2261         * Drop all traffic from lan
2262         */
2263        if (nvram_matchi("pptpd_lockdown", 1))
2264                save2file("-A FORWARD -i %s -j %s\n", lanface, log_drop);
2265
2266        /*
2267         * Filter by destination ports "filter_port" if firewall on
2268         */
2269        if (nvram_invmatch("filter", "off"))
2270                parse_port_filter(nvram_safe_get("filter_port"));
2271
2272        /*
2273         * Sveasoft mods - accept OSPF protocol broadcasts
2274         */
2275        if (nvram_match("wk_mode", "ospf")) {
2276                save2file("-A FORWARD -p ospf -j %s\n", log_accept);
2277        }
2278        if (nvram_match("wk_mode", "bgp")) {
2279                save2file("-A FORWARD -p tcp --sport 179 -j %s\n", log_accept); // BGP
2280                // port
2281                save2file("-A FORWARD -p tcp --dport 179 -j %s\n", log_accept); // BGP
2282                // port
2283        }
2284#ifdef HAVE_OLSRD
2285        if (nvram_match("wk_mode", "olsr")) {
2286                save2file("-A FORWARD -p udp --dport 698 -j %s\n", log_accept);
2287                save2file("-A FORWARD -p udp --sport 698 -j %s\n", log_accept);
2288        }
2289#endif
2290
2291        /*
2292         * Sveasoft mod - FORWARD br1 to br0, protecting br0
2293         */
2294        if (nvram_matchi("wl0_br1_enable", 1)) {
2295
2296                if (nvram_matchi("wl0_br1_nat", 1)) {
2297                        save2file("-A FORWARD -i br0 -o br1 -j %s\n", log_accept);
2298                        save2file("-A FORWARD -o br0 -i br1 -m state --state ESTABLISHED,RELATED -j %s\n", log_accept);
2299                }
2300
2301                /*
2302                 * Sveasoft mod - FORWARD br0 to br1, protecting br1
2303                 */
2304                else if (nvram_matchi("wl0_br1_nat", 2)) {
2305                        save2file("-A FORWARD -o br0 -i br1 -j %s\n", log_accept);
2306                        save2file("-A FORWARD -i br0 -o br1 -m state --state ESTABLISHED,RELATED -j %s\n", log_accept);
2307                }
2308                /*
2309                 * Sveasoft mod - default for br1/separate subnet WDS type
2310                 */
2311                else
2312                        save2file("-A FORWARD -i br1 -o br0 -j %s\n", log_accept);
2313
2314                char *wan = get_wan_face();
2315                if (wan && strlen(wan))
2316                        save2file("-A FORWARD -i br1 -o %s -j %s\n", wan, log_accept);
2317
2318        }
2319#ifdef HAVE_VLANTAGGING
2320        add_bridges("FORWARD", 1);
2321#endif
2322        stop_vpn_modules();
2323        // unload_vpn_modules ();
2324
2325        if (nvram_invmatch("filter", "off") && strlen(wanface)) {
2326
2327                /*
2328                 * DROP packets for PPTP pass through.
2329                 */
2330                if (nvram_matchi("pptp_pass", 0))
2331                        save2file("-A FORWARD -o %s -p tcp --dport %d -j %s\n", wanface, PPTP_PORT, log_drop);
2332
2333                /*
2334                 * DROP packets for L2TP pass through.
2335                 */
2336                if (nvram_matchi("l2tp_pass", 0))
2337                        save2file("-A FORWARD -o %s -p udp --dport %d -j %s\n", wanface, L2TP_PORT, log_drop);
2338
2339                /*
2340                 * DROP packets for IPsec pass through
2341                 */
2342                if (nvram_matchi("ipsec_pass", 0))
2343                        save2file("-A FORWARD -o %s -p udp --dport %d -j %s\n", wanface, ISAKMP_PORT, log_drop);
2344
2345        }
2346        start_vpn_modules();
2347        // load_vpn_modules ();
2348        if (nvram_invmatch("filter", "off")) {
2349                if (nvram_matchi("pptp_pass", 1)) {
2350                        if (strlen(wanface)) {
2351                                save2file("-I FORWARD -o %s -s %s/%d -p tcp --dport %d -j %s\n", wanface, nvram_safe_get("lan_ipaddr"), getmask(nvram_safe_get("lan_netmask")), PPTP_PORT, log_accept);
2352                                save2file("-I FORWARD -o %s -s %s/%d -p gre -j %s\n", wanface, nvram_safe_get("lan_ipaddr"), getmask(nvram_safe_get("lan_netmask")), log_accept);
2353                        }
2354                }
2355        }
2356        /*
2357         * ACCEPT packets for Multicast pass through
2358         */
2359        if (nvram_matchi("dtag_vlan8", 1) && nvram_matchi("wan_vdsl", 1)) {
2360                if (doMultiCast() > 0)
2361                        save2file("-A FORWARD -i %s -p udp --destination %s -j %s\n", nvram_safe_get("tvnicfrom"), IP_MULTICAST, log_accept);
2362#ifdef HAVE_PPTP
2363        } else if (nvram_match("wan_proto", "pptp") && nvram_matchi("pptp_iptv", 1) && nvram_get("tvnicfrom")) {
2364                if (doMultiCast() > 0)
2365                        save2file("-A FORWARD -i %s -p udp --destination %s -j %s\n", nvram_safe_get("tvnicfrom"), IP_MULTICAST, log_accept);
2366#endif
2367#ifdef HAVE_L2TP
2368        } else if (nvram_match("wan_proto", "l2tp") && nvram_matchi("pptp_iptv", 1) && nvram_get("tvnicfrom")) {
2369                if (doMultiCast() > 0)
2370                        save2file("-A FORWARD -i %s -p udp --destination %s -j %s\n", nvram_safe_get("tvnicfrom"), IP_MULTICAST, log_accept);
2371#endif
2372#ifdef HAVE_PPPOEDUAL
2373        } else if (nvram_match("wan_proto", "pppoe_dual") && nvram_matchi("pptp_iptv", 1) && nvram_get("tvnicfrom")) {
2374                if (doMultiCast() > 0)
2375                        save2file("-A FORWARD -i %s -p udp --destination %s -j %s\n", nvram_safe_get("tvnicfrom"), IP_MULTICAST, log_accept);
2376#endif
2377        } else {
2378                if (doMultiCast() > 0 && strlen(wanface))
2379                        save2file("-A FORWARD -i %s -p udp --destination %s -j %s\n", wanface, IP_MULTICAST, log_accept);
2380        }
2381        /*
2382         * port-forwarding accepting rules
2383         */
2384        if (*suspense != 0)
2385                save2file("%s", suspense);
2386        free(suspense);
2387        /*
2388         * Port trigger by user definition
2389         */
2390        /*
2391         * Incoming connection will be accepted, if it match the port-ranges.
2392         */
2393        if (strlen(wanface)) {
2394                save2file("-A FORWARD -i %s -o %s -j TRIGGER --trigger-type in\n", wanface, lanface);
2395                save2file("-A FORWARD -i %s -j trigger_out\n", lanface);
2396        }
2397        /*
2398         * DMZ forwarding
2399         */
2400        if (dmzenable)
2401                save2file("-A FORWARD -o %s -d %s%s -j %s\n", lanface, lan_cclass, nvram_safe_get("dmz_ipaddr"), log_accept);
2402
2403        getIfLists(vifs, 256);
2404
2405        foreach(var, vifs, next) {
2406                if (strcmp(get_wan_face(), var)
2407                    && strcmp(nvram_safe_get("lan_ifname"), var)) {
2408                        if (nvram_nmatch("1", "%s_isolation", var)) {
2409                                save2file("-I FORWARD -i %s -d %s/%s -m state --state NEW -j %s\n", var, nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"), log_drop);
2410                                save2file("-A FORWARD -i br0 -o %s -m state --state NEW -j %s\n", var, log_drop);
2411                                if (nvram_matchi("privoxy_transp_enable", 1)) {
2412                                        save2file("-I INPUT -i %s -d %s/%s -p tcp --dport 8118 -j %s\n", var, nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"), log_accept);
2413                                }
2414                        }
2415                }
2416        }
2417
2418        /*
2419         * Accept new connections
2420         */
2421        save2file("-A FORWARD -i %s -m state --state NEW -j %s\n", lanface, log_accept);
2422        /*
2423         * ...otherwise drop if firewall on
2424         */
2425        if (nvram_invmatch("filter", "off"))
2426                save2file("-A FORWARD -j %s\n", log_drop);
2427
2428        lan2wan_chains();
2429
2430        parse_trigger_out(nvram_safe_get("port_trigger"));
2431
2432        /*
2433         * If webfilter is not used we can put this rule on top in order to increase WAN<->LAN throughput
2434         */
2435        if (!filter_host_url)
2436                save2file("-I FORWARD -m state --state RELATED,ESTABLISHED -j %s\n", log_accept);
2437}
2438
2439/*
2440 *      Mangle table
2441 */
2442static void mangle_table(void)
2443{
2444        save2file("*mangle\n:PREROUTING ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n");
2445
2446        if (wanactive() && (nvram_matchi("block_loopback", 0) || nvram_match("filter", "off"))) {
2447                insmod("ipt_mark xt_mark ipt_CONNMARK xt_CONNMARK xt_connmark");
2448
2449                save2file("-A PREROUTING -i ! %s -d %s -j MARK --set-mark %s\n", get_wan_face(), get_wan_ipaddr(), get_NFServiceMark("FORWARD", 1));
2450
2451                save2file("-A PREROUTING -j CONNMARK --save-mark\n");
2452        }
2453
2454        /*
2455         * Clamp TCP MSS to PMTU of WAN interface
2456         */
2457        save2file("-I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n");
2458
2459#ifdef HAVE_PRIVOXY
2460        if ((nvram_matchi("privoxy_enable", 1)) && (nvram_matchi("wshaper_enable", 1))) {
2461                save2file("-I OUTPUT -p tcp --sport 8118 -j IMQ --todev 0\n");
2462        }
2463#endif
2464
2465        /*
2466         * Sveasoft add - avoid the "mark everything" rule, Reformed's PPPoE code
2467         * should take care of this
2468         */
2469        /*
2470         * For PPPoE Connect On Demand, to reset idle timer. add by honor
2471         * (2003-04-17) Reference driver/net/ppp_generic.c
2472         */
2473        // save2file("-A PREROUTING -i %s -m mark ! --mark 0 -j MARK --set-mark
2474        // %d\n", lanface, MARK_LAN2WAN);
2475        save2file("COMMIT\n");
2476}
2477
2478/*
2479 *      NAT table
2480 */
2481static void nat_table(void)
2482{
2483        save2file("*nat\n:PREROUTING ACCEPT [0:0]\n:POSTROUTING ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n");
2484        if (wanactive()) {
2485                nat_prerouting();
2486                nat_postrouting();
2487        }
2488        save2file("COMMIT\n");
2489}
2490
2491/*
2492 *      Filter table
2493 */
2494static void filter_table(void)
2495{
2496        save2file("*filter\n:INPUT ACCEPT [0:0]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n:logaccept - [0:0]\n:logdrop - [0:0]\n:logreject - [0:0]\n"
2497#ifdef FLOOD_PROTECT
2498                  ":limaccept - [0:0]\n"
2499#endif
2500                  ":trigger_out - [0:0]\n:lan2wan - [0:0]\n");
2501
2502        int seq;
2503
2504        for (seq = 1; seq <= NR_RULES; seq++) {
2505                save2file(":grp_%d - [0:0]\n", seq);
2506                save2file(":advgrp_%d - [0:0]\n", seq);
2507        }
2508#ifndef HAVE_MICRO
2509        if ((nvram_matchi("limit_telnet", 1)) || (nvram_matchi("limit_pptp", 1)) || (nvram_matchi("limit_ssh", 1)) || (nvram_matchi("limit_ftp", 1))) {
2510                save2file(":logbrute - [0:0]\n");
2511                save2file("-A logbrute -m recent --set --name BRUTEFORCE --rsource\n");
2512                save2file("-A logbrute -m recent ! --update --seconds 60 --hitcount 4 --name BRUTEFORCE --rsource -j RETURN\n");
2513                // -m limit rule is a fallback in case -m recent isn't included in a build
2514                save2file("-A logbrute -m limit --limit 1/min --limit-burst 1 -j RETURN\n");
2515                if ((nvram_matchi("log_enable", 1))
2516                    && (nvram_matchi("log_dropped", 1)))
2517                        save2file("-A logbrute -j LOG --log-prefix \"[DROP BRUTEFORCE] : \" --log-tcp-options --log-ip-options\n");
2518                save2file("-A logbrute -j %s\n", log_drop);
2519        }
2520#endif
2521
2522        if (wanactive()) {
2523                /*
2524                 * Does it disable the filter?
2525                 */
2526                if (nvram_match("filter", "off")
2527                    || !has_gateway()) {
2528
2529                        /*
2530                         * Make sure remote management ports are filtered if it is disabled
2531                         */
2532                        if (!remotemanage && strlen(wanface)) {
2533                                save2file("-A INPUT -p tcp -i %s --dport %s -j %s\n", wanface, nvram_safe_get("http_wanport"), log_drop);
2534                                save2file("-A INPUT -p tcp -i %s --dport 80 -j %s\n", wanface, log_drop);
2535                                save2file("-A INPUT -p tcp -i %s --dport 443 -j %s\n", wanface, log_drop);
2536                                save2file("-A INPUT -p tcp -i %s --dport 69 -j %s\n", wanface, log_drop);
2537                        }
2538                        /*
2539                         * Make sure remote ssh/telnet port is filtered if it is disabled :
2540                         * Botho 03-05-2006
2541                         */
2542#ifdef HAVE_SSHD
2543                        if (!remotessh && strlen(wanface) > 0) {
2544                                save2file("-A INPUT -i %s -p tcp --dport %s -j %s\n", wanface, nvram_safe_get("sshd_port"), log_drop);
2545                        }
2546#endif
2547
2548#ifdef HAVE_TELNET
2549                        if (!remotetelnet && strlen(wanface) > 0) {
2550                                save2file("-A INPUT -p tcp -i %s --dport 23 -j %s\n", wanface, log_drop);
2551                        }
2552#endif
2553                        filter_forward();
2554                } else {
2555
2556                        filter_input();
2557                        filter_output();
2558                        filter_forward();
2559                }
2560        } else {
2561                char dev[16];
2562                char var[80];
2563                char vifs[256];
2564                char *next;
2565                getIfLists(vifs, 256);
2566                foreach(var, vifs, next) {
2567                        if (strcmp(get_wan_face(), var)
2568                            && strcmp(nvram_safe_get("lan_ifname"), var)) {
2569                                if (nvram_nmatch("1", "%s_isolation", var)) {
2570                                        save2file("-A INPUT -i %s -p udp --dport 67 -j %s\n", var, log_accept);
2571                                        save2file("-A INPUT -i %s -p udp --dport 53 -j %s\n", var, log_accept);
2572                                        save2file("-A INPUT -i %s -p tcp --dport 53 -j %s\n", var, log_accept);
2573                                        save2file("-A INPUT -i %s -m state --state NEW -j %s\n", var, log_drop);
2574                                }
2575                                if (isstandalone(var)) {
2576                                        save2file("-A INPUT -i %s -j %s\n", var, log_accept);
2577                                }
2578
2579                        }
2580                }
2581
2582        }
2583
2584        /*
2585         * logaccept chain
2586         */
2587#ifdef FLOOD_PROTECT
2588        if ((nvram_matchi("log_enable", 1))
2589            && (nvram_matchi("log_accepted", 1)))
2590                save2file("-A logaccept -i %s -m state --state NEW -m limit --limit %d -j LOG --log-prefix \"FLOOD \" --log-tcp-sequence --log-tcp-options --log-ip-options\n", wanface, FLOOD_RATE);
2591        save2file("-A logaccept -i %s -m state --state NEW -m limit --limit %d -j %s\n", wanface, FLOOD_RATE, log_drop);
2592#endif
2593        if ((nvram_matchi("log_enable", 1))
2594            && (nvram_matchi("log_accepted", 1)))
2595                save2file("-A logaccept -m state --state NEW -j LOG --log-prefix \"ACCEPT \" --log-tcp-sequence --log-tcp-options --log-ip-options\n");
2596        save2file("-A logaccept -j ACCEPT\n");
2597
2598        /*
2599         * logdrop chain
2600         */
2601        if (has_gateway()) {
2602                if ((nvram_matchi("log_enable", 1))
2603                    && (nvram_matchi("log_dropped", 1)))
2604                        save2file
2605                            ("-A logdrop -m state --state NEW -j LOG --log-prefix \"DROP \" --log-tcp-sequence --log-tcp-options --log-ip-options\n-A logdrop -m state --state INVALID -j LOG --log-prefix \"DROP \" --log-tcp-sequence --log-tcp-options --log-ip-options\n");
2606        } else {
2607                if ((nvram_matchi("log_enable", 1))
2608                    && (nvram_matchi("log_dropped", 1)))
2609                        save2file("-A logdrop -m state --state NEW -j LOG --log-prefix \"DROP \" --log-tcp-sequence --log-tcp-options --log-ip-options\n");
2610        }
2611        save2file("-A logdrop -j DROP\n");
2612
2613        /*
2614         * logreject chain
2615         */
2616        if ((nvram_matchi("log_enable", 1))
2617            && (nvram_matchi("log_rejected", 1)))
2618                save2file("-A logreject -j LOG --log-prefix \"WEBDROP \" --log-tcp-sequence --log-tcp-options --log-ip-options\n");
2619        save2file("-A logreject -p tcp -j REJECT --reject-with tcp-reset\n");
2620
2621#ifdef FLOOD_PROTECT
2622        /*
2623         * limaccept chain
2624         */
2625        if ((nvram_matchi("log_enable", 1))
2626            && (nvram_matchi("log_accepted", 1)))
2627                save2file("-A limaccept -i %s -m state --state NEW -m limit --limit %d -j LOG --log-prefix \"FLOOD \" --log-tcp-sequence --log-tcp-options --log-ip-options\n");
2628        save2file("-A limaccept -i %s -m state --state NEW -m limit --limit %d -j %s\n-A limaccept -j ACCEPT\n", wanface, FLOOD_RATE, wanface, FLOOD_RATE, log_drop);
2629#endif
2630
2631        save2file("COMMIT\n");
2632}
2633
2634static void create_restore_file(void)
2635{
2636        mangle_table();
2637        nat_table();
2638        filter_table();
2639}
2640
2641#ifdef HAVE_GUESTPORT
2642void set_gprules(char *iface)
2643{
2644        char gport[32];
2645        char giface[16];
2646        char gvar[32];
2647        char gipaddr[32];
2648        char gnetmask[32];
2649
2650        sprintf(gport, "guestport_%s", iface);
2651        if (nvram_get(gport)) {
2652                sprintf(giface, nvram_safe_get(gport));
2653
2654                sprintf(gvar, "%s_ipaddr", giface);
2655                sprintf(gipaddr, nvram_safe_get(gvar));
2656
2657                sprintf(gvar, "%s_netmask", giface);
2658                sprintf(gnetmask, nvram_safe_get(gvar));
2659
2660                sysprintf("iptables -I INPUT -i %s -d %s/%s -m state --state NEW -j DROP", giface, nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
2661
2662                sysprintf("iptables -I INPUT -i %s -d %s/255.255.255.255 -m state --state NEW -j DROP", giface, gipaddr);
2663                sysprintf("iptables -I INPUT -i %s -d %s/255.255.255.255 -p udp --dport 67 -j %s", giface, gipaddr, TARG_PASS);
2664                sysprintf("iptables -I INPUT -i %s -d %s/255.255.255.255 -p udp --dport 53 -j %s", giface, gipaddr, TARG_PASS);
2665                sysprintf("iptables -I INPUT -i %s -d %s/255.255.255.255 -p tcp --dport 53 -j %s", giface, gipaddr, TARG_PASS);
2666
2667                sysprintf("iptables -I FORWARD -i %s -m state --state NEW -j %s", giface, TARG_PASS);
2668                sysprintf("iptables -I FORWARD -i %s -o br0 -m state --state NEW -j DROP", giface);
2669                sysprintf("iptables -I FORWARD -i br0 -o %s -m state --state NEW -j DROP", giface);
2670        }
2671}
2672#endif
2673
2674int isregistered_real(void);
2675#ifdef HAVE_IPV6
2676void start_firewall6(void)
2677{
2678
2679        if (nvram_matchi("ipv6_enable", 0))
2680                return;
2681
2682        fprintf(stderr, "start firewall6\n");
2683
2684        insmod("nf_defrag_ipv6 nf_log_ipv6 ip6_tables nf_conntrack_ipv6 ip6table_filter");
2685
2686        eval("ip6tables", "-F", "INPUT");
2687        eval("ip6tables", "-F", "FORWARD");
2688        eval("ip6tables", "-F", "OUTPUT");
2689        eval("ip6tables", "-A", "INPUT", "-m", "state", "--state", "RELATED,ESTABLISHED", "-j", "ACCEPT");
2690        eval("ip6tables", "-A", "INPUT", "-p", "icmpv6", "-j", "ACCEPT");
2691        eval("ip6tables", "-A", "INPUT", "-s", "fe80::/64", "-j", "ACCEPT");
2692        eval("ip6tables", "-A", "INPUT", "-i", "br0", "-j", "ACCEPT");
2693
2694        if (nvram_match("ipv6_typ", "ipv6rd") || nvram_match("ipv6_typ", "ipv6in4") || nvram_match("ipv6_typ", "ipv6to4")) {
2695
2696                eval("iptables", "-I", "INPUT", "-p", "41", "-j", "ACCEPT");
2697
2698                eval("ip6tables", "-A", "FORWARD", "-p", "tcp", "-m", "tcp", "--tcp-flags", "SYN,RST", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu");
2699
2700        }
2701
2702        /* accept ICMP requests from the remote tunnel endpoint */
2703        if (nvram_match("ipv6_typ", "ipv6in4")) {
2704                char *ip = nvram_safe_get("ipv6_tun_end_ipv4");
2705                if (*ip && strcmp(ip, "0.0.0.0") != 0)
2706                        eval("iptables", "-I", "INPUT", "-p", "icmp", "-s", ip, "-j", "ACCEPT");
2707        }
2708
2709        if (nvram_match("ipv6_typ", "ipv6in4") || nvram_match("ipv6_typ", "ipv6native"))
2710                eval("ip6tables", "-A", "INPUT", "-p", "udp", "--dport", "546", "-j", "ACCEPT");
2711
2712        eval("ip6tables", "-A", "INPUT", "-j", "DROP");
2713
2714        eval("ip6tables", "-A", "FORWARD", "-m", "state", "--state", "RELATED,ESTABLISHED", "-j", "ACCEPT");
2715
2716        if (nvram_match("ipv6_typ", "ipv6native") || nvram_match("ipv6_typ", "ipv6pd")) {
2717                if (nvram_match("wan_proto", "disabled")) {
2718                        eval("ip6tables", "-A", "FORWARD", "-o", nvram_safe_get("lan_ifname"), "-j", "ACCEPT");
2719                } else {
2720                        eval("ip6tables", "-A", "FORWARD", "-o", get_wan_face(), "-j", "ACCEPT");
2721                }
2722        }
2723
2724        if (nvram_match("ipv6_typ", "ipv6in4"))
2725                eval("ip6tables", "-A", "FORWARD", "-o", "ip6tun", "-j", "ACCEPT");
2726
2727        eval("ip6tables", "-A", "FORWARD", "-p", "icmpv6", "--icmpv6-type", "echo-request", "-m", "limit", "--limit", "2/s", "-j", "ACCEPT");
2728
2729        eval("ip6tables", "-A", "FORWARD", "-j", "DROP");
2730
2731}
2732#endif
2733
2734void start_loadfwmodules(void)
2735{
2736        insmod("iptable_raw iptable_mangle nf_conntrack_h323 xt_NFLOG"
2737               " xt_length xt_REDIRECT xt_CT xt_limit xt_TCPMSS"
2738               " xt_connbytes xt_connlimit"
2739               " xt_CLASSIFY xt_recent"
2740               " xt_conntrack xt_state"
2741               " xt_string xt_LOG xt_iprange xt_tcpmss" " xt_NETMAP compat_xtables" " ipt_MASQUERADE iptable_filter nf_reject_ipv4" " ipt_REJECT nf_nat_h323" " ipt_TRIGGER nf_nat_masquerade_ipv4 ipt_ah");
2742
2743}
2744
2745#ifdef DEVELOPE_ENV
2746int main(void)
2747#else
2748void start_firewall(void)
2749#endif
2750{
2751        DIR *dir;
2752        struct dirent *file;
2753        FILE *fp;
2754        char name[NAME_MAX];
2755        struct stat statbuff;
2756        int log_level = 0;
2757        start_loadfwmodules();
2758        system("cat /proc/net/ip_conntrack_flush 2>&1");
2759        system("cat /proc/sys/net/netfilter/nf_conntrack_flush 2>&1");
2760        if (nvram_matchi("arp_spoofing", 1))
2761                writeproc("/proc/net/arp_spoofing_enable", "1");
2762        else
2763                writeproc("/proc/net/arp_spoofing_enable", "0");
2764
2765        if (!nvram_invmatchi("wshaper_enable", 0))
2766                insmod("shortcut-fe");
2767        else
2768                rmmod("shortcut-fe");
2769        writeint("/sys/fast_classifier/skip_to_bridge_ingress", 1);
2770#ifndef HAVE_80211AC
2771        /*
2772         * Improve WAN<->LAN Performance on K26
2773         */
2774        writeprocsysnet("core/netdev_max_backlog", "120");
2775#endif
2776        /*
2777         * Block obviously spoofed IP addresses
2778         */
2779        DEBUG("start firewall()...........\n");
2780#if 0
2781        if (!(dir = opendir("/proc/sys/net/ipv4/conf")))
2782                perror("/proc/sys/net/ipv4/conf");
2783        while (dir && (file = readdir(dir))) {
2784                if (strncmp(file->d_name, ".", NAME_MAX) != 0 && strncmp(file->d_name, "..", NAME_MAX) != 0) {
2785                        sprintf(name, "/proc/sys/net/ipv4/conf/%s/rp_filter", file->d_name);
2786                        if (!(fp = fopen(name, "r+"))) {
2787                                perror(name);
2788                                break;
2789                        }
2790                        fputc('1', fp);
2791                        fclose(fp);
2792                }
2793        }
2794        closedir(dir);
2795#endif
2796        /*
2797         * Determine LOG level
2798         */
2799        DEBUG("start firewall()........1\n");
2800        log_level = nvram_geti("log_level");
2801        // sprintf(log_drop, "%s", (log_level & 1) ? "logdrop" : "DROP");
2802        // sprintf(log_accept, "%s", (log_level & 2) ? "logaccept" : TARG_PASS);
2803        // sprintf(log_reject, "%s", (log_level & 1) ? "logreject" : TARG_RST);
2804        if (log_level >= 1)
2805                sprintf(log_drop, "%s", "logdrop");
2806        else
2807                sprintf(log_drop, "%s", "DROP");
2808        if (log_level >= 2)
2809                sprintf(log_accept, "%s", "logaccept");
2810        else
2811                sprintf(log_accept, "%s", TARG_PASS);
2812        if (log_level >= 1)
2813                sprintf(log_reject, "%s", "logreject");
2814        else
2815                sprintf(log_reject, "%s", TARG_RST);
2816
2817        /*
2818         * Get NVRAM value into globle variable
2819         */
2820        DEBUG("start firewall()........2\n");
2821        strncpy(lanface, nvram_safe_get("lan_ifname"), IFNAMSIZ);
2822        strncpy(wanface, get_wan_face(), IFNAMSIZ);
2823        strncpy(wanaddr, get_wan_ipaddr(), sizeof(wanaddr));
2824
2825        if (nvram_match("wan_proto", "pptp")) {
2826                if (strlen(nvram_safe_get("pptp_get_ip")) == 0) // for initial dhcp ip
2827                {
2828                        if (getSTA())
2829                                strncpy(wanface, getSTA(), IFNAMSIZ);
2830                        else
2831                                strncpy(wanface, nvram_safe_get("wan_ifname"), IFNAMSIZ);
2832                }
2833        }
2834
2835        ip2cclass(nvram_safe_get("lan_ipaddr"), &lan_cclass[0], sizeof(lan_cclass));
2836
2837        /*
2838         * Run Webfilter ?
2839         */
2840        webfilter = 0;          /* Reset, clear the late setting */
2841        if (nvram_matchi("block_cookie", 1))
2842                webfilter |= BLK_COOKIE;
2843        if (nvram_matchi("block_java", 1))
2844                webfilter |= BLK_JAVA;
2845        if (nvram_matchi("block_activex", 1))
2846                webfilter |= BLK_ACTIVE;
2847        if (nvram_matchi("block_proxy", 1))
2848                webfilter |= BLK_PROXY;
2849
2850        /*
2851         * Run DMZ forwarding ?
2852         */
2853        if (has_gateway()
2854            && nvram_matchi("dmz_enable", 1)
2855            && nvram_invmatch("dmz_ipaddr", "")
2856            && nvram_invmatchi("dmz_ipaddr", 0))
2857                dmzenable = 1;
2858        else
2859                dmzenable = 0;
2860
2861        /*
2862         * Remote Web GUI management
2863         */
2864        if (nvram_matchi("remote_management", 1) && nvram_invmatch("http_wanport", "") && nvram_invmatchi("http_wanport", 0))
2865                remotemanage = 1;
2866        else
2867                remotemanage = 0;
2868
2869#ifdef HAVE_SSHD
2870        /*
2871         * Remote ssh management : Botho 03-05-2006
2872         */
2873        if (nvram_matchi("remote_mgt_ssh", 1) && nvram_invmatch("sshd_wanport", "") && nvram_invmatchi("sshd_wanport", 0) && nvram_matchi("sshd_enable", 1))
2874                remotessh = 1;
2875        else
2876                remotessh = 0;
2877#endif
2878
2879#ifdef HAVE_TELNET
2880        /*
2881         * Remote telnet management
2882         */
2883        if (nvram_matchi("remote_mgt_telnet", 1) && nvram_invmatch("telnet_wanport", "") && nvram_invmatchi("telnet_wanport", 0) && nvram_matchi("telnetd_enable", 1))
2884                remotetelnet = 1;
2885        else
2886                remotetelnet = 0;
2887#endif
2888
2889#ifdef HAVE_HTTPS
2890        if (nvram_matchi("remote_mgt_https", 1))
2891                web_lanport = HTTPS_PORT;
2892        else
2893#endif
2894                web_lanport = nvram_geti("http_lanport") ? : HTTP_PORT;
2895
2896        /*
2897         * Remove existent file
2898         */
2899        DEBUG("start firewall()........3\n");
2900        if (stat(IPTABLES_SAVE_FILE, &statbuff) == 0)
2901                unlink(IPTABLES_SAVE_FILE);
2902
2903        /*
2904         * Create file for iptables-restore
2905         */
2906        DEBUG("start firewall()........4\n");
2907        create_restore_file();
2908
2909#ifndef DEVELOPE_ENV
2910        /*
2911         * Insert the rules into kernel
2912         */
2913        DEBUG("start firewall()........5\n");
2914        eval("iptables-restore", IPTABLES_SAVE_FILE);
2915
2916        // unlink(IPTABLES_SAVE_FILE);
2917#endif
2918#ifdef HAVE_IPV6
2919        start_firewall6();
2920#endif
2921        /*
2922         * begin Sveasoft add
2923         */
2924        /*
2925         * run rc_firewall script
2926         */
2927        cprintf("Exec RC Filewall\n");
2928#ifdef HAVE_REGISTER
2929#ifndef HAVE_ERC
2930        if (isregistered_real())
2931#endif
2932#endif
2933        {
2934                runStartup("/jffs/etc/config", ".prewall");     // if available
2935                runStartup("/mmc/etc/config", ".prewall");      // if available
2936                runStartup("/tmp/etc/config", ".prewall");      // if available
2937                create_rc_file(RC_FIREWALL);
2938                if (f_exists("/tmp/.rc_firewall")) {
2939                        setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
2940                        system("/tmp/.rc_firewall");
2941                }
2942                runStartup("/etc/config", ".firewall");
2943                runStartup("/sd/etc/config", ".firewall");
2944        }
2945
2946        cprintf("Ready\n");
2947        /*
2948         * end Sveasoft add
2949         */
2950
2951        // run wanup scripts
2952        start_wanup();
2953
2954        /*
2955         * Turn on the DMZ-LED, if enabled.(from service.c)
2956         */
2957        cprintf("enable DMZ\n");
2958        if (dmzenable)
2959                diag_led(DMZ, START_LED);
2960        else
2961                diag_led(DMZ, STOP_LED);
2962        cprintf("done");
2963
2964        cprintf("Start firewall\n");
2965        /*
2966         * We don't forward packet until those policies are set.
2967         */
2968        DEBUG("start firewall()........6\n");
2969        if ((fp = fopen("/proc/sys/net/ipv4/ip_forward", "r+"))) {
2970                fputc('1', fp);
2971                fclose(fp);
2972        } else
2973                perror("/proc/sys/net/ipv4/ip_forward");
2974        cprintf("start ipv6\n");
2975#ifdef HAVE_IPV6
2976        if (nvram_matchi("ipv6_enable", 1)) {
2977                writeprocsysnet("ipv6/conf/all/forwarding", "1");
2978        }
2979#endif
2980#ifdef HAVE_GGEW
2981        char *wordlist = nvram_safe_get("ral");
2982        char var[256], *next;
2983
2984        foreach(var, wordlist, next) {
2985                sysprintf("iptables -I INPUT -s %s -j %s", var, log_accept);
2986        }
2987#endif
2988#ifdef HAVE_IAS
2989        if (nvram_matchi("ias_startup", 3))
2990                sysprintf("iptables -t nat -I PREROUTING -i br0 -p udp --dport 53 -j DNAT --to 192.168.11.1:55300");
2991#endif
2992#ifdef HAVE_GUESTPORT
2993        set_gprules("ath0");
2994#ifdef HAVE_WZRHPAG300NH
2995        set_gprules("ath1");
2996#endif
2997#endif
2998
2999/*
3000 *      Services restart.
3001 *      Should be always at the end.
3002 */
3003
3004#ifdef HAVE_WIFIDOG
3005        if (nvram_matchi("wd_enable", 1)) {
3006                stop_wifidog();
3007                start_wifidog();
3008        }
3009#endif
3010#ifdef HAVE_CHILLI
3011        if (nvram_matchi("chilli_enable", 1)
3012            || nvram_matchi("hotss_enable", 1)) {
3013                stop_chilli();
3014                start_chilli();
3015        }
3016#endif
3017#ifdef HAVE_PPPOESERVER
3018        if (nvram_matchi("pppoeserver_enabled", 1)) {
3019                stop_pppoeserver();
3020                start_pppoeserver();
3021        }
3022#endif
3023
3024        cprintf("ready");
3025
3026        cprintf("done\n");
3027}
3028
3029#ifdef HAVE_IPV6
3030void stop_firewall6(void)
3031{
3032        if (nvram_matchi("ipv6_enable", 0))
3033                return;
3034
3035        //eval("ip", "-6", "addr", "flush", "scope", "global");
3036}
3037#endif
3038
3039void stop_firewall(void)
3040{
3041        eval("iptables", "-t", "raw", "-F");
3042//      stop_anchorfree();
3043        /*
3044         * Make sure the DMZ-LED is off (from service.c)
3045         */
3046        diag_led(DMZ, STOP_LED);
3047#ifdef HAVE_GGEW
3048        char *wordlist = nvram_safe_get("ral");
3049        char var[256], *next;
3050
3051        foreach(var, wordlist, next) {
3052                sysprintf("iptables -D INPUT -s %s -j %s", var, log_accept);
3053        }
3054#endif
3055        char num[32];
3056        int i;
3057
3058        for (i = 0; i < 10; i++) {
3059                eval("iptables", "-F", "lan2wan");
3060                sprintf(num, "grp_%d", i);
3061                eval("iptables", "-F", num);
3062                sprintf(num, "advgrp_%d", i);
3063                eval("iptables", "-F", num);
3064        }
3065        rmmod("ipt_webstr");
3066        rmmod("ipt_layer7");
3067        rmmod("xt_layer7");
3068        rmmod("ipt_ipp2p");
3069        rmmod("xt_ipp2p");
3070        if (nvram_invmatchi("apd_enable", 0)) {
3071                rmmod("ipt_mark");
3072                rmmod("xt_mark");
3073        }
3074        if (nvram_invmatchi("apd_enable", 0)) {
3075                rmmod("ipt_mac");
3076                rmmod("xt_mac");
3077        }
3078        cprintf("done\n");
3079#ifdef HAVE_IPV6
3080        stop_firewall6();
3081#endif
3082        return;
3083}
3084
3085/*
3086 * PARAM - seq : Seqence number.
3087 *
3088 * RETURN - 0 : It's not in time.
3089 *                      1 : in time and anytime
3090 *                      2 : in time
3091 */
3092int if_tod_intime(int seq)
3093{
3094        char *todvalue;
3095        int sched = 0, allday = 0;
3096        int hr_st, hr_end;      /* hour */
3097        int mi_st, mi_end;      /* minute */
3098        char wday[128];
3099        int intime = 0;
3100
3101        /*
3102         * Get the NVRAM data
3103         */
3104        todvalue = nvram_nget("filter_tod%d", seq);
3105
3106        DEBUG("%s: %s\n", todname, todvalue);
3107        if (strcmp(todvalue, "") == 0)
3108                return 0;
3109
3110        /*
3111         * Is it anytime or scheduled ?
3112         */
3113        if (strcmp(todvalue, "0:0 23:59 0-0") == 0 || strcmp(todvalue, "0:0 23:59 0-6") == 0) {
3114                sched = 0;
3115        } else {
3116                sched = 1;
3117                if (strcmp(todvalue, "0:0 23:59") == 0)
3118                        allday = 1;
3119                if (sscanf(todvalue, "%d:%d %d:%d %s", &hr_st, &mi_st, &hr_end, &mi_end, wday) != 5)
3120                        return 0;       /* error format */
3121        }
3122
3123        DEBUG("sched=%d, allday=%d\n", sched, allday);
3124
3125        /*
3126         * Anytime
3127         */
3128        if (!sched)
3129                return 1;
3130
3131        /*
3132         * Scheduled
3133         */
3134        if (allday) {           /* 24-hour, but not everyday */
3135
3136                if (match_wday(wday))
3137                        intime = 1;
3138        } else {                /* Nither 24-hour, nor everyday */
3139
3140                if (match_wday(wday)
3141                    && match_hrmin(hr_st, mi_st, hr_end, mi_end))
3142                        intime = 1;
3143        }
3144        DEBUG("intime=%d\n", intime);
3145
3146        /*
3147         * Would it be enabled now ?
3148         */
3149        if (intime)
3150                return 2;
3151
3152        return 0;
3153}
Note: See TracBrowser for help on using the repository browser.