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

Revision 12379, 77.0 kB (checked in by BrainSlayer, 5 months ago)

use snat instead of masquerade

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