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

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

still alot todo

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