root/src/router/services/networking/firewall.c

Revision 12235, 76.9 kB (checked in by BrainSlayer, 6 months ago)

auto formated source

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