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

Last change on this file since 8955 was 8955, checked in by BrainSlayer, 5 years ago

now multicast works for multiple separated interfaces

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