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

Revision 12387, 77.1 kB (checked in by BrainSlayer, 5 months ago)

should be more simple

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