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

Last change on this file since 10953 was 10953, checked in by eko, 5 years ago

typo

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