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

Revision 12386, 77.3 kB (checked in by BrainSlayer, 5 months ago)

fixes pptp snat issue

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