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

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

disable snat if routing mode is not gateway/nat

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