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

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

solves chilli routing problems

File size: 77.3 KB
Line 
1/*
2 * firewall.c
3 *
4 * Copyright (C) 2007 Sebastian Gottschall <gottschall@dd-wrt.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * $Id:
21 */
22
23// #define DEVELOPE_ENV
24// #define XBOX_SUPPORT /* Define Microsoft XBox, game machine, support */
25#define AOL_SUPPORT             /* Define AOL support */
26// #define FLOOD_PROTECT /* Define flooding protection */
27// #define REVERSE_RULE_ORDER /* If it needs to reverse the rule's
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        if (nvram_match("wk_mode","gateway"))
2246        {
2247        save2file( "-I INPUT -m state --state NEW -i tun0 -j ACCEPT\n" );
2248        save2file( "-I FORWARD -m state --state NEW -i tun0 -j ACCEPT\n" );
2249        }else
2250        {
2251        save2file( "-I INPUT -i tun0 -j ACCEPT\n" );
2252        save2file( "-I FORWARD -i tun0 -j ACCEPT\n" ); 
2253        }
2254    }
2255
2256    /*
2257     * Does it disable the filter?
2258     */
2259    if( nvram_match( "filter", "off" ) || nvram_match( "wk_mode", "router" )
2260        || nvram_match( "wk_mode", "static" ) )
2261    {
2262
2263        /*
2264         * Make sure remote management ports are filtered if it is disabled
2265         */
2266        if( !remotemanage )
2267        {
2268            save2file( "-A INPUT -p tcp -i %s --dport %s -j DROP\n", wanface,
2269                       nvram_safe_get( "http_wanport" ) );
2270            save2file( "-A INPUT -p tcp -i %s --dport 80 -j DROP\n",
2271                       wanface );
2272            save2file( "-A INPUT -p tcp -i %s --dport 443 -j DROP\n",
2273                       wanface );
2274            save2file( "-A INPUT -p tcp -i %s --dport 69 -j DROP\n",
2275                       wanface );
2276        }
2277        /*
2278         * Make sure remote ssh/telnet port is filtered if it is disabled :
2279         * Botho 03-05-2006
2280         */
2281#ifdef HAVE_SSHD
2282        if( !remotessh )
2283        {
2284            save2file( "-A INPUT -p tcp -i %s --dport %s -j DROP\n",
2285                       wanface, nvram_safe_get( "sshd_wanport" ) );
2286            save2file( "-A INPUT -p tcp -i %s --dport 22 -j DROP\n",
2287                       wanface );
2288            save2file( "-A INPUT -p tcp -i %s --dport 23 -j DROP\n",
2289                       wanface );
2290        }
2291#else
2292        if( !remotetelnet )
2293        {
2294            save2file( "-A INPUT -p tcp -i %s --dport 22 -j DROP\n",
2295                       wanface );
2296            save2file( "-A INPUT -p tcp -i %s --dport %s -j DROP\n", wanface,
2297                       nvram_safe_get( "telnet_wanport" ) );
2298            save2file( "-A INPUT -p tcp -i %s --dport 23 -j DROP\n",
2299                       wanface );
2300        }
2301#endif
2302
2303        filter_forward(  );
2304
2305    }
2306    else
2307    {
2308
2309        filter_input(  );
2310        filter_output(  );
2311        filter_forward(  );
2312    }
2313
2314    /*
2315     * logaccept chain
2316     */
2317#ifdef FLOOD_PROTECT
2318    if( ( nvram_match( "log_enable", "1" ) )
2319        && ( nvram_match( "log_accepted", "1" ) ) )
2320        save2file
2321            ( "-A logaccept -i %s -m state --state NEW -m limit --limit %d -j LOG "
2322              "--log-prefix \"FLOOD \" --log-tcp-sequence --log-tcp-options --log-ip-options\n",
2323              wanface, FLOOD_RATE );
2324    save2file
2325        ( "-A logaccept -i %s -m state --state NEW -m limit --limit %d -j DROP\n",
2326          wanface, FLOOD_RATE );
2327#endif
2328    if( ( nvram_match( "log_enable", "1" ) )
2329        && ( nvram_match( "log_accepted", "1" ) ) )
2330        save2file
2331            ( "-A logaccept -m state --state NEW -j LOG --log-prefix \"ACCEPT \" "
2332              "--log-tcp-sequence --log-tcp-options --log-ip-options\n" );
2333    save2file( "-A logaccept -j ACCEPT\n" );
2334
2335    /*
2336     * logdrop chain
2337     */
2338    if( ( nvram_match( "log_enable", "1" ) )
2339        && ( nvram_match( "log_dropped", "1" ) ) )
2340        save2file
2341            ( "-A logdrop -m state --state NEW -j LOG --log-prefix \"DROP \" "
2342              "--log-tcp-sequence --log-tcp-options --log-ip-options\n"
2343              "-A logdrop -m state --state INVALID -j LOG --log-prefix \"DROP \" "
2344              "--log-tcp-sequence --log-tcp-options --log-ip-options\n" );
2345    save2file( "-A logdrop -j DROP\n" );
2346
2347    /*
2348     * logreject chain
2349     */
2350    if( ( nvram_match( "log_enable", "1" ) )
2351        && ( nvram_match( "log_rejected", "1" ) ) )
2352        save2file( "-A logreject -j LOG --log-prefix \"WEBDROP \" "
2353                   "--log-tcp-sequence --log-tcp-options --log-ip-options\n" );
2354    save2file
2355        ( "-A logreject -p tcp -m tcp -j REJECT --reject-with tcp-reset\n" );
2356
2357#ifdef FLOOD_PROTECT
2358    /*
2359     * limaccept chain
2360     */
2361    if( ( nvram_match( "log_enable", "1" ) )
2362        && ( nvram_match( "log_accepted", "1" ) ) )
2363        save2file
2364            ( "-A limaccept -i %s -m state --state NEW -m limit --limit %d -j LOG "
2365              "--log-prefix \"FLOOD \" --log-tcp-sequence --log-tcp-options --log-ip-options\n" );
2366    save2file
2367        ( "-A limaccept -i %s -m state --state NEW -m limit --limit %d -j DROP\n"
2368          "-A limaccept -j ACCEPT\n", wanface, FLOOD_RATE, wanface,
2369          FLOOD_RATE );
2370#endif
2371#ifdef HAVE_CHILLI
2372    /*
2373     * DD-WRT BrainSlayer CHILLI Security Fix
2374     */
2375    if( nvram_match( "chilli_enable", "1" ) )
2376    {
2377        save2file( "-A FORWARD -i br0 -j DROP\n" );
2378        save2file( "-A FORWARD -o br0 -j DROP\n" );
2379        // if (nvram_match("chilli_nowifibridge","1"))
2380        // {
2381        // save2file("-t nat -A PREROUTING -s 192.168.182.0/24 -d
2382        // 192.168.182.1 -j DROP");
2383        // }
2384    }
2385    /*
2386     * DD-WRT end
2387     */
2388#endif
2389
2390    save2file( "COMMIT\n" );
2391}
2392
2393static void create_restore_file( void )
2394{
2395    mangle_table(  );
2396    nat_table(  );
2397    filter_table(  );
2398}
2399
2400char *ftp_ext[] = { "ftp-data", NULL };
2401
2402struct application_based_qos_t
2403{
2404    char *port;
2405    char *nv_name;
2406    char *user_port;
2407    char **port_ext;
2408} application_based_qos[] =
2409{
2410    /*
2411     * {"ftp", "sel_qosftp", NULL, ftp_ext}, {"http", "sel_qoshttp",},
2412     * {"telnet", "sel_qostelnet",}, {"smtp", "sel_qossmtp",}, {"pop3",
2413     * "sel_qospop3",},
2414     */
2415    {
2416    NULL, "sel_qosport1", "qos_appport1",},
2417    {
2418    NULL, "sel_qosport2", "qos_appport2",},
2419    {
2420    NULL, "sel_qosport3", "qos_appport3",},
2421    {
2422    NULL, "sel_qosport4", "qos_appport4",},
2423    {
2424    NULL, "sel_qosport5", "qos_appport5",},
2425    {
2426    NULL, "sel_qosport6", "qos_appport6",},
2427    {
2428    NULL, "sel_qosport7", "qos_appport7",},
2429    {
2430    NULL, "sel_qosport8", "qos_appport8",}
2431};
2432
2433struct game_port_t
2434{
2435    /*
2436     * unsigned **single_port; struct range_port_t *range_port;
2437     */
2438    char **single_port;
2439    char **range_port;
2440};
2441
2442/*
2443 * struct range_port_t cs_tcp_range[]={{27030,27039}, {0,0}}; unsigned
2444 * cs_udp_single[]={1200, 0}; struct range_port_t
2445 * cs_udp_range[]={{27000,27015}, {0,0}};
2446 *
2447 * unsigned aoe_single[]={6073, 0}; struct range_port_t
2448 * aoe_range[]={{2302,2400}, {0,0}};
2449 *
2450 * unsigned diablo_tcp_single[]={4000, 0}; struct range_port_t
2451 * diablo_range[]={{6112,6119}, {0,0}};
2452 *
2453 * unsigned everquest_single[]={7000, 0}; struct range_port_t
2454 * everquest_range[]={{1024,6000}, {0,0}};
2455 *
2456 * unsigned halflife_tcp_single[]={6003, 7002, 0}; unsigned
2457 * halflife_udp_single[]={27005, 27010, 27011, 27015, 0};
2458 *
2459 * unsigned quake2_single[]={27910, 0};
2460 *
2461 * unsigned quake3_single[]={27660, 0};
2462 *
2463 * unsigned RCW_udp_single[]={27950, 27960, 27965, 27952, 0};
2464 *
2465 * unsigned unreal_single[]={8080, 27900, 0}; struct range_port_t
2466 * unreal_range[]={{7777, 7783}, {0,0}};
2467 */
2468
2469char *cs_tcp_range[] = { "27030:27039", NULL };
2470char *cs_udp_single[] = { "1200", NULL };
2471char *cs_udp_range[] = { "27000:27015", NULL };
2472
2473char *aoe_single[] = { "6073", NULL };
2474char *aoe_range[] = { "2302:2400", NULL };
2475
2476char *diablo_tcp_single[] = { "4000", NULL };
2477char *diablo_range[] = { "6112:6119", NULL };
2478
2479char *everquest_single[] = { "7000", NULL };
2480char *everquest_range[] = { "1024:6000", NULL };
2481
2482char *halflife_tcp_single[] = { "6003", "7002", NULL };
2483char *halflife_udp_single[] = { "27005", "27010", "27011", "27015", NULL };
2484
2485char *quake2_single[] = { "27910", NULL };
2486
2487char *quake3_single[] = { "27660", NULL };
2488
2489char *RCW_udp_single[] = { "27950", "27960", "27965", "27952", NULL };
2490
2491char *unreal_single[] = { "8080", "27900", NULL };
2492char *unreal_range[] = { "7777:7783", NULL };
2493
2494struct game_port_t cs_port_tcp = {
2495    // {NULL}, {{27030, 27039}, NULL}
2496    NULL, cs_tcp_range
2497};
2498
2499struct game_port_t cs_port_udp = {
2500    // {1200, NULL}, {{27000, 27015}, NULL}
2501    cs_udp_single, cs_udp_range
2502};
2503
2504struct game_port_t aoe_port = {
2505    // {6073, NULL}, {{2302, 2400}, NULL}
2506    aoe_single, aoe_range
2507};
2508
2509struct game_port_t diablo_port_tcp = {
2510    // {4000, NULL}, {{6112, 6119}, NULL}
2511    diablo_tcp_single, diablo_range
2512};
2513
2514struct game_port_t diablo_port_udp = {
2515    // {NULL}, {{6112, 6119}, NULL}
2516    NULL, diablo_range
2517};
2518
2519struct game_port_t everquest_port = {
2520    // {7000, NULL}, {{1024, 6000}, NULL}
2521    everquest_single, everquest_range
2522};
2523
2524struct game_port_t halflife_port_tcp = {
2525    // {6003, 7002, NULL}, {NULL}
2526    halflife_tcp_single, NULL
2527};
2528
2529struct game_port_t halflife_port_udp = {
2530    // {27005, 27010, 27011, 27015, NULL}, {NULL}
2531    halflife_udp_single, NULL
2532};
2533
2534struct game_port_t quake2_port = {
2535    // {27910, NULL}, {NULL}
2536    quake2_single, NULL
2537};
2538
2539struct game_port_t quake3_port = {
2540    // {27660, NULL}, {NULL}
2541    quake3_single, NULL
2542};
2543
2544struct game_port_t RCW_port_tcp = {
2545    // {NULL}, {NULL}
2546    NULL, NULL
2547};
2548
2549struct game_port_t RCW_port_udp = {
2550    // {27950, 27960, 27965,27952, NULL}, {NULL}
2551    RCW_udp_single, NULL
2552};
2553
2554struct game_port_t unreal_port = {
2555    // {8080, 27900, NULL}, {{7777, 7783}, NULL}
2556    unreal_single, unreal_range
2557};
2558
2559struct gaming_app_t
2560{
2561    char *name;
2562    struct game_port_t *tcp_port;
2563    struct game_port_t *udp_port;
2564} gamming_app_table[] =
2565{
2566    {
2567    "Counter Strike", &cs_port_tcp, &cs_port_udp},
2568    {
2569    "Age of Empires", &aoe_port, &aoe_port},
2570    {
2571    "Diablo II(Blizzard Battle.net)", &diablo_port_tcp, &diablo_port_udp},
2572    {
2573    "Everquest", &everquest_port, &everquest_port},
2574    {
2575    "Half life", &halflife_port_tcp, &halflife_port_udp},
2576    {
2577    "Quake2", &quake2_port, &quake2_port},
2578    {
2579    "Quake3", &quake3_port, &quake3_port},
2580    {
2581    "Return to Castle Wolfenstein", &RCW_port_tcp, &RCW_port_udp},
2582    {
2583    "Unreal Tournament", &unreal_port, &unreal_port}
2584};
2585
2586char *dscp_class_map[] = {
2587    "BE",
2588    "AF31",
2589    "AF11",
2590    "EF",
2591};
2592
2593enum
2594{ TCP, UDP };
2595
2596void app_savefile( char *port, int direction, int protocol, int app_prio )
2597{
2598    char *interface = direction ? wanface : lanface;
2599    char *position = direction ? "--source-port" : "--destination-port";
2600
2601    if( protocol == TCP )
2602    {
2603        save2file
2604            ( "-I PREROUTING -i %s -p tcp %s %s -j DSCP --set-dscp-class %s\n",
2605              interface, position, port, dscp_class_map[app_prio] );
2606    }
2607    else if( protocol == UDP )
2608    {
2609        char *argv[] =
2610            { "iptables", "-I", "PREROUTING", "-t", "mangle", "-i", interface,
2611            "-p", "udp", position, port, "-j", "DSCP", "--set-dscp-class",
2612            dscp_class_map[app_prio], NULL
2613        };
2614        pid_t pid;
2615
2616        _evalpid( argv, NULL, 0, &pid );
2617    }
2618}
2619
2620void
2621appitem_savefile( struct application_based_qos_t app_item, char *port,
2622                  int direction, int protocol, int app_prio )
2623{
2624    int i = 0;
2625
2626    app_savefile( port, direction, protocol, app_prio );
2627
2628    if( app_item.port_ext )
2629        for( i = 0; ( port = app_item.port_ext[i] ); i++ )
2630            app_savefile( port, direction, protocol, app_prio );
2631}
2632
2633int check_app_port( char *port, char *validated_port )
2634{
2635    char *dash_index;
2636    int valid_port = 0;
2637
2638    strcpy( validated_port, port );
2639
2640    if( !strcmp( validated_port, "" ) )
2641        return valid_port;
2642
2643    dash_index = strchr( validated_port, '-' );
2644
2645    if( dash_index )
2646    {
2647        validated_port[dash_index - validated_port] = ':';
2648        valid_port = 1;
2649    }
2650    else if( atoi( port ) )
2651        valid_port = 1;
2652
2653    return valid_port;
2654}
2655
2656void app_udp_settable( void )
2657{
2658    if( !strcmp( nvram_safe_get( "QoS" ), "1" ) )
2659    {
2660        int i = 0;
2661
2662        /*
2663         * char *port = NULL; struct application_based_qos_t app_item;
2664         *
2665         * for (i = 0; i<STRUCT_LEN(application_based_qos); i++) { int
2666         * app_prio = 0; char validated_port[12];
2667         *
2668         * app_item = application_based_qos[i]; app_prio =
2669         * atoi(nvram_safe_get(app_item.nv_name));
2670         *
2671         * //if (!strcmp(nvram_safe_get(app_item.nv_name), "1")) if
2672         * (app_prio) { if (!(port = app_item.port)) { port =
2673         * nvram_safe_get(app_item.user_port);
2674         *
2675         * if (!check_app_port(port, validated_port)) continue;
2676         *
2677         * port = validated_port; }
2678         *
2679         * appitem_savefile(app_item, port, 0, UDP, app_prio);//0:LAN 2 WAN
2680         * #if 0 //#ifdef QDISC_PRIO appitem_savefile(app_item, port, 1, UDP,
2681         * app_prio);//1:WAN 2 LAN #endif } }
2682         */
2683        cprintf( "enable game\n" );
2684        if( nvram_match( "enable_game", "1" ) )
2685        {
2686            for( i = 0; i < STRUCT_LEN( gamming_app_table ); i++ )
2687            {
2688                int j = 0;
2689                struct game_port_t *udp_item = gamming_app_table[i].udp_port;
2690
2691                cprintf( "count %d of %d\n", i,
2692                         STRUCT_LEN( gamming_app_table ) );
2693                if( udp_item->single_port )
2694                {
2695                    for( j = 0; udp_item->single_port[j]; j++ )
2696                    {
2697                        app_savefile( udp_item->single_port[j], 0, UDP, 3 );
2698
2699                    }
2700                }
2701
2702                if( udp_item->range_port )
2703                {
2704                    for( j = 0; udp_item->range_port[j]; j++ )
2705                    {
2706                        app_savefile( udp_item->range_port[j], 0, UDP, 3 );
2707
2708                    }
2709
2710                }
2711            }
2712
2713        }
2714
2715    }
2716}
2717
2718int isregistered_real( void );
2719
2720
2721#ifdef DEVELOPE_ENV
2722int main( void )
2723#else
2724void start_firewall( void )
2725#endif
2726{
2727    DIR *dir;
2728    struct dirent *file;
2729    FILE *fp;
2730    char name[NAME_MAX];
2731    struct stat statbuff;
2732    int log_level = 0;
2733
2734    /*
2735     * Block obviously spoofed IP addresses
2736     */
2737    DEBUG( "start firewall()...........\n" );
2738    if( !( dir = opendir( "/proc/sys/net/ipv4/conf" ) ) )
2739        perror( "/proc/sys/net/ipv4/conf" );
2740    while( dir && ( file = readdir( dir ) ) )
2741    {
2742        if( strncmp( file->d_name, ".", NAME_MAX ) != 0 &&
2743            strncmp( file->d_name, "..", NAME_MAX ) != 0 )
2744        {
2745            sprintf( name, "/proc/sys/net/ipv4/conf/%s/rp_filter",
2746                     file->d_name );
2747            if( !( fp = fopen( name, "r+" ) ) )
2748            {
2749                perror( name );
2750                break;
2751            }
2752            fputc( '1', fp );
2753            fclose( fp );
2754        }
2755    }
2756    closedir( dir );
2757    /*
2758     * Determine LOG level
2759     */
2760    DEBUG( "start firewall()........1\n" );
2761    log_level = atoi( nvram_safe_get( "log_level" ) );
2762    // sprintf(log_drop, "%s", (log_level & 1) ? "logdrop" : "DROP");
2763    // sprintf(log_accept, "%s", (log_level & 2) ? "logaccept" : TARG_PASS);
2764    // sprintf(log_reject, "%s", (log_level & 1) ? "logreject" : TARG_RST);
2765    if( log_level >= 1 )
2766        sprintf( log_drop, "%s", "logdrop" );
2767    else
2768        sprintf( log_drop, "%s", "DROP" );
2769    if( log_level >= 2 )
2770        sprintf( log_accept, "%s", "logaccept" );
2771    else
2772        sprintf( log_accept, "%s", TARG_PASS );
2773    if( log_level >= 1 )
2774        sprintf( log_reject, "%s", "logreject" );
2775    else
2776        sprintf( log_reject, "%s", TARG_RST );
2777
2778    /*
2779     * Get NVRAM value into globle variable
2780     */
2781    DEBUG( "start firewall()........2\n" );
2782    strncpy( lanface, nvram_safe_get( "lan_ifname" ), IFNAMSIZ );
2783    strncpy( wanface, get_wan_face(  ), IFNAMSIZ );
2784
2785    if( nvram_match( "wan_proto", "pptp" ) )
2786        strncpy( wanaddr, nvram_safe_get( "pptp_get_ip" ),
2787                 sizeof( wanaddr ) );
2788    else if( nvram_match( "wan_proto", "l2tp" ) )
2789        strncpy( wanaddr, nvram_safe_get( "l2tp_get_ip" ),
2790                 sizeof( wanaddr ) );
2791    else
2792        strncpy( wanaddr, nvram_safe_get( "wan_ipaddr" ), sizeof( wanaddr ) );
2793
2794    ip2cclass( nvram_safe_get( "lan_ipaddr" ), &lan_cclass[0],
2795               sizeof( lan_cclass ) );
2796
2797    /*
2798     * Run Webfilter ?
2799     */
2800    webfilter = 0;              /* Reset, clear the late setting */
2801    if( nvram_match( "block_cookie", "1" ) )
2802        webfilter |= BLK_COOKIE;
2803    if( nvram_match( "block_java", "1" ) )
2804        webfilter |= BLK_JAVA;
2805    if( nvram_match( "block_activex", "1" ) )
2806        webfilter |= BLK_ACTIVE;
2807    if( nvram_match( "block_proxy", "1" ) )
2808        webfilter |= BLK_PROXY;
2809
2810    /*
2811     * Run DMZ forwarding ?
2812     */
2813    if( nvram_match( "wk_mode", "gateway" )
2814        && nvram_match( "dmz_enable", "1" )
2815        && nvram_invmatch( "dmz_ipaddr", "" )
2816        && nvram_invmatch( "dmz_ipaddr", "0" ) )
2817        dmzenable = 1;
2818    else
2819        dmzenable = 0;
2820
2821    /*
2822     * Remote Web GUI management
2823     */
2824    if( nvram_match( "remote_management", "1" ) &&
2825        nvram_invmatch( "http_wanport", "" ) &&
2826        nvram_invmatch( "http_wanport", "0" ) )
2827        remotemanage = 1;
2828    else
2829        remotemanage = 0;
2830
2831#ifdef HAVE_SSHD
2832    /*
2833     * Remote ssh management : Botho 03-05-2006
2834     */
2835    if( nvram_match( "remote_mgt_ssh", "1" ) &&
2836        nvram_invmatch( "sshd_wanport", "" ) &&
2837        nvram_invmatch( "sshd_wanport", "0" ) &&
2838        nvram_match( "sshd_enable", "1" ) )
2839        remotessh = 1;
2840    else
2841        remotessh = 0;
2842#else
2843    /*
2844     * Remote telnet management
2845     */
2846    if( nvram_match( "remote_mgt_telnet", "1" ) &&
2847        nvram_invmatch( "telnet_wanport", "" ) &&
2848        nvram_invmatch( "telnet_wanport", "0" ) &&
2849        nvram_match( "telnetd_enable", "1" ) )
2850        remotetelnet = 1;
2851    else
2852        remotetelnet = 0;
2853#endif
2854
2855#ifdef HAVE_HTTPS
2856    if( nvram_match( "remote_mgt_https", "1" ) )
2857        web_lanport = HTTPS_PORT;
2858    else
2859#endif
2860        web_lanport = atoi( nvram_safe_get( "http_lanport" ) ) ? : HTTP_PORT;
2861
2862    /*
2863     * Remove existent file
2864     */
2865    DEBUG( "start firewall()........3\n" );
2866    if( stat( IPTABLES_SAVE_FILE, &statbuff ) == 0 )
2867        unlink( IPTABLES_SAVE_FILE );
2868
2869    /*
2870     * Create file for iptables-restore
2871     */
2872    DEBUG( "start firewall()........4\n" );
2873    create_restore_file(  );
2874
2875#ifndef DEVELOPE_ENV
2876    /*
2877     * Insert the rules into kernel
2878     */
2879    DEBUG( "start firewall()........5\n" );
2880    eval( "iptables-restore", IPTABLES_SAVE_FILE );
2881    cprintf( "app udp settable\n" );
2882    app_udp_settable(  );
2883
2884    // unlink(IPTABLES_SAVE_FILE);
2885#endif
2886
2887    /*
2888     * begin Sveasoft add
2889     */
2890    /*
2891     * run rc_firewall script
2892     */
2893    cprintf( "Exec RC Filewall\n" );
2894#ifdef HAVE_REGISTER
2895    if( isregistered_real(  ) )
2896#endif
2897        if( create_rc_file( RC_FIREWALL ) == 0 )
2898        {
2899            setenv( "PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1 );
2900            system2( "/tmp/.rc_firewall" );
2901        }
2902    runStartup( "/etc/config", ".firewall" );
2903
2904    cprintf( "Ready\n" );
2905    /*
2906     * end Sveasoft add
2907     */
2908
2909    // run wanup scripts
2910    start_wanup(  );
2911
2912    /*
2913     * Turn on the DMZ-LED, if enabled.(from service.c)
2914     */
2915    cprintf( "enable DMZ\n" );
2916    if( dmzenable )
2917        diag_led( DMZ, START_LED );
2918    else
2919        diag_led( DMZ, STOP_LED );
2920    cprintf( "done" );
2921#ifdef XBOX_SUPPORT
2922#ifdef HAVE_RB500
2923    if( ( fp =
2924          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
2925                 "r+" ) ) )
2926    {
2927        fprintf( fp, "%d", 65 );
2928        fclose( fp );
2929    }
2930    else
2931        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
2932#elif HAVE_XSCALE
2933    if( ( fp =
2934          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
2935                 "r+" ) ) )
2936    {
2937        fprintf( fp, "%d", 65 );
2938        fclose( fp );
2939    }
2940    else
2941        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
2942#elif HAVE_MAGICBOX
2943    if( ( fp =
2944          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
2945                 "r+" ) ) )
2946    {
2947        fprintf( fp, "%d", 65 );
2948        fclose( fp );
2949    }
2950    else
2951        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
2952#elif HAVE_FONERA
2953    if( ( fp =
2954          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
2955                 "r+" ) ) )
2956    {
2957        fprintf( fp, "%d", 65 );
2958        fclose( fp );
2959    }
2960    else
2961        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
2962#elif HAVE_RT2880
2963    if( ( fp =
2964          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
2965                 "r+" ) ) )
2966    {
2967        fprintf( fp, "%d", 65 );
2968        fclose( fp );
2969    }
2970    else
2971        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
2972#elif HAVE_LS2
2973    if( ( fp =
2974          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
2975                 "r+" ) ) )
2976    {
2977        fprintf( fp, "%d", 65 );
2978        fclose( fp );
2979    }
2980    else
2981        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
2982#elif HAVE_LS5
2983    if( ( fp =
2984          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
2985                 "r+" ) ) )
2986    {
2987        fprintf( fp, "%d", 65 );
2988        fclose( fp );
2989    }
2990    else
2991        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
2992#elif HAVE_WHRAG108
2993    if( ( fp =
2994          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
2995                 "r+" ) ) )
2996    {
2997        fprintf( fp, "%d", 65 );
2998        fclose( fp );
2999    }
3000    else
3001        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3002#elif HAVE_LSX
3003    if( ( fp =
3004          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
3005                 "r+" ) ) )
3006    {
3007        fprintf( fp, "%d", 65 );
3008        fclose( fp );
3009    }
3010    else
3011        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3012#elif HAVE_DANUBE
3013    if( ( fp =
3014          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
3015                 "r+" ) ) )
3016    {
3017        fprintf( fp, "%d", 65 );
3018        fclose( fp );
3019    }
3020    else
3021        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3022#elif HAVE_STORM
3023    if( ( fp =
3024          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
3025                 "r+" ) ) )
3026    {
3027        fprintf( fp, "%d", 65 );
3028        fclose( fp );
3029    }
3030    else
3031        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3032#elif HAVE_ADM5120
3033    if( ( fp =
3034          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
3035                 "r+" ) ) )
3036    {
3037        fprintf( fp, "%d", 65 );
3038        fclose( fp );
3039    }
3040    else
3041        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3042#elif HAVE_PB42
3043    if( ( fp =
3044          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
3045                 "r+" ) ) )
3046    {
3047        fprintf( fp, "%d", 65 );
3048        fclose( fp );
3049    }
3050    else
3051        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3052#elif HAVE_TW6600
3053    if( ( fp =
3054          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
3055                 "r+" ) ) )
3056    {
3057        fprintf( fp, "%d", 65 );
3058        fclose( fp );
3059    }
3060    else
3061        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3062#elif HAVE_CA8
3063    if( ( fp =
3064          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
3065                 "r+" ) ) )
3066    {
3067        fprintf( fp, "%d", 65 );
3068        fclose( fp );
3069    }
3070    else
3071        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3072#elif HAVE_X86
3073    if( ( fp =
3074          fopen( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout",
3075                 "r+" ) ) )
3076    {
3077        fprintf( fp, "%d", 65 );
3078        fclose( fp );
3079    }
3080    else
3081        perror( "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout" );
3082#else
3083    if( ( fp =
3084          fopen( "/proc/sys/net/ipv4/ip_conntrack_udp_timeouts", "r+" ) ) )
3085    {
3086        fprintf( fp, "%d %d", 65, 180 );
3087        fclose( fp );
3088    }
3089    else
3090        perror( "/proc/sys/net/ipv4/ip_conntrack_udp_timeouts" );
3091#endif
3092#endif
3093    cprintf( "Start firewall\n" );
3094    /*
3095     * We don't forward packet until those policies are set.
3096     */
3097    DEBUG( "start firewall()........6\n" );
3098    if( ( fp = fopen( "/proc/sys/net/ipv4/ip_forward", "r+" ) ) )
3099    {
3100        fputc( '1', fp );
3101        fclose( fp );
3102    }
3103    else
3104        perror( "/proc/sys/net/ipv4/ip_forward" );
3105    cprintf( "start ipv6\n" );
3106    if( nvram_match( "ipv6_enable", "1" ) )
3107    {
3108
3109        if( ( fp = fopen( "/proc/sys/net/ipv6/conf/all/forwarding", "r+" ) ) )
3110        {
3111            fputc( '1', fp );
3112            fclose( fp );
3113        }
3114        else
3115            perror( "/proc/sys/net/ipv6/conf/all/forwarding" );
3116    }
3117
3118#ifdef HAVE_WIFIDOG
3119    stop_wifidog(  );
3120    start_wifidog(  );
3121#endif
3122    cprintf( "ready" );
3123
3124    cprintf( "done\n" );
3125    return 0;
3126}
3127
3128void stop_firewall( void )
3129{
3130    stop_anchorfree(  );
3131    /*
3132     * Make sure the DMZ-LED is off (from service.c)
3133     */
3134    diag_led( DMZ, STOP_LED );
3135#ifdef HAVE_GGEW
3136    char *wordlist = nvram_safe_get( "ral" );
3137    char var[256], *next;
3138
3139    foreach( var, wordlist, next )
3140    {
3141        sysprintf( "iptables -D INPUT -s %s -j ACCEPT", var );
3142    }
3143#endif
3144    char num[32];
3145    int i;
3146
3147    for( i = 0; i < 10; i++ )
3148    {
3149        eval( "iptables", "-F", "lan2wan" );
3150        sprintf( num, "grp_%d", i );
3151        eval( "iptables", "-F", num );
3152        sprintf( num, "advgrp_%d", i );
3153        eval( "iptables", "-F", num );
3154    }
3155    rmmod( "ipt_webstr" );
3156    rmmod( "ipt_layer7" );
3157    rmmod( "ipt_ipp2p" );
3158    if( nvram_invmatch( "apd_enable", "0" ) )
3159    {
3160        rmmod( "ipt_mark" );
3161        rmmod( "xt_mark" );
3162    }
3163    if( nvram_invmatch( "apd_enable", "0" ) )
3164    {
3165        rmmod( "ipt_mac" );
3166        rmmod( "xt_mac" );
3167    }
3168    cprintf( "done\n" );
3169    return 0;
3170}
3171
3172/*
3173 * PARAM - seq : Seqence number.
3174 *
3175 * RETURN - 0 : It's not in time.
3176 *                      1 : in time and anytime
3177 *                      2 : in time
3178 */
3179int if_tod_intime( int seq )
3180{
3181    char *todvalue;
3182    int sched = 0, allday = 0;
3183    int hr_st, hr_end;          /* hour */
3184    int mi_st, mi_end;          /* minute */
3185    char wday[128];
3186    int intime = 0;
3187
3188    /*
3189     * Get the NVRAM data
3190     */
3191    todvalue = nvram_nget( "filter_tod%d", seq );
3192
3193    DEBUG( "%s: %s\n", todname, todvalue );
3194    if( strcmp( todvalue, "" ) == 0 )
3195        return 0;
3196
3197    /*
3198     * Is it anytime or scheduled ?
3199     */
3200    if( strcmp( todvalue, "0:0 23:59 0-0" ) == 0 ||
3201        strcmp( todvalue, "0:0 23:59 0-6" ) == 0 )
3202    {
3203        sched = 0;
3204    }
3205    else
3206    {
3207        sched = 1;
3208        if( strcmp( todvalue, "0:0 23:59" ) == 0 )
3209            allday = 1;
3210        if( sscanf( todvalue, "%d:%d %d:%d %s", &hr_st, &mi_st,
3211                    &hr_end, &mi_end, wday ) != 5 )
3212            return 0;           /* error format */
3213    }
3214
3215    DEBUG( "sched=%d, allday=%d\n", sched, allday );
3216
3217    /*
3218     * Anytime
3219     */
3220    if( !sched )
3221        return 1;
3222
3223    /*
3224     * Scheduled
3225     */
3226    if( allday )
3227    {                           /* 24-hour, but not everyday */
3228
3229        if( match_wday( wday ) )
3230            intime = 1;
3231    }
3232    else
3233    {                           /* Nither 24-hour, nor everyday */
3234
3235        if( match_wday( wday )
3236            && match_hrmin( hr_st, mi_st, hr_end, mi_end ) )
3237            intime = 1;
3238    }
3239    DEBUG( "intime=%d\n", intime );
3240
3241    /*
3242     * Would it be enabled now ?
3243     */
3244    if( intime )
3245        return 2;
3246
3247    return 0;
3248}
Note: See TracBrowser for help on using the repository browser.