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

Last change on this file since 12387 was 12387, checked in by BrainSlayer, 4 years ago

should be more simple

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