source: src/router/httpd/validate/validators.c @ 10965

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

more general validator, so it can be reused for e.g. DMZ ....

File size: 87.4 KB
Line 
1
2#define VALIDSOURCE 1
3
4#ifdef WEBS
5#include <webs.h>
6#include <uemf.h>
7#include <ej.h>
8#else /* !WEBS */
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <ctype.h>
13#include <unistd.h>
14#include <limits.h>
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <arpa/inet.h>
20#include <httpd.h>
21#include <errno.h>
22#endif /* WEBS */
23
24#include <proto/ethernet.h>
25#include <fcntl.h>
26#include <signal.h>
27#include <time.h>
28#include <sys/klog.h>
29#include <sys/wait.h>
30#include <cyutils.h>
31#include <support.h>
32#include <cy_conf.h>
33// #ifdef EZC_SUPPORT
34#include <ezc.h>
35// #endif
36#include <broadcom.h>
37#include <wlutils.h>
38#include <netdb.h>
39#include <utils.h>
40
41#ifdef FILTER_DEBUG
42extern FILE *debout;
43
44#define D(a) fprintf(debout,"%s\n",a); fflush(debout);
45#else
46#define D(a)
47#endif
48
49void ( *do_ej_buffer ) ( char *buffer, webs_t stream );
50int ( *httpd_filter_name ) ( char *old_name, char *new_name, size_t size,
51                             int type );
52char *( *websGetVar ) ( webs_t wp, char *var, char *d );
53int ( *websWrite ) ( webs_t wp, char *fmt, ... );
54struct wl_client_mac *wl_client_macs;
55
56void initWeb( struct Webenvironment *env )
57{
58    cprintf( "set websgetwar\n" );
59    websGetVar = env->PwebsGetVar;
60    httpd_filter_name = env->Phttpd_filter_name;
61    wl_client_macs = env->Pwl_client_macs;
62    websWrite = env->PwebsWrite;
63    do_ej_buffer = env->Pdo_ej_buffer;
64}
65
66/*
67 * Example: ISASCII("", 0); return true; ISASCII("", 1); return false;
68 * ISASCII("abc123", 1); return true;
69 */
70int ISASCII( char *value, int flag )
71{
72    int i, tag = TRUE;
73
74#if COUNTRY == JAPAN
75    return tag;                 // don't check for japan version
76#endif
77
78    if( !strcmp( value, "" ) )
79    {
80        if( flag )
81            return 0;           // null
82        else
83            return 1;
84    }
85
86    for( i = 0; *( value + i ); i++ )
87    {
88        if( !isascii( *( value + i ) ) )
89        {
90            tag = FALSE;
91            break;
92        }
93    }
94    return tag;
95}
96
97/*
98 * Example: legal_hwaddr("00:11:22:33:44:aB"); return true;
99 * legal_hwaddr("00:11:22:33:44:5"); return false;
100 * legal_hwaddr("00:11:22:33:44:HH"); return false;
101 */
102int legal_hwaddr( char *value )
103{
104    unsigned int hwaddr[6];
105    int tag = TRUE;
106    int i, count;
107
108    /*
109     * Check for bad, multicast, broadcast, or null address
110     */
111    for( i = 0, count = 0; *( value + i ); i++ )
112    {
113        if( *( value + i ) == ':' )
114        {
115            if( ( i + 1 ) % 3 != 0 )
116            {
117                tag = FALSE;
118                break;
119            }
120            count++;
121        }
122        else if( isxdigit( *( value + i ) ) )   /* one of 0 1 2 3 4 5 6 7 8 9
123                                                 * a b c d e f A B C D E F */
124            continue;
125        else
126        {
127            tag = FALSE;
128            break;
129        }
130    }
131
132    if( !tag || i != 17 || count != 5 ) /* must have 17's characters and 5's
133                                         * ':' */
134        tag = FALSE;
135    else if( sscanf( value, "%x:%x:%x:%x:%x:%x",
136                     &hwaddr[0], &hwaddr[1], &hwaddr[2],
137                     &hwaddr[3], &hwaddr[4], &hwaddr[5] ) != 6 )
138    {
139        // (hwaddr[0] & 1) || // the bit 7 is 1
140        // (hwaddr[0] & hwaddr[1] & hwaddr[2] & hwaddr[3] & hwaddr[4] &
141        // hwaddr[5]) == 0xff ){ // FF:FF:FF:FF:FF:FF
142        // (hwaddr[0] | hwaddr[1] | hwaddr[2] | hwaddr[3] | hwaddr[4] |
143        // hwaddr[5]) == 0x00){ // 00:00:00:00:00:00
144        tag = FALSE;
145    }
146    else
147        tag = TRUE;
148
149    return tag;
150}
151
152/*
153 * Example: 255.255.255.0 (111111111111111111111100000000) is a legal netmask
154 * 255.255.0.255 (111111111111110000000011111111) is an illegal netmask
155 */
156int legal_netmask( char *value )
157{
158    struct in_addr ipaddr;
159    int ip[4] = { 0, 0, 0, 0 };
160    int i, j;
161    int match0 = -1;
162    int match1 = -1;
163    int ret, tag;
164
165    ret = sscanf( value, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3] );
166
167    if( ret == 4 && inet_aton( value, &ipaddr ) )
168    {
169        for( i = 3; i >= 0; i-- )
170        {
171            for( j = 1; j <= 8; j++ )
172            {
173                if( ( ip[i] % 2 ) == 0 )
174                    match0 = ( 3 - i ) * 8 + j;
175                else if( ( ( ip[i] % 2 ) == 1 ) && match1 == -1 )
176                    match1 = ( 3 - i ) * 8 + j;
177                ip[i] = ip[i] / 2;
178            }
179        }
180    }
181
182    if( match0 >= match1 )
183        tag = FALSE;
184    else
185        tag = TRUE;
186
187    return tag;
188}
189
190/*
191 * Example: legal_ipaddr("192.168.1.1"); return true;
192 * legal_ipaddr("192.168.1.1111"); return false;
193 */
194int legal_ipaddr( char *value )
195{
196    struct in_addr ipaddr;
197    int ip[4];
198    int ret, tag;
199
200    ret = sscanf( value, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3] );
201
202    if( ret != 4 || !inet_aton( value, &ipaddr ) )
203        tag = FALSE;
204    else
205        tag = TRUE;
206
207    return tag;
208}
209
210int valid_wep_key( webs_t wp, char *value, struct variable *v )
211{
212    int i;
213
214    switch ( strlen( value ) )
215    {
216        case 5:
217        case 13:
218            for( i = 0; *( value + i ); i++ )
219            {
220                if( isascii( *( value + i ) ) )
221                {
222                    continue;
223                }
224                else
225                {
226                    websDebugWrite( wp,
227                                    "Invalid <b>%s</b> %s: must be ascii code<br>",
228                                    v->longname, value );
229                    return FALSE;
230                }
231            }
232            break;
233        case 10:
234        case 26:
235            for( i = 0; *( value + i ); i++ )
236            {
237                if( isxdigit( *( value + i ) ) )
238                {               /* one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B
239                                 * C D E F */
240                    continue;
241                }
242                else
243                {
244                    websDebugWrite( wp,
245                                    "Invalid <b>%s</b> %s: must be hexadecimal digits<br>",
246                                    v->longname, value );
247                    return FALSE;
248                }
249            }
250            break;
251
252        default:
253            websDebugWrite( wp,
254                            "Invalid <b>%s</b>: must be 5 or 13 ASCII characters or 10 or 26 hexadecimal digits<br>",
255                            v->longname );
256            return FALSE;
257
258    }
259
260    /*
261     * for(i=0 ; *(value+i) ; i++){ if(isxdigit(*(value+i))){ continue; }
262     * else{ websDebugWrite(wp, "Invalid <b>%s</b> %s: must be hexadecimal
263     * digits<br>", v->longname, value); return FALSE; } }
264     *
265     * if (i != length) { websDebugWrite(wp, "Invalid <b>%s</b> %s: must be
266     * %d characters<br>", v->longname, value,length); return FALSE; }
267     */
268    return TRUE;
269}
270
271void validate_statics( webs_t wp, char *value, struct variable *v )
272{
273
274    if( !sv_valid_statics( value ) )
275    {
276        websDebugWrite( wp,
277                        "Invalid <b>%s</b> %s: not a legal statics entry<br>",
278                        v->longname, value );
279        return;
280    }
281
282    nvram_set( v->name, value );
283}
284
285int valid_netmask( webs_t wp, char *value, struct variable *v )
286{
287
288    if( !legal_netmask( value ) )
289    {
290        websDebugWrite( wp, "Invalid <b>%s</b> %s: not a legal netmask<br>",
291                        v->longname, value );
292        return FALSE;
293    }
294
295    return TRUE;
296
297}
298
299void validate_netmask( webs_t wp, char *value, struct variable *v )
300{
301    if( valid_netmask( wp, value, v ) )
302        nvram_set( v->name, value );
303}
304
305void validate_merge_netmask( webs_t wp, char *value, struct variable *v )
306{
307    char netmask[20], maskname[30];
308    char *mask;
309    int i;
310
311    strcpy( netmask, "" );
312    for( i = 0; i < 4; i++ )
313    {
314        snprintf( maskname, sizeof( maskname ), "%s_%d", v->name, i );
315        mask = websGetVar( wp, maskname, NULL );
316        if( mask )
317        {
318            strcat( netmask, mask );
319            if( i < 3 )
320                strcat( netmask, "." );
321        }
322        else
323        {
324            return;
325        }
326    }
327
328    if( valid_netmask( wp, netmask, v ) )
329        nvram_set( v->name, netmask );
330}
331
332// Added by Daniel(2004-07-29) for EZC
333// char webs_buf[5000];
334// int webs_buf_offset = 0;
335
336void
337validate_list( webs_t wp, char *value, struct variable *v,
338               int ( *valid ) ( webs_t, char *, struct variable * ) )
339{
340    int n, i;
341    char name[100];
342    char buf[1000] = "", *cur = buf;
343
344    n = atoi( value );
345
346    for( i = 0; i < n; i++ )
347    {
348        snprintf( name, sizeof( name ), "%s%d", v->name, i );
349        if( !( value = websGetVar( wp, name, NULL ) ) )
350            return;
351        if( !*value && v->nullok )
352            continue;
353        if( !valid( wp, value, v ) )
354            continue;
355        cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s",
356                         cur == buf ? "" : " ", value );
357    }
358    nvram_set( v->name, buf );
359
360}
361
362int valid_ipaddr( webs_t wp, char *value, struct variable *v )
363{
364    struct in_addr netaddr, netmask;
365
366    if( !legal_ipaddr( value ) )
367    {
368        websDebugWrite( wp, "Invalid <b>%s</b> %s: not an IP address<br>",
369                        v->longname, value );
370        return FALSE;
371    }
372
373    if( v->argv )
374    {
375        if( !strcmp( v->argv[0], "lan" ) )
376        {
377            if( *( value + strlen( value ) - 2 ) == '.'
378                && *( value + strlen( value ) - 1 ) == '0' )
379            {
380                websDebugWrite( wp,
381                                "Invalid <b>%s</b> %s: not an IP address<br>",
382                                v->longname, value );
383                return FALSE;
384            }
385        }
386
387        else if( !legal_ip_netmask( v->argv[0], v->argv[1], value ) )
388        {
389            ( void )inet_aton( nvram_safe_get( v->argv[0] ), &netaddr );
390            ( void )inet_aton( nvram_safe_get( v->argv[1] ), &netmask );
391            return FALSE;
392        }
393    }
394
395    return TRUE;
396}
397
398void validate_ipaddr( webs_t wp, char *value, struct variable *v )
399{
400    if( valid_ipaddr( wp, value, v ) )
401        nvram_set( v->name, value );
402}
403
404void validate_ipaddrs( webs_t wp, char *value, struct variable *v )
405{
406    validate_list( wp, value, v, valid_ipaddr );
407}
408
409int valid_merge_ip_4( webs_t wp, char *value, struct variable *v )
410{
411    char ipaddr[20];
412
413    if( atoi( value ) == 255 )
414    {
415        websDebugWrite( wp, "Invalid <b>%s</b> %s: out of range 0 - 254 <br>",
416                        v->longname, value );
417        return FALSE;
418    }
419
420    sprintf( ipaddr, "%d.%d.%d.%s",
421             get_single_ip( nvram_safe_get( "lan_ipaddr" ), 0 ),
422             get_single_ip( nvram_safe_get( "lan_ipaddr" ), 1 ),
423             get_single_ip( nvram_safe_get( "lan_ipaddr" ), 2 ), value );
424
425    if( !valid_ipaddr( wp, ipaddr, v ) )
426    {
427        return FALSE;
428    }
429
430    return TRUE;
431}
432
433/*
434 * static void validate_merge_ip_4 (webs_t wp, char *value, struct variable
435 * *v) { if (!strcmp (value, "")) { nvram_set (v->name, "0"); return; }
436 *
437 * if (valid_merge_ip_4 (wp, value, v)) nvram_set (v->name, value); }
438 */
439
440/*
441 * Example: lan_ipaddr_0 = 192 lan_ipaddr_1 = 168 lan_ipaddr_2 = 1
442 * lan_ipaddr_3 = 1 get_merge_ipaddr("lan_ipaddr", ipaddr); produces
443 * ipaddr="192.168.1.1"
444 */
445int get_merge_ipaddr( webs_t wp, char *name, char *ipaddr )
446{
447    char ipname[30];
448    int i;
449    char buf[50] = { 0 };
450    char *ip[4];
451    char *tmp;
452
453    // cprintf("ip addr\n");
454    strcpy( ipaddr, "" );
455    // cprintf("safe get\n");
456    char *ipa = nvram_safe_get( name );
457
458    // cprintf("strcpy\n");
459    if( ipa == NULL )
460        strcpy( buf, "0.0.0.0" );
461    else
462        strcpy( buf, ipa );
463    // cprintf("strsep\n");
464    char *b = ( char * )&buf;
465
466    ip[0] = strsep( &b, "." );
467    ip[1] = strsep( &b, "." );
468    ip[2] = strsep( &b, "." );
469    ip[3] = b;
470
471    for( i = 0; i < 4; i++ )
472    {
473        // cprintf("merge %s_%d\n",name,i);
474        snprintf( ipname, sizeof( ipname ), "%s_%d", name, i );
475        tmp = websGetVar( wp, ipname, ip[i] );
476        if( tmp == NULL )
477            return 0;
478        strcat( ipaddr, tmp );
479        if( i < 3 )
480            strcat( ipaddr, "." );
481    }
482
483    return 1;
484
485}
486
487void validate_merge_ipaddrs( webs_t wp, char *value, struct variable *v )
488{
489    char ipaddr[20];
490
491    get_merge_ipaddr( wp, v->name, ipaddr );
492
493    if( valid_ipaddr( wp, ipaddr, v ) )
494        nvram_set( v->name, ipaddr );
495}
496
497/*
498 * Example: wan_mac_0 = 00 wan_mac_1 = 11 wan_mac_2 = 22 wan_mac_3 = 33
499 * wan_mac_4 = 44 wan_mac_5 = 55 get_merge_mac("wan_mac",mac); produces
500 * mac="00:11:22:33:44:55"
501 */
502int get_merge_mac( webs_t wp, char *name, char *macaddr )
503{
504    char macname[30];
505    char *mac;
506    int i;
507
508    strcpy( macaddr, "" );
509
510    for( i = 0; i < 6; i++ )
511    {
512        snprintf( macname, sizeof( macname ), "%s_%d", name, i );
513        mac = websGetVar( wp, macname, "00" );
514        if( strlen( mac ) == 1 )
515            strcat( macaddr, "0" );
516        strcat( macaddr, mac );
517        if( i < 5 )
518            strcat( macaddr, ":" );
519    }
520
521    return 1;
522
523}
524
525void validate_merge_mac( webs_t wp, char *value, struct variable *v )
526{
527    char macaddr[20];
528
529    get_merge_mac( wp, v->name, macaddr );
530
531    if( valid_hwaddr( wp, macaddr, v ) )
532        nvram_set( v->name, macaddr );
533
534}
535
536void validate_dns( webs_t wp, char *value, struct variable *v )
537{
538    char buf[100] = "", *cur = buf;
539    char ipaddr[20], ipname[30];
540    char *ip;
541    int i, j;
542
543    for( j = 0; j < 3; j++ )
544    {
545        strcpy( ipaddr, "" );
546        for( i = 0; i < 4; i++ )
547        {
548            snprintf( ipname, sizeof( ipname ), "%s%d_%d", v->name, j, i );
549            ip = websGetVar( wp, ipname, NULL );
550            if( ip )
551            {
552                strcat( ipaddr, ip );
553                if( i < 3 )
554                    strcat( ipaddr, "." );
555            }
556            else
557                return;
558        }
559
560        if( !strcmp( ipaddr, "0.0.0.0" ) )
561            continue;
562        if( !valid_ipaddr( wp, ipaddr, v ) )
563            continue;
564        cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s",
565                         cur == buf ? "" : " ", ipaddr );
566    }
567    nvram_set( v->name, buf );
568
569    dns_to_resolv(  );
570}
571
572int valid_choice( webs_t wp, char *value, struct variable *v )
573{
574    char **choice;
575
576    for( choice = v->argv; *choice; choice++ )
577    {
578        if( !strcmp( value, *choice ) )
579            return TRUE;
580    }
581
582    websDebugWrite( wp, "Invalid <b>%s</b> %s: not one of ", v->longname,
583                    value );
584    for( choice = v->argv; *choice; choice++ )
585        websDebugWrite( wp, "%s%s", choice == v->argv ? "" : "/", *choice );
586    websDebugWrite( wp, "<br>" );
587    return FALSE;
588}
589
590void validate_choice( webs_t wp, char *value, struct variable *v )
591{
592    if( valid_choice( wp, value, v ) )
593        nvram_set( v->name, value );
594}
595
596void validate_noack( webs_t wp, char *value, struct variable *v )
597{
598    char *wme;
599
600    /*
601     * return if wme is not enabled
602     */
603    if( !( wme = websGetVar( wp, "wl_wme", NULL ) ) )
604        return;
605    else if( strcmp( wme, "on" ) )
606        return;
607
608    validate_choice( wp, value, v );
609}
610
611int valid_range( webs_t wp, char *value, struct variable *v )
612{
613    int n, start, end;
614
615    n = atoi( value );
616    start = atoi( v->argv[0] );
617    end = atoi( v->argv[1] );
618
619    if( !ISDIGIT( value, 1 ) || n < start || n > end )
620    {
621        websDebugWrite( wp, "Invalid <b>%s</b> %s: out of range %d-%d<br>",
622                        v->longname, value, start, end );
623        return FALSE;
624    }
625
626    return TRUE;
627}
628
629void validate_range( webs_t wp, char *value, struct variable *v )
630{
631    char buf[20];
632    int range;
633
634    if( valid_range( wp, value, v ) )
635    {
636        range = atoi( value );
637        snprintf( buf, sizeof( buf ), "%d", range );
638        nvram_set( v->name, buf );
639    }
640}
641
642int valid_name( webs_t wp, char *value, struct variable *v )
643{
644    int n, max;
645
646    n = atoi( value );
647
648    if( !ISASCII( value, 1 ) )
649    {
650        return FALSE;
651    }
652    if( v )
653    {
654        max = atoi( v->argv[0] );
655        if( strlen( value ) > max )
656        {
657            return FALSE;
658        }
659    }
660    return TRUE;
661}
662
663void validate_name( webs_t wp, char *value, struct variable *v )
664{
665    if( valid_name( wp, value, v ) )
666        nvram_set( v->name, value );
667}
668
669void validate_reboot( webs_t wp, char *value, struct variable *v )
670{
671    if( value && v )
672    {
673        nvram_set( v->name, value );
674        nvram_set( "do_reboot", "1" );
675    }
676}
677
678/*
679 * the html always show "d6nw5v1x2pc7st9m" so we must filter it.
680 */
681void validate_password( webs_t wp, char *value, struct variable *v )
682{
683    if( strcmp( value, TMP_PASSWD ) && valid_name( wp, value, v ) )
684    {
685        nvram_set( v->name, zencrypt( value ) );
686
687        system2( "/sbin/setpasswd" );
688    }
689}
690
691void validate_password2( webs_t wp, char *value, struct variable *v )
692{
693    if( strcmp( value, TMP_PASSWD ) && valid_name( wp, value, v ) )
694    {
695        nvram_set( v->name, value );
696    }
697}
698
699int valid_hwaddr( webs_t wp, char *value, struct variable *v )
700{
701    /*
702     * Make exception for "NOT IMPLELEMENTED" string
703     */
704    if( !strcmp( value, "NOT_IMPLEMENTED" ) )
705        return ( TRUE );
706
707    /*
708     * Check for bad, multicast, broadcast, or null address
709     */
710    if( !legal_hwaddr( value ) )
711    {
712        websDebugWrite( wp,
713                        "Invalid <b>%s</b> %s: not a legal MAC address<br>",
714                        v->longname, value );
715        return FALSE;
716    }
717
718    return TRUE;
719}
720
721void validate_hwaddr( webs_t wp, char *value, struct variable *v )
722{
723    if( valid_hwaddr( wp, value, v ) )
724        nvram_set( v->name, value );
725}
726
727void validate_hwaddrs( webs_t wp, char *value, struct variable *v )
728{
729    validate_list( wp, value, v, valid_hwaddr );
730}
731
732void validate_wan_ipaddr( webs_t wp, char *value, struct variable *v )
733{
734    char wan_ipaddr[20], wan_netmask[20], wan_gateway[20];
735    char *wan_proto = websGetVar( wp, "wan_proto", NULL );
736    char *pptp_use_dhcp = websGetVar( wp, "pptp_use_dhcp", NULL );
737
738    int pptp_skip_check = FALSE;
739
740    struct variable wan_variables[] = {
741        {NULL},
742        {NULL},
743      {argv:ARGV( "wan_ipaddr", "wan_netmask" )},
744    }, *which;
745
746    which = &wan_variables[0];
747
748    get_merge_ipaddr( wp, "wan_ipaddr", wan_ipaddr );
749    get_merge_ipaddr( wp, "wan_netmask", wan_netmask );
750    if( !strcmp( wan_proto, "pptp" ) )
751    {
752        nvram_set( "pptp_pass", "0" );  // disable pptp passthrough
753        get_merge_ipaddr( wp, "pptp_server_ip", wan_gateway );
754    }
755    else
756        get_merge_ipaddr( wp, "wan_gateway", wan_gateway );
757
758    if( !strcmp( wan_proto, "pptp" ) && !strcmp( "0.0.0.0", wan_ipaddr ) )
759    {                           // Sveasoft: allow 0.0.0.0 for pptp IP addr
760        pptp_skip_check = TRUE;
761        nvram_set( "pptp_use_dhcp", "1" );
762    }
763    else
764        nvram_set( "pptp_use_dhcp", "0" );
765
766    if( FALSE == pptp_skip_check
767        && !valid_ipaddr( wp, wan_ipaddr, &which[0] ) )
768        return;
769
770    nvram_set( "wan_ipaddr_buf", nvram_safe_get( "wan_ipaddr" ) );
771    nvram_set( "wan_ipaddr", wan_ipaddr );
772
773    if( FALSE == pptp_skip_check
774        && !valid_netmask( wp, wan_netmask, &which[1] ) )
775        return;
776
777    nvram_set( "wan_netmask", wan_netmask );
778
779    if( !valid_ipaddr( wp, wan_gateway, &which[2] )
780        && strcmp( wan_gateway, "0.0.0.0" ) )
781        return;
782
783    if( !strcmp( wan_proto, "pptp" ) )
784        nvram_set( "pptp_server_ip", wan_gateway );
785    else
786        nvram_set( "wan_gateway", wan_gateway );
787
788    if( !strcmp( wan_proto, "pptp" ) && !strcmp( pptp_use_dhcp, "1" ) )
789    {
790        if( !legal_ipaddr( wan_gateway ) )
791            return;
792        nvram_set( "pptp_server_ip", wan_gateway );
793        return;
794    }
795}
796
797#ifdef HAVE_PORTSETUP
798void validate_portsetup( webs_t wp, char *value, struct variable *v )
799{
800    char *next;
801    char var[64];
802    char eths[256];
803
804    getIfLists( eths, 256 );
805    foreach( var, eths, next )
806    {
807        char val[64];
808
809        sprintf( val, "%s_bridged", var );
810        char *bridged = websGetVar( wp, val, NULL );
811
812        if( bridged )
813            nvram_set( val, bridged );
814
815        sprintf( val, "%s_multicast", var );
816        char *multicast = websGetVar( wp, val, NULL );
817
818        if( multicast )
819            nvram_set( val, multicast );
820
821        if( bridged && strcmp( bridged, "0" ) == 0 )
822        {
823            sprintf( val, "%s_ipaddr", var );
824            char ipaddr[64];
825
826            if( get_merge_ipaddr( wp, val, ipaddr ) )
827                nvram_set( val, ipaddr );
828            sprintf( val, "%s_netmask", var );
829            char netmask[64];
830
831            if( get_merge_ipaddr( wp, val, netmask ) )
832                nvram_set( val, netmask );
833        }
834    }
835    next = websGetVar( wp, "wan_ifname", NULL );
836    if( next )
837    {
838        nvram_set( "wan_ifname2", next );
839    }
840}
841#endif
842int lan_ip_changed;
843
844void validate_lan_ipaddr( webs_t wp, char *value, struct variable *v )
845{
846    char lan_ipaddr[20], lan_netmask[20];
847
848    get_merge_ipaddr( wp, "lan_netmask", lan_netmask );
849    get_merge_ipaddr( wp, v->name, lan_ipaddr );
850
851    if( !valid_ipaddr( wp, lan_ipaddr, v ) )
852        return;
853
854    if( strcmp( nvram_safe_get( "lan_ipaddr" ), lan_ipaddr ) )
855    {
856        unlink( "/tmp/udhcpd.leases" );
857        unlink( "/jffs/udhcpd.leases" );
858        unlink( "/tmp/dnsmasq.leases" );
859        unlink( "/jffs/dnsmasq.leases" );
860    }
861    if( strcmp( nvram_safe_get( "lan_netmask" ), lan_netmask ) )
862    {
863        unlink( "/tmp/udhcpd.leases" );
864        unlink( "/jffs/udhcpd.leases" );
865        unlink( "/tmp/dnsmasq.leases" );
866        unlink( "/jffs/dnsmasq.leases" );
867    }
868
869    if( strcmp( lan_ipaddr, nvram_safe_get( "lan_ipaddr" ) ) ||
870        strcmp( lan_netmask, nvram_safe_get( "lan_netmask" ) ) )
871        lan_ip_changed = 1;
872    else
873        lan_ip_changed = 0;
874
875    nvram_set( v->name, lan_ipaddr );
876    nvram_set( "lan_netmask", lan_netmask );
877
878}
879
880void
881validate_remote_ip(webs_t wp, char *value, struct variable *v)
882{
883        char from[20], *to;
884        char remote_ip[254];
885        char name[32];
886
887                get_merge_ipaddr(wp, v->name, from);
888       
889                snprintf( name, sizeof( name ), "%s_4", v->name );
890                to = websGetVar(wp, name, NULL);
891       
892                if( !valid_ipaddr( wp, from, v ) )
893                return;
894
895                snprintf(remote_ip, sizeof(remote_ip), "%s %s", from, to);
896               
897                nvram_set( v->name, remote_ip );
898}
899
900
901#define SRL_VALID(v)        (((v) > 0) && ((v) <= 15))
902#define SFBL_VALID(v)       (((v) > 0) && ((v) <= 15))
903#define LRL_VALID(v)        (((v) > 0) && ((v) <= 15))
904#define LFBL_VALID(v)       (((v) > 0) && ((v) <= 15))
905
906void
907validate_wl_wme_tx_params( webs_t wp, char *value, struct variable *v,
908                           char *varname )
909{
910    int srl = 0, sfbl = 0, lrl = 0, lfbl = 0, max_rate = 0, nmode = 0;
911    char *s, *errmsg;
912    char tmp[256];
913
914    /* return if wme is not enabled */
915    if( !( s = websGetVar( wp, "wl0_wme", NULL ) ) )
916    {
917        return;
918    }
919    else if( !strcmp( s, "off" ) )
920    {
921        return;
922    }
923
924    /* return if afterburner enabled */
925    if( ( s = websGetVar( wp, "wl0_afterburner", NULL ) )
926        && ( !strcmp( s, "auto" ) ) )
927    {
928        return;
929    }
930
931    if( !value || atoi( value ) != 5 )
932    {                           /* Number of INPUTs */
933        return;
934    }
935
936    s = nvram_get( v->name );
937
938    if( s != NULL )
939        sscanf( s, "%d %d %d %d %d", &srl, &sfbl, &lrl, &lfbl, &max_rate );
940
941    if( ( value =
942          websGetVar( wp, strcat_r( v->name, "0", tmp ), NULL ) ) != NULL )
943        srl = atoi( value );
944
945    if( !SRL_VALID( srl ) )
946    {
947        errmsg = "Short Retry Limit must be in the range 1 to 15";
948        return;
949    }
950
951    if( ( value =
952          websGetVar( wp, strcat_r( v->name, "1", tmp ), NULL ) ) != NULL )
953        sfbl = atoi( value );
954
955    if( !SFBL_VALID( sfbl ) )
956    {
957        errmsg = "Short Fallback Limit must be in the range 1 to 15";
958        return;
959    }
960
961    if( ( value =
962          websGetVar( wp, strcat_r( v->name, "2", tmp ), NULL ) ) != NULL )
963        lrl = atoi( value );
964
965    if( !LRL_VALID( lrl ) )
966    {
967        errmsg = "Long Retry Limit must be in the range 1 to 15";
968        return;
969    }
970
971    if( ( value =
972          websGetVar( wp, strcat_r( v->name, "3", tmp ), NULL ) ) != NULL )
973        lfbl = atoi( value );
974
975    if( !LFBL_VALID( lfbl ) )
976    {
977        errmsg = "Long Fallback Limit must be in the range 1 to 15";
978        return;
979    }
980
981    if( ( value =
982          websGetVar( wp, strcat_r( v->name, "4", tmp ), NULL ) ) != NULL )
983        max_rate = atoi( value );
984
985    s = nvram_get( "wl0_nmode" );
986    if( s != NULL )
987        nmode = atoi( s );
988
989    sprintf( tmp, "%d %d %d %d %d", srl, sfbl, lrl, lfbl, max_rate );
990
991    nvram_set( v->name, tmp );
992
993    return;
994
995}
996
997void validate_wl_wme_params( webs_t wp, char *value, struct variable *v )
998{
999    int n, i;
1000    int cwmin = 0, cwmax = 0;
1001    char *wme, *afterburner;
1002    char name[100];
1003    char buf[1000] = "", *cur = buf;
1004    struct
1005    {
1006        char *name;
1007        int range;
1008        char *arg1;
1009        char *arg2;
1010    } field_attrib[] =
1011    {
1012        {
1013        "WME AC CWmin", 1, "0", "32767"},
1014        {
1015        "WME AC CWmax", 1, "0", "32767"},
1016        {
1017        "WME AC AIFSN", 1, "1", "15"},
1018        {
1019        "WME AC TXOP(b)", 1, "0", "65504"},
1020        {
1021        "WME AC TXOP(a/g)", 1, "0", "65504"},
1022        {
1023        "WME AC Admin Forced", 0, "on", "off"}
1024    };
1025
1026    /*
1027     * return if wme is not enabled
1028     */
1029    if( !( wme = websGetVar( wp, "wl_wme", NULL ) ) )
1030        return;
1031    else if( strcmp( wme, "on" ) )
1032        return;
1033
1034    /*
1035     * return if afterburner enabled
1036     */
1037    if( ( afterburner = websGetVar( wp, "wl_afterburner", NULL ) )
1038        && ( !strcmp( afterburner, "auto" ) ) )
1039        return;
1040
1041    n = atoi( value ) + 1;
1042
1043    for( i = 0; i < n; i++ )
1044    {
1045        snprintf( name, sizeof( name ), "%s%d", v->name, i );
1046        if( !( value = websGetVar( wp, name, NULL ) ) )
1047            return;
1048        if( !*value && v->nullok )
1049            continue;
1050
1051        if( i == 0 )
1052            cwmin = atoi( value );
1053        else if( i == 1 )
1054        {
1055            cwmax = atoi( value );
1056            if( cwmax < cwmin )
1057            {
1058                websDebugWrite( wp,
1059                                "Invalid <b>%s</b> %d: greater than <b>%s</b> %d<br>",
1060                                field_attrib[0].name, cwmin,
1061                                field_attrib[i].name, cwmax );
1062                return;
1063            }
1064        }
1065        if( field_attrib[i].range )
1066        {
1067            if( atoi( value ) < atoi( field_attrib[i].arg1 )
1068                || atoi( value ) > atoi( field_attrib[i].arg2 ) )
1069            {
1070                websDebugWrite( wp,
1071                                "Invalid <b>%s</b> %d: should be in range %s to %s<br>",
1072                                field_attrib[i].name, atoi( value ),
1073                                field_attrib[i].arg1, field_attrib[i].arg2 );
1074                return;
1075            }
1076        }
1077        else
1078        {
1079            if( strcmp( value, field_attrib[i].arg1 )
1080                && strcmp( value, field_attrib[i].arg2 ) )
1081            {
1082                websDebugWrite( wp,
1083                                "Invalid <b>%s</b> %s: should be %s or %s<br>",
1084                                field_attrib[i].name, value,
1085                                field_attrib[i].arg1, field_attrib[i].arg2 );
1086            }
1087        }
1088
1089        cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s",
1090                         cur == buf ? "" : " ", value );
1091    }
1092
1093    nvram_set( v->name, buf );
1094}
1095
1096#ifndef HAVE_MSSID
1097void validate_security_mode( webs_t wp, char *value, struct variable *v )
1098{
1099    char *security_mode_last = websGetVar( wp, "security_mode_last", NULL );
1100    char *wl_wep_last = websGetVar( wp, "wl_wep_last", NULL );
1101    int from_index_page = 0;
1102    char *wl_wep = NULL;
1103
1104    // If you don't press "Edit Security Setting" to set some value, and
1105    // direct select to enable "Wireless Security".
1106    // It'll returned, due to security_mode_buf is space.
1107    if( !strcmp( value, "enabled" ) )
1108    {
1109        if( nvram_match( "security_mode_last", "" ) )   // from index.asp and
1110            // first time
1111            return;
1112        else
1113        {
1114            if( !security_mode_last )
1115            {                   // from index.asp
1116                from_index_page = 1;
1117                value = nvram_safe_get( "security_mode_last" );
1118                wl_wep = nvram_safe_get( "wl_wep_last" );
1119            }
1120            else
1121            {                   // from WL_WPATable.asp page
1122                value = websGetVar( wp, "security_mode_last", NULL );
1123                wl_wep = nvram_safe_get( "wl_wep_last" );
1124            }
1125        }
1126    }
1127
1128    if( !valid_choice( wp, value, v ) )
1129        return;
1130
1131    if( !strcmp( value, "disabled" ) )
1132    {
1133        nvram_set( "security_mode", "disabled" );
1134        nvram_set( "wl_akm", "" );
1135        nvram_set( "wl_auth_mode", "none" );
1136        nvram_set( "wl_wep", "disabled" );
1137    }
1138    else if( !strcmp( value, "psk" ) )
1139    {
1140        nvram_set( "wl_akm", value );
1141        nvram_set( "wl_auth_mode", "none" );
1142        nvram_set( "wl_wep", "disabled" );
1143    }
1144    else if( !strcmp( value, "wpa" ) )
1145    {
1146        nvram_set( "wl_akm", value );
1147        nvram_set( "wl_auth_mode", "none" );
1148        nvram_set( "wl_wep", "disabled" );
1149    }
1150    else if( !strcmp( value, "radius" ) )
1151    {
1152        nvram_set( "security_mode", "radius" );
1153        nvram_set( "wl_akm", "" );
1154        nvram_set( "wl_auth_mode", "radius" );
1155        nvram_set( "wl_wep", "enabled" );       // the nas need this value,
1156        // the "restricted" is no
1157        // longer need. (20040624 by
1158        // honor)
1159    }
1160    else if( !strcmp( value, "wep" ) )
1161    {
1162        nvram_set( "wl_akm", "" );
1163        nvram_set( "wl_auth_mode", "none" );
1164        nvram_set( "wl_wep", "enabled" );       // the nas need this value,
1165        // the "restricted" is no
1166        // longer need. (20040624 by
1167        // honor)
1168    }
1169    else if( !strcmp( value, "psk2" ) )
1170    {                           // WPA2 Only Mode
1171        nvram_set( "wl_akm", value );
1172        nvram_set( "wl_auth_mode", "none" );
1173        nvram_set( "wl_wep", "disabled" );
1174    }
1175    else if( !strcmp( value, "wpa2" ) )
1176    {                           // WPA2 Only Mode
1177        nvram_set( "wl_akm", value );
1178        nvram_set( "wl_auth_mode", "none" );
1179        nvram_set( "wl_wep", "disabled" );
1180    }
1181    else if( !strcmp( value, "psk psk2" ) )
1182    {                           // WPA2 Mixed Mode
1183        nvram_set( "wl_akm", value );
1184        nvram_set( "wl_auth_mode", "none" );
1185        nvram_set( "wl_wep", "disabled" );
1186    }
1187    else if( !strcmp( value, "wpa wpa2" ) )
1188    {                           // WPA2 Mixed Mode
1189        nvram_set( "wl_akm", value );
1190        nvram_set( "wl_auth_mode", "none" );
1191        nvram_set( "wl_wep", "disabled" );
1192    }
1193
1194    if( security_mode_last )
1195        nvram_set( "security_mode_last", security_mode_last );
1196
1197    if( wl_wep_last )
1198        nvram_set( "wl_wep_last", wl_wep_last );
1199
1200    nvram_set( v->name, value );
1201}
1202#endif
1203void validate_wl_key( webs_t wp, char *value, struct variable *v )
1204{
1205    char *c;
1206
1207    switch ( strlen( value ) )
1208    {
1209        case 5:
1210        case 13:
1211            break;
1212        case 10:
1213        case 26:
1214            for( c = value; *c; c++ )
1215            {
1216                if( !isxdigit( *c ) )
1217                {
1218                    websDebugWrite( wp,
1219                                    "Invalid <b>%s</b>: character %c is not a hexadecimal digit<br>",
1220                                    v->longname, *c );
1221                    return;
1222                }
1223            }
1224            break;
1225        default:
1226            websDebugWrite( wp,
1227                            "Invalid <b>%s</b>: must be 5 or 13 ASCII characters or 10 or 26 hexadecimal digits<br>",
1228                            v->longname );
1229            return;
1230    }
1231
1232    nvram_set( v->name, value );
1233}
1234
1235#ifndef GMODE_AFTERBURNER
1236#       define GMODE_AFTERBURNER 7
1237#endif
1238
1239void validate_wl_wep( webs_t wp, char *value, struct variable *v )
1240{
1241    if( !valid_choice( wp, value, v ) )
1242        return;
1243#ifdef ABURN_WSEC_CHECK
1244    if( strcmp( value, "off" )
1245        && atoi( nvram_safe_get( "wl_gmode" ) ) == GMODE_AFTERBURNER )
1246    {
1247        websDebugWrite( wp,
1248                        "<br>Invalid <b>%s</b>: must be set to <b>Off</b> when 54g Mode is AfterBurner.",
1249                        v->longname );
1250        return;
1251    }
1252#endif
1253    nvram_set( v->name, value );
1254}
1255
1256void validate_auth_mode( webs_t wp, char *value, struct variable *v )
1257{
1258    if( !valid_choice( wp, value, v ) )
1259        return;
1260    nvram_set( v->name, value );
1261}
1262
1263void validate_wpa_psk( webs_t wp, char *value, struct variable *v )
1264{
1265    int len = strlen( value );
1266    char *c;
1267
1268    if( len == 64 )
1269    {
1270        for( c = value; *c; c++ )
1271        {
1272            if( !isxdigit( ( int )*c ) )
1273            {
1274                websDebugWrite( wp,
1275                                "Invalid <b>%s</b>: character %c is not a hexadecimal digit<br>",
1276                                v->longname, *c );
1277                return;
1278            }
1279        }
1280    }
1281    else if( len < 8 || len > 63 )
1282    {
1283        websDebugWrite( wp,
1284                        "Invalid <b>%s</b>: must be between 8 and 63 ASCII characters or 64 hexadecimal digits<br>",
1285                        v->longname );
1286        return;
1287    }
1288
1289    nvram_set( v->name, value );
1290}
1291
1292#ifdef HAVE_MSSID
1293
1294void validate_wl_wep_key( webs_t wp, char *value, struct variable *v )
1295{
1296    char buf[200] = "";
1297    int error_value = 0;
1298    struct variable wl_wep_variables[] = {
1299      {argv:ARGV( "16" )},
1300      {argv:ARGV( "5", "10" )},
1301        // for 64 bit
1302      {argv:ARGV( "13", "26" )},
1303        // for 128 bit
1304      {argv:ARGV( "1", "4" )},
1305    }, *which;
1306
1307    char *wep_bit = "", *wep_passphrase = "", *wep_key1 = "", *wep_key2 =
1308        "", *wep_key3 = "", *wep_key4 = "", *wep_tx = "";
1309    char new_wep_passphrase[50] = "", new_wep_key1[30] =
1310        "", new_wep_key2[30] = "", new_wep_key3[30] = "", new_wep_key4[30] =
1311        "";
1312    int index;
1313
1314    which = &wl_wep_variables[0];
1315
1316    wep_bit = websGetVar( wp, "wl_wep_bit", NULL );     // 64 or 128
1317    if( !wep_bit )
1318        return;
1319    if( strcmp( wep_bit, "64" ) && strcmp( wep_bit, "128" ) )
1320        return;
1321
1322    wep_passphrase = websGetVar( wp, "wl_passphrase", "" );
1323    // if(!wep_passphrase) return ;
1324
1325    // strip_space(wep_passphrase);
1326    if( strcmp( wep_passphrase, "" ) )
1327    {
1328        if( !valid_name( wp, wep_passphrase, &which[0] ) )
1329        {
1330            error_value = 1;
1331        }
1332        else
1333        {
1334            httpd_filter_name( wep_passphrase, new_wep_passphrase,
1335                               sizeof( new_wep_passphrase ), SET );
1336        }
1337    }
1338
1339    wep_key1 = websGetVar( wp, "wl_key1", "" );
1340    wep_key2 = websGetVar( wp, "wl_key2", "" );
1341    wep_key3 = websGetVar( wp, "wl_key3", "" );
1342    wep_key4 = websGetVar( wp, "wl_key4", "" );
1343    wep_tx = websGetVar( wp, "wl_key", NULL );
1344
1345    if( !wep_tx )
1346    {
1347        error_value = 1;
1348        return;
1349    }
1350
1351    index = ( atoi( wep_bit ) == 64 ) ? 1 : 2;
1352
1353    if( strcmp( wep_key1, "" ) )
1354    {
1355        if( !valid_wep_key( wp, wep_key1, &which[index] ) )
1356        {
1357            error_value = 1;
1358        }
1359        else
1360        {
1361            httpd_filter_name( wep_key1, new_wep_key1, sizeof( new_wep_key1 ),
1362                               SET );
1363        }
1364
1365    }
1366    if( strcmp( wep_key2, "" ) )
1367    {
1368        if( !valid_wep_key( wp, wep_key2, &which[index] ) )
1369        {
1370            error_value = 1;
1371        }
1372        else
1373        {
1374            httpd_filter_name( wep_key2, new_wep_key2, sizeof( new_wep_key2 ),
1375                               SET );
1376        }
1377    }
1378    if( strcmp( wep_key3, "" ) )
1379    {
1380        if( !valid_wep_key( wp, wep_key3, &which[index] ) )
1381        {
1382            error_value = 1;
1383        }
1384        else
1385        {
1386            httpd_filter_name( wep_key3, new_wep_key3, sizeof( new_wep_key3 ),
1387                               SET );
1388        }
1389    }
1390    if( strcmp( wep_key4, "" ) )
1391    {
1392        if( !valid_wep_key( wp, wep_key4, &which[index] ) )
1393        {
1394            error_value = 1;
1395        }
1396        else
1397        {
1398            httpd_filter_name( wep_key4, new_wep_key4, sizeof( new_wep_key4 ),
1399                               SET );
1400        }
1401    }
1402
1403    if( !error_value )
1404    {
1405        snprintf( buf, sizeof( buf ), "%s:%s:%s:%s:%s:%s", new_wep_passphrase,
1406                  new_wep_key1, new_wep_key2, new_wep_key3, new_wep_key4,
1407                  wep_tx );
1408        nvram_set( "wl_wep_bit", wep_bit );
1409        nvram_set( "wl_wep_buf", buf );
1410
1411        nvram_set( "wl_passphrase", wep_passphrase );
1412        nvram_set( "wl_key", wep_tx );
1413        nvram_set( "wl_key1", wep_key1 );
1414        nvram_set( "wl_key2", wep_key2 );
1415        nvram_set( "wl_key3", wep_key3 );
1416        nvram_set( "wl_key4", wep_key4 );
1417
1418        if( !strcmp( wep_key1, "" ) && !strcmp( wep_key2, "" ) && !strcmp( wep_key3, "" ) && !strcmp( wep_key4, "" ) )  // Allow
1419            // null
1420            // wep
1421            nvram_set( "wl_wep", "off" );
1422        else
1423            nvram_set( "wl_wep", "restricted" );
1424    }
1425
1426}
1427
1428#else
1429
1430void validate_wl_wep_key( webs_t wp, char *value, struct variable *v )
1431{
1432    char buf[200] = "";
1433    struct variable wl_wep_variables[] = {
1434      {argv:ARGV( "16" )},
1435      {argv:ARGV( "5", "10" )},
1436        // for 64 bit
1437      {argv:ARGV( "13", "26" )},
1438        // for 128 bit
1439      {argv:ARGV( "1", "4" )},
1440    }, *which;
1441    int error_value = 0;
1442    char *wep_bit = "", *wep_passphrase = "", *wep_key1 = "", *wep_key2 =
1443        "", *wep_key3 = "", *wep_key4 = "", *wep_tx = "";
1444    char new_wep_passphrase[50] = "", new_wep_key1[30] =
1445        "", new_wep_key2[30] = "", new_wep_key3[30] = "", new_wep_key4[30] =
1446        "";
1447    int index;
1448
1449    which = &wl_wep_variables[0];
1450
1451    wep_bit = websGetVar( wp, "wl_wep_bit", NULL );     // 64 or 128
1452    if( !wep_bit )
1453        return;
1454    if( strcmp( wep_bit, "64" ) && strcmp( wep_bit, "128" ) )
1455        return;
1456
1457    wep_passphrase = websGetVar( wp, "wl_passphrase", "" );
1458    // if(!wep_passphrase) return ;
1459
1460    // strip_space(wep_passphrase);
1461    if( strcmp( wep_passphrase, "" ) )
1462    {
1463        if( !valid_name( wp, wep_passphrase, &which[0] ) )
1464        {
1465            error_value = 1;
1466        }
1467        else
1468        {
1469            httpd_filter_name( wep_passphrase, new_wep_passphrase,
1470                               sizeof( new_wep_passphrase ), SET );
1471        }
1472    }
1473
1474    wep_key1 = websGetVar( wp, "wl_key1", "" );
1475    wep_key2 = websGetVar( wp, "wl_key2", "" );
1476    wep_key3 = websGetVar( wp, "wl_key3", "" );
1477    wep_key4 = websGetVar( wp, "wl_key4", "" );
1478    wep_tx = websGetVar( wp, "wl_key", NULL );
1479
1480    if( !wep_tx )
1481    {
1482        error_value = 1;
1483        return;
1484    }
1485
1486    index = ( atoi( wep_bit ) == 64 ) ? 1 : 2;
1487
1488    if( strcmp( wep_key1, "" ) )
1489    {
1490        if( !valid_wep_key( wp, wep_key1, &which[index] ) )
1491        {
1492            error_value = 1;
1493        }
1494        else
1495        {
1496            httpd_filter_name( wep_key1, new_wep_key1, sizeof( new_wep_key1 ),
1497                               SET );
1498        }
1499
1500    }
1501    if( strcmp( wep_key2, "" ) )
1502    {
1503        if( !valid_wep_key( wp, wep_key2, &which[index] ) )
1504        {
1505            error_value = 1;
1506        }
1507        else
1508        {
1509            httpd_filter_name( wep_key2, new_wep_key2, sizeof( new_wep_key2 ),
1510                               SET );
1511        }
1512    }
1513    if( strcmp( wep_key3, "" ) )
1514    {
1515        if( !valid_wep_key( wp, wep_key3, &which[index] ) )
1516        {
1517            error_value = 1;
1518        }
1519        else
1520        {
1521            httpd_filter_name( wep_key3, new_wep_key3, sizeof( new_wep_key3 ),
1522                               SET );
1523        }
1524    }
1525    if( strcmp( wep_key4, "" ) )
1526    {
1527        if( !valid_wep_key( wp, wep_key4, &which[index] ) )
1528        {
1529            error_value = 1;
1530        }
1531        else
1532        {
1533            httpd_filter_name( wep_key4, new_wep_key4, sizeof( new_wep_key4 ),
1534                               SET );
1535        }
1536    }
1537
1538    if( !error_value )
1539    {
1540        snprintf( buf, sizeof( buf ), "%s:%s:%s:%s:%s:%s", new_wep_passphrase,
1541                  new_wep_key1, new_wep_key2, new_wep_key3, new_wep_key4,
1542                  wep_tx );
1543        nvram_set( "wl_wep_bit", wep_bit );
1544        nvram_set( "wl_wep_buf", buf );
1545
1546        nvram_set( "wl_passphrase", wep_passphrase );
1547        nvram_set( "wl_key", wep_tx );
1548        nvram_set( "wl_key1", wep_key1 );
1549        nvram_set( "wl_key2", wep_key2 );
1550        nvram_set( "wl_key3", wep_key3 );
1551        nvram_set( "wl_key4", wep_key4 );
1552
1553        if( !strcmp( wep_key1, "" ) && !strcmp( wep_key2, "" ) && !strcmp( wep_key3, "" ) && !strcmp( wep_key4, "" ) )  // Allow
1554            // null
1555            // wep
1556            nvram_set( "wl_wep", "off" );
1557        else
1558            nvram_set( "wl_wep", "restricted" );
1559    }
1560
1561}
1562#endif
1563void validate_wl_auth( webs_t wp, char *value, struct variable *v )
1564{
1565    if( !valid_choice( wp, value, v ) )
1566        return;
1567    /*
1568     * // not to check , spec for linksys if (atoi(value) == 1) { char
1569     * wl_key[] = "wl_keyXXX";
1570     *
1571     * snprintf(wl_key, sizeof(wl_key), "wl_key%s",
1572     * nvram_safe_get("wl_key")); if (!strlen(nvram_safe_get(wl_key))) {
1573     * websDebugWrite(wp, "Invalid <b>%s</b>: must first specify a valid
1574     * <b>Network Key</b><br>", v->longname); return; } }
1575     */
1576    nvram_set( v->name, value );
1577}
1578
1579/*
1580 * Example: 00:11:22:33:44:55=1 00:12:34:56:78:90=0 (ie 00:11:22:33:44:55 if
1581 * filterd, and 00:12:34:56:78:90 is not) wl_maclist = "00:11:22:33:44:55"
1582 */
1583void validate_wl_hwaddrs( webs_t wp, char *value, struct variable *v )
1584{
1585    int i;
1586    int error_value = 0;
1587    char buf[19 * WL_FILTER_MAC_NUM * WL_FILTER_MAC_PAGE] = "", *cur = buf;
1588    char *wordlist;
1589    unsigned int m[6];
1590    char *ifname = websGetVar( wp, "ifname", NULL );    // 64 or 128
1591
1592    if( ifname == NULL )
1593        return;
1594    char mlist[32];
1595
1596    sprintf( mlist, "%s_maclist", ifname );
1597    wordlist = nvram_safe_get( mlist );
1598    if( !wordlist )
1599        return;
1600
1601    for( i = 0; i < WL_FILTER_MAC_NUM * WL_FILTER_MAC_PAGE; i++ )
1602    {
1603        char filter_mac[] = "ath10.99_macXXX";
1604        char *mac = NULL;
1605        char mac1[20];
1606
1607        snprintf( filter_mac, sizeof( filter_mac ), "%s%s%d", ifname, "_mac",
1608                  i );
1609
1610        mac = websGetVar( wp, filter_mac, NULL );
1611
1612        if( !mac || !strcmp( mac, "0" ) || !strcmp( mac, "" ) )
1613        {
1614            continue;
1615        }
1616
1617        if( strlen( mac ) == 12 )
1618        {
1619            sscanf( mac, "%02X%02X%02X%02X%02X%02X", &m[0],
1620                    &m[1], &m[2], &m[3], &m[4], &m[5] );
1621            sprintf( mac1, "%02X:%02X:%02X:%02X:%02X:%02X", m[0], m[1], m[2],
1622                     m[3], m[4], m[5] );
1623        }
1624        else if( strlen( mac ) == 17 )
1625        {
1626            sscanf( mac, "%02X:%02X:%02X:%02X:%02X:%02X", &m[0],
1627                    &m[1], &m[2], &m[3], &m[4], &m[5] );
1628            sprintf( mac1, "%02X:%02X:%02X:%02X:%02X:%02X", m[0], m[1], m[2],
1629                     m[3], m[4], m[5] );
1630        }
1631        else
1632        {
1633            mac1[0] = 0;
1634        }
1635
1636        if( !valid_hwaddr( wp, mac1, v ) )
1637        {
1638            error_value = 1;
1639            continue;
1640        }
1641        cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s",
1642                         cur == buf ? "" : " ", mac1 );
1643
1644    }
1645
1646    if( !error_value )
1647    {
1648        nvram_set( v->name, buf );
1649        nvram_set( mlist, buf );
1650        nvram_set( "wl_active_mac", "" );
1651        nvram_set( "wl0_active_mac", "" );
1652    }
1653}
1654
1655/*
1656 * Example: name:[on|off]:[tcp|udp|both]:8000:80>100
1657 */
1658
1659void validate_forward_proto( webs_t wp, char *value, struct variable *v )
1660{
1661    int i, error = 0;
1662    char *buf, *cur;
1663    int count, sof;
1664    struct variable forward_proto_variables[] = {
1665      {argv:ARGV( "12" )},
1666      {argv:ARGV( "0", "65535" )},
1667      {argv:ARGV( "0", "65535" )},
1668        {NULL},
1669    }, *which;
1670    buf = nvram_safe_get( "forward_entries" );
1671    if( buf == NULL || strlen( buf ) == 0 )
1672        return;
1673    count = atoi( buf );
1674    sof = ( count * 128 ) + 1;
1675    buf = ( char * )malloc( sof );
1676    cur = buf;
1677    buf[0] = 0;
1678
1679    for( i = 0; i < count; i++ )
1680    {
1681
1682        char forward_name[] = "nameXXX";
1683        char forward_from[] = "fromXXX";
1684        char forward_to[] = "toXXX";
1685        char forward_ip[] = "ipXXX";
1686        char forward_tcp[] = "tcpXXX";  // for checkbox
1687        char forward_udp[] = "udpXXX";  // for checkbox
1688        char forward_pro[] = "proXXX";  // for select, cisco style UI
1689        char forward_enable[] = "enableXXX";
1690        char *name = "", new_name[200] = "", *from = "", *to = "", *ip =
1691            "", *tcp = "", *udp = "", *enable = "", proto[10], *pro = "";
1692
1693        snprintf( forward_name, sizeof( forward_name ), "name%d", i );
1694        snprintf( forward_from, sizeof( forward_from ), "from%d", i );
1695        snprintf( forward_to, sizeof( forward_to ), "to%d", i );
1696        snprintf( forward_ip, sizeof( forward_ip ), "ip%d", i );
1697        snprintf( forward_tcp, sizeof( forward_tcp ), "tcp%d", i );
1698        snprintf( forward_udp, sizeof( forward_udp ), "udp%d", i );
1699        snprintf( forward_enable, sizeof( forward_enable ), "enable%d", i );
1700        snprintf( forward_pro, sizeof( forward_pro ), "pro%d", i );
1701
1702        name = websGetVar( wp, forward_name, "" );
1703        from = websGetVar( wp, forward_from, "0" );
1704        to = websGetVar( wp, forward_to, "0" );
1705        ip = websGetVar( wp, forward_ip, "0" );
1706        tcp = websGetVar( wp, forward_tcp, NULL );      // for checkbox
1707        udp = websGetVar( wp, forward_udp, NULL );      // for checkbox
1708        pro = websGetVar( wp, forward_pro, NULL );      // for select option
1709        enable = websGetVar( wp, forward_enable, "off" );
1710
1711        which = &forward_proto_variables[0];
1712
1713        if( !*from && !*to && !*ip )
1714            continue;
1715        if( !strcmp( ip, "0" ) || !strcmp( ip, "" ) )
1716            continue;
1717        if( ( !strcmp( from, "0" ) || !strcmp( from, "" ) ) &&
1718            ( !strcmp( to, "0" ) || !strcmp( to, "" ) ) &&
1719            ( !strcmp( ip, "0" ) || !strcmp( ip, "" ) ) )
1720        {
1721            continue;
1722        }
1723
1724        /*
1725         * check name
1726         */
1727        if( strcmp( name, "" ) )
1728        {
1729            if( !valid_name( wp, name, &which[0] ) )
1730            {
1731                continue;
1732            }
1733            else
1734            {
1735                httpd_filter_name( name, new_name, sizeof( new_name ), SET );
1736            }
1737        }
1738
1739        if( !strcmp( from, "" ) )
1740            from = to;
1741        if( !strcmp( to, "" ) )
1742            to = from;
1743
1744        if( atoi( from ) > atoi( to ) )
1745        {
1746            SWAP( from, to );
1747        }
1748
1749        if( !valid_range( wp, from, &which[1] )
1750            || !valid_range( wp, to, &which[2] ) )
1751        {
1752            continue;
1753        }
1754
1755        if( pro )
1756        {                       // use select option
1757            strcpy( proto, pro );
1758        }
1759        else
1760        {                       // use checkbox
1761            if( tcp && udp )
1762                strcpy( proto, "both" );
1763            else if( tcp && !udp )
1764                strcpy( proto, "tcp" );
1765            else if( !tcp && udp )
1766                strcpy( proto, "udp" );
1767        }
1768        /*
1769         * check ip address
1770         */
1771
1772        if( !*ip )
1773        {
1774            error = 1;
1775            // websWrite(wp, "Invalid <b>%s</b> : must specify a
1776            // ip<br>",which[4].longname);
1777            continue;
1778        }
1779
1780        /*
1781         * Sveasoft add - new format allows full IP address
1782         */
1783        if( sv_valid_ipaddr( ip ) )
1784        {
1785            cur += snprintf( cur, buf + sof - cur, "%s%s:%s:%s:%d:%d>%s",
1786                             cur == buf ? "" : " ", new_name, enable, proto,
1787                             atoi( from ), atoi( to ), ip );
1788        }
1789        /*
1790         * Sveasoft - for backwords compatability allow single number
1791         */
1792        else if( sv_valid_range( ip, 0, 254 ) )
1793        {
1794            char fullip[16] = { 0 };
1795            int f_ip[4];
1796
1797            sscanf( nvram_safe_get( "lan_ipaddr" ), "%d.%d.%d.%d", &f_ip[0],
1798                    &f_ip[1], &f_ip[2], &f_ip[3] );
1799            snprintf( fullip, 15, "%d.%d.%d.%d", f_ip[0], f_ip[1], f_ip[2],
1800                      atoi( ip ) );
1801            cur +=
1802                snprintf( cur, buf + sof - cur, "%s%s:%s:%s:%d:%d>%s",
1803                          cur == buf ? "" : " ", new_name, enable, proto,
1804                          atoi( from ), atoi( to ), fullip );
1805
1806        }
1807        else
1808        {
1809            error = 1;
1810            continue;
1811        }
1812
1813    }
1814    if( !error )
1815        nvram_set( v->name, buf );
1816    free( buf );
1817}
1818
1819/*
1820 * Example: name:[on|off]:[tcp|udp|both]:8000:80>100
1821 */
1822
1823void validate_forward_spec( webs_t wp, char *value, struct variable *v )
1824{
1825    int i, error = 0;
1826    char *buf, *cur;
1827    int count, sof;
1828    struct variable forward_proto_variables[] = {
1829      {argv:ARGV( "12" )},
1830      {argv:ARGV( "0", "65535" )},
1831      {argv:ARGV( "0", "65535" )},
1832        {NULL},
1833    }, *which;
1834    buf = nvram_safe_get( "forwardspec_entries" );
1835    if( buf == NULL || strlen( buf ) == 0 )
1836        return;
1837    count = atoi( buf );
1838    sof = ( count * 128 ) + 1;
1839    buf = ( char * )malloc( sof );
1840    cur = buf;
1841    buf[0] = 0;
1842
1843    for( i = 0; i < count; i++ )
1844    {
1845
1846        char forward_name[] = "nameXXX";
1847        char forward_from[] = "fromXXX";
1848        char forward_to[] = "toXXX";
1849        char forward_ip[] = "ipXXX";
1850        char forward_tcp[] = "tcpXXX";  // for checkbox
1851        char forward_udp[] = "udpXXX";  // for checkbox
1852        char forward_pro[] = "proXXX";  // for select, cisco style UI
1853        char forward_enable[] = "enableXXX";
1854        char *name = "", new_name[200] = "", *from = "", *to = "", *ip =
1855            "", *tcp = "", *udp = "", *enable = "", proto[10], *pro = "";
1856
1857        snprintf( forward_name, sizeof( forward_name ), "name%d", i );
1858        snprintf( forward_from, sizeof( forward_from ), "from%d", i );
1859        snprintf( forward_to, sizeof( forward_to ), "to%d", i );
1860        snprintf( forward_ip, sizeof( forward_ip ), "ip%d", i );
1861        snprintf( forward_tcp, sizeof( forward_tcp ), "tcp%d", i );
1862        snprintf( forward_udp, sizeof( forward_udp ), "udp%d", i );
1863        snprintf( forward_enable, sizeof( forward_enable ), "enable%d", i );
1864        snprintf( forward_pro, sizeof( forward_pro ), "pro%d", i );
1865
1866        name = websGetVar( wp, forward_name, "" );
1867        from = websGetVar( wp, forward_from, "0" );
1868        to = websGetVar( wp, forward_to, "0" );
1869        ip = websGetVar( wp, forward_ip, "0" );
1870        tcp = websGetVar( wp, forward_tcp, NULL );      // for checkbox
1871        udp = websGetVar( wp, forward_udp, NULL );      // for checkbox
1872        pro = websGetVar( wp, forward_pro, NULL );      // for select option
1873        enable = websGetVar( wp, forward_enable, "off" );
1874
1875        which = &forward_proto_variables[0];
1876
1877        if( !*from && !*to && !*ip )
1878            continue;
1879        if( !strcmp( ip, "0" ) || !strcmp( ip, "" ) )
1880            continue;
1881        if( ( !strcmp( from, "0" ) || !strcmp( from, "" ) ) &&
1882            ( !strcmp( to, "0" ) || !strcmp( to, "" ) ) &&
1883            ( !strcmp( ip, "0" ) || !strcmp( ip, "" ) ) )
1884        {
1885            continue;
1886        }
1887
1888        /*
1889         * check name
1890         */
1891        if( strcmp( name, "" ) )
1892        {
1893            if( !valid_name( wp, name, &which[0] ) )
1894            {
1895                continue;
1896            }
1897            else
1898            {
1899                httpd_filter_name( name, new_name, sizeof( new_name ), SET );
1900            }
1901        }
1902
1903        if( !strcmp( from, "" ) )
1904            from = to;
1905        if( !strcmp( to, "" ) )
1906            to = from;
1907
1908        /*
1909         * if(atoi(from) > atoi(to)){ SWAP(from, to); }
1910         */
1911
1912        if( !valid_range( wp, from, &which[1] )
1913            || !valid_range( wp, to, &which[2] ) )
1914        {
1915            continue;
1916        }
1917
1918        if( pro )
1919        {                       // use select option
1920            strcpy( proto, pro );
1921        }
1922        else
1923        {                       // use checkbox
1924            if( tcp && udp )
1925                strcpy( proto, "both" );
1926            else if( tcp && !udp )
1927                strcpy( proto, "tcp" );
1928            else if( !tcp && udp )
1929                strcpy( proto, "udp" );
1930        }
1931        /*
1932         * check ip address
1933         */
1934
1935        if( !*ip )
1936        {
1937            error = 1;
1938            // websWrite(wp, "Invalid <b>%s</b> : must specify a
1939            // ip<br>",which[4].longname);
1940            continue;
1941        }
1942
1943        /*
1944         * Sveasoft add - new format allows full IP address
1945         */
1946        if( sv_valid_ipaddr( ip ) )
1947        {
1948            cur += snprintf( cur, buf + sof - cur, "%s%s:%s:%s:%d>%s:%d",
1949                             cur == buf ? "" : " ", new_name, enable, proto,
1950                             atoi( from ), ip, atoi( to ) );
1951        }
1952        /*
1953         * Sveasoft - for backwords compatability allow single number
1954         */
1955        else if( sv_valid_range( ip, 0, 254 ) )
1956        {
1957            char fullip[16] = { 0 };
1958            int f_ip[4];
1959
1960            sscanf( nvram_safe_get( "lan_ipaddr" ), "%d.%d.%d.%d", &f_ip[0],
1961                    &f_ip[1], &f_ip[2], &f_ip[3] );
1962            snprintf( fullip, 15, "%d.%d.%d.%d", f_ip[0], f_ip[1], f_ip[2],
1963                      atoi( ip ) );
1964            cur +=
1965                snprintf( cur, buf + sof - cur, "%s%s:%s:%s:%d>%s:%d",
1966                          cur == buf ? "" : " ", new_name, enable, proto,
1967                          atoi( from ), fullip, atoi( to ) );
1968
1969        }
1970        else
1971        {
1972            error = 1;
1973            continue;
1974        }
1975
1976    }
1977    if( !error )
1978        nvram_set( v->name, buf );
1979    free( buf );
1980}
1981
1982void validate_dynamic_route( webs_t wp, char *value, struct variable *v )
1983{
1984    struct variable dr_variables[] = {
1985      {argv:ARGV( "0", "1", "2", "3" )},
1986    }, *which;
1987    char *dr_setting;
1988
1989    which = &dr_variables[0];
1990
1991    if( valid_choice( wp, value, v ) )
1992        nvram_set( v->name, value );
1993
1994    dr_setting = websGetVar( wp, "dr_setting", NULL );
1995    if( !dr_setting )
1996        return;
1997
1998    if( !valid_choice( wp, dr_setting, &which[0] ) )
1999        return;
2000
2001    nvram_set( "dr_setting", dr_setting );
2002
2003    if( !dr_setting || atoi( dr_setting ) == 0 )
2004    {
2005        nvram_set( "dr_lan_tx", "0" );
2006        nvram_set( "dr_lan_rx", "0" );
2007        nvram_set( "dr_wan_tx", "0" );
2008        nvram_set( "dr_wan_rx", "0" );
2009    }
2010    else if( atoi( dr_setting ) == 1 )
2011    {
2012        nvram_set( "dr_lan_tx", "1 2" );
2013        nvram_set( "dr_lan_rx", "1 2" );
2014        nvram_set( "dr_wan_tx", "0" );
2015        nvram_set( "dr_wan_rx", "0" );
2016    }
2017    else if( atoi( dr_setting ) == 2 )
2018    {
2019        nvram_set( "dr_lan_tx", "0" );
2020        nvram_set( "dr_lan_rx", "0" );
2021        nvram_set( "dr_wan_tx", "1 2" );
2022        nvram_set( "dr_wan_rx", "1 2" );
2023    }
2024    else if( atoi( dr_setting ) == 3 )
2025    {
2026        nvram_set( "dr_lan_tx", "1 2" );
2027        nvram_set( "dr_lan_rx", "1 2" );
2028        nvram_set( "dr_wan_tx", "1 2" );
2029        nvram_set( "dr_wan_rx", "1 2" );
2030    }
2031    else
2032    {
2033        nvram_set( "dr_lan_tx", "0" );
2034        nvram_set( "dr_lan_rx", "0" );
2035        nvram_set( "dr_wan_tx", "0" );
2036        nvram_set( "dr_wan_rx", "0" );
2037    }
2038
2039    /*
2040     * <lonewolf>
2041     */
2042    if( atoi( websGetVar( wp, "dyn_default", "0" ) ) == 1 )
2043        nvram_set( "dyn_default", "1" );
2044    else
2045        nvram_set( "dyn_default", "0" );
2046
2047    if( nvram_match( "wk_mode", "ospf" ) )
2048    {
2049        nvram_set( "zebra_conf", websGetVar( wp, "zebra_conf", "" ) );
2050        nvram_set( "ospfd_conf", websGetVar( wp, "ospfd_conf", "" ) );
2051        nvram_set( "zebra_copt", websGetVar( wp, "zebra_copt", "0" ) );
2052        nvram_set( "ospfd_copt", websGetVar( wp, "ospfd_copt", "0" ) );
2053    }
2054    /*
2055     * </lonewolf>
2056     */
2057}
2058void validate_wl_gmode( webs_t wp, char *value, struct variable *v )
2059{
2060    if( !valid_choice( wp, value, v ) )
2061        return;
2062    if( atoi( value ) == GMODE_AFTERBURNER )
2063    {
2064        nvram_set( "wl_lazywds", "0" );
2065        nvram_set( "wl_wds", "" );
2066        nvram_set( "wl_mode", "ap" );
2067        /*
2068         * if(nvram_invmatch("security_mode", "disabled") &&
2069         * nvram_invmatch("security_mode", "wep")){
2070         * nvram_set("security_mode", "disabled");
2071         * nvram_set("security_mode_last", nvram_safe_get("security_mode"));
2072         * nvram_set("security_mode", "disabled"); }
2073         */
2074    }
2075    nvram_set( v->name, value );
2076
2077    return;
2078    /*
2079     * force certain wireless variables to fixed values
2080     */
2081    if( atoi( value ) == GMODE_AFTERBURNER )
2082    {
2083        if( nvram_invmatch( "wl_auth_mode", "disabled" ) ||
2084#ifdef ABURN_WSEC_CHECK
2085            nvram_invmatch( "wl_wep", "off" ) ||
2086#endif
2087            nvram_invmatch( "wl_mode", "ap" ) ||
2088            nvram_invmatch( "wl_lazywds", "0" )
2089            || nvram_invmatch( "wl_wds", "" ) )
2090        {
2091            /*
2092             * notify the user
2093             */
2094            /*
2095             * #ifdef ABURN_WSEC_CHECK websWrite (wp, "Invalid <b>%s</b>:
2096             * AfterBurner mode requires:" "<br><b>Network Authentication</b>
2097             * set to <b>Disabled</b>" "<br><b>Data Encryption</b> set to
2098             * <b>Off</b>" "<br><b>Mode</b> set to <b>Access Point</b>" //
2099             * "<br><b>Bridge Restrict</b> set to <b>Enabled</b>" "<br><b>WDS
2100             * devices</b> disabled." "<br>", v->name); #else websWrite (wp,
2101             * "Invalid <b>%s</b>: AfterBurner mode requires:"
2102             * "<br><b>Network Authentication</b> set to <b>Disabled</b>"
2103             * "<br><b>Mode</b> set to <b>Access Point</b>" // "<br><b>Bridge
2104             * Restrict</b> set to <b>Enabled</b>" "<br><b>WDS devices</b>
2105             * disabled." "<br>", v->name); #endif
2106             */
2107            return;
2108        }
2109    }
2110}
2111
2112/*
2113 * UI Mode GMODE Afterburner Override Basic Rate Set FrameBurst CTS
2114 * Protection Mixed 6 - AfterBurner -1 Default ON -1(auto) 54g-Only 6 -
2115 * AfterBurner -1 ALL ON 0(off) 11b-Only 0 - 54g Legacy B NA Default ON
2116 * -1(auto)
2117 */
2118
2119/*
2120 * Sveasoft note: settings for b-only, mixed, and g-mode set back to original
2121 * defaults before "afterburner" mods. Afterburner bizarre settings
2122 * maintained for "speedbooster" mode
2123 */
2124
2125void convert_wl_gmode( char *value, char *prefix )
2126{
2127#ifndef HAVE_MSSID
2128        if( nvram_nmatch( value, "%s_net_mode", prefix ) )
2129        {
2130            return;
2131        }
2132#endif
2133        if( !strcmp( value, "disabled" ) )
2134        {
2135            nvram_nset( value, "%s_net_mode", prefix );
2136            nvram_nset( "-1", "%s_gmode", prefix );
2137#ifdef HAVE_MSSID
2138            nvram_nset( "-1", "%s_nmode", prefix );
2139#endif
2140            nvram_nset( "0", "%s_nreqd", prefix );
2141            nvram_nset( "2", "%s_nband", prefix );
2142        }
2143        else if( !strcmp( value, "mixed" ) )
2144        {
2145            nvram_nset( value, "wl_net_mode", prefix );
2146#ifdef HAVE_MSSID
2147            nvram_nset( "1", "%s_gmode", prefix );
2148            nvram_nset( "-1", "%s_nmode", prefix );
2149#else
2150            nvram_nset( "6", "%s_gmode", prefix );
2151#endif
2152            nvram_nset( "auto", "%s_afterburner", prefix );
2153            nvram_nset( "default", "%s_rateset", prefix );
2154            nvram_nset( "on", "%s_frameburst", prefix );
2155            if( !has_mimo( prefix ) )
2156                nvram_nset( "g", "%s_phytype", prefix );
2157            nvram_nset( "0", "%s_nreqd", prefix );
2158            nvram_nset( "2", "%s_nband", prefix );
2159        }
2160#ifdef HAVE_MSSID
2161        else if( !strcmp( value, "bg-mixed" ) )
2162        {
2163            nvram_nset( value, "%s_net_mode", prefix );
2164            nvram_nset( "1", "%s_gmode", prefix );
2165            nvram_nset( "auto", "%s_afterburner", prefix );
2166            nvram_nset( "default", "%s_rateset", prefix );
2167            nvram_nset( "on", "%s_frameburst", prefix );
2168            nvram_nset( "0", "%s_nmode", prefix );
2169            if( !has_mimo( prefix ) )
2170                nvram_nset( "g", "%s_phytype", prefix );
2171            nvram_nset( "0", "%s_nreqd", prefix );
2172            nvram_nset( "2", "%s_nband", prefix );
2173        }
2174#endif
2175        else if( !strcmp( value, "g-only" ) )
2176        {
2177            nvram_nset( value, "wl_net_mode", prefix );
2178#ifdef HAVE_MSSID
2179            nvram_nset( "0", "wl_nmode", prefix );
2180#endif
2181            nvram_nset( "2", "wl_gmode", prefix );
2182            if( !has_mimo( prefix ) )
2183                nvram_nset( "g", "wl_phytype", prefix );
2184            nvram_nset( "0", "wl_nreqd", prefix );
2185
2186            nvram_nset( "2", "%s_nband", prefix );
2187        }
2188        else if( !strcmp( value, "b-only" ) )
2189        {
2190            nvram_nset( value, "%s_net_mode", prefix );
2191            nvram_nset( "0", "%s_gmode", prefix );
2192#ifdef HAVE_MSSID
2193            nvram_nset( "0", "%s_nmode", prefix );
2194#endif
2195            nvram_nset( "off", "%s_afterburner", prefix );
2196            nvram_nset( "default", "%s_rateset", prefix );
2197            nvram_nset( "on", "%s_frameburst", prefix );
2198            if( !has_mimo( prefix ) )
2199                nvram_nset( "g", "%s_phytype", prefix );
2200            nvram_nset( "0", "%s_nreqd", prefix );
2201            nvram_nset( "2", "%s_nband", prefix );
2202        }
2203#ifdef HAVE_MSSID
2204        else if( !strcmp( value, "n-only" ) )
2205        {
2206            nvram_nset( value, "%s_net_mode", prefix );
2207            nvram_nset( "1", "%s_gmode", prefix );
2208            nvram_nset( "2", "%s_nmode", prefix );
2209            nvram_nset( "1", "%s_nreqd", prefix );
2210            nvram_nset( "off", "%s_afterburner", prefix );      // From
2211            // 3.61.13.0
2212            nvram_nset( "n", "%s_phytype", prefix );
2213            nvram_nset( "2", "%s_nband", prefix );
2214        }
2215        else if( !strcmp( value, "na-only" ) )
2216        {
2217            nvram_nset( value, "%s_net_mode", prefix );
2218            nvram_nset( "2", "%s_nmode", prefix );
2219            nvram_nset( "1", "%s_nreqd", prefix );
2220            nvram_nset( "off", "%s_afterburner", prefix );      // From
2221            // 3.61.13.0
2222            nvram_nset( "n", "%s_phytype", prefix );
2223            nvram_nset( "1", "%s_nband", prefix );
2224        }
2225#endif
2226        else if( !strcmp( value, "a-only" ) )
2227        {
2228            nvram_nset( value, "%s_net_mode", prefix );
2229            nvram_nset( "0", "%s_nmode", prefix );
2230            if( !has_mimo( prefix ) )
2231                nvram_nset( "a", "%s_phytype", prefix );
2232            nvram_nset( "0", "%s_nreqd", prefix );
2233            nvram_nset( "1", "%s_nband", prefix );
2234        }
2235}
2236
2237void validate_wl_net_mode( webs_t wp, char *value, struct variable *v )
2238{
2239
2240    if( !valid_choice( wp, value, v ) )
2241        return;
2242
2243    convert_wl_gmode( value, "wl" );
2244
2245    nvram_set( v->name, value );
2246}
2247
2248#ifdef HAVE_PPPOESERVER
2249
2250void validate_chaps( webs_t wp, char *value, struct variable *v )
2251{
2252
2253    int i, error = 0;
2254    char *buf, *cur;
2255    int count, sof;
2256    struct variable chaps_variables[] = {
2257      {argv:ARGV( "30" )},
2258      {argv:ARGV( "30" )},
2259        {NULL},
2260    }, *which;
2261    buf = nvram_safe_get( "pppoeserver_chapsnum" );
2262    if( buf == NULL || strlen( buf ) == 0 )
2263        return;
2264    count = atoi( buf );
2265    sof = ( count * 128 ) + 1;
2266    buf = ( char * )malloc( sof );
2267    cur = buf;
2268    buf[0] = 0;
2269
2270    for( i = 0; i < count; i++ )
2271    {
2272
2273        char chap_user[] = "userXXX";
2274        char chap_pass[] = "passXXX";
2275        char chap_ip[] = "ipXXX";
2276        char chap_enable[] = "enableXXX";
2277        char *user = "", new_user[200] = "", *pass = "", new_pass[200] =
2278            "", *ip = "", *enable = "";
2279
2280        snprintf( chap_user, sizeof( chap_user ), "user%d", i );
2281        snprintf( chap_pass, sizeof( chap_pass ), "pass%d", i );
2282        snprintf( chap_ip, sizeof( chap_ip ), "ip%d", i );
2283        snprintf( chap_enable, sizeof( chap_enable ), "enable%d", i );
2284
2285        user = websGetVar( wp, chap_user, "" );
2286        pass = websGetVar( wp, chap_pass, "" );
2287        ip = websGetVar( wp, chap_ip, "0" );
2288        enable = websGetVar( wp, chap_enable, "off" );
2289
2290        which = &chaps_variables[0];
2291
2292        if( !*ip )
2293            continue;
2294        if( !strcmp( ip, "0" ) || !strcmp( ip, "" ) )
2295            continue;
2296
2297        /*
2298         * check name
2299         */
2300        if( strcmp( user, "" ) )
2301        {
2302            if( !valid_name( wp, user, &which[0] ) )
2303            {
2304                continue;
2305            }
2306            else
2307            {
2308                httpd_filter_name( user, new_user, sizeof( new_user ), SET );
2309            }
2310        }
2311
2312        if( strcmp( pass, "" ) )
2313        {
2314            if( !valid_name( wp, pass, &which[1] ) )
2315            {
2316                continue;
2317            }
2318            else
2319            {
2320                httpd_filter_name( pass, new_pass, sizeof( new_pass ), SET );
2321            }
2322        }
2323
2324        /*
2325         * check ip address
2326         */
2327        if( !*ip )
2328        {
2329            error = 1;
2330            // websWrite(wp, "Invalid <b>%s</b> : must specify a
2331            // ip<br>",which[4].longname);
2332            continue;
2333        }
2334
2335        if( sv_valid_ipaddr( ip ) )
2336        {
2337            cur += snprintf( cur, buf + sof - cur, "%s%s:%s:%s:%s",
2338                             cur == buf ? "" : " ", new_user, new_pass, ip,
2339                             enable );
2340        }
2341        else
2342        {
2343            error = 1;
2344            continue;
2345        }
2346
2347    }
2348    if( !error )
2349        nvram_set( v->name, buf );
2350    free( buf );
2351}
2352#endif
2353#ifdef HAVE_MILKFISH
2354
2355void validate_aliases( webs_t wp, char *value, struct variable *v )
2356{
2357
2358    int i, error = 0;
2359    char *buf, *cur;
2360    int count, sof;
2361    struct variable alias_variables[] = {
2362      {argv:ARGV( "30" )},
2363      {argv:ARGV( "30" )},
2364        {NULL},
2365    }, *which;
2366    buf = nvram_safe_get( "milkfish_ddaliasesnum" );
2367    if( buf == NULL || strlen( buf ) == 0 )
2368        return;
2369    count = atoi( buf );
2370    sof = ( count * 128 ) + 1;
2371    buf = ( char * )malloc( sof );
2372    cur = buf;
2373    buf[0] = 0;
2374
2375    for( i = 0; i < count; i++ )
2376    {
2377
2378        char alias_user[] = "userXXX";
2379        char alias_pass[] = "passXXX";
2380        char *user = "", new_user[200] = "", *pass = "", new_pass[200] = "";
2381
2382        snprintf( alias_user, sizeof( alias_user ), "user%d", i );
2383        snprintf( alias_pass, sizeof( alias_pass ), "pass%d", i );
2384
2385        user = websGetVar( wp, alias_user, "" );
2386        pass = websGetVar( wp, alias_pass, "" );
2387
2388        which = &alias_variables[0];
2389        if( strcmp( user, "" ) )
2390        {
2391            if( !valid_name( wp, user, &which[0] ) )
2392            {
2393                continue;
2394            }
2395            else
2396            {
2397                httpd_filter_name( user, new_user, sizeof( new_user ), SET );
2398            }
2399        }
2400
2401        if( strcmp( pass, "" ) )
2402        {
2403            if( !valid_name( wp, pass, &which[1] ) )
2404            {
2405                continue;
2406            }
2407            else
2408            {
2409                httpd_filter_name( pass, new_pass, sizeof( new_pass ), SET );
2410            }
2411        }
2412        cur += snprintf( cur, buf + sof - cur, "%s%s:%s",
2413                         cur == buf ? "" : " ", new_user, new_pass );
2414
2415    }
2416    if( !error )
2417        nvram_set( v->name, buf );
2418    free( buf );
2419
2420}
2421
2422void validate_subscribers( webs_t wp, char *value, struct variable *v )
2423{
2424
2425    int i, error = 0;
2426    char *buf, *cur;
2427    int count, sof;
2428    struct variable subscriber_variables[] = {
2429      {argv:ARGV( "30" )},
2430      {argv:ARGV( "30" )},
2431        {NULL},
2432    }, *which;
2433    buf = nvram_safe_get( "milkfish_ddsubscribersnum" );
2434    if( buf == NULL || strlen( buf ) == 0 )
2435        return;
2436    count = atoi( buf );
2437    sof = ( count * 128 ) + 1;
2438    buf = ( char * )malloc( sof );
2439    cur = buf;
2440    buf[0] = 0;
2441
2442    for( i = 0; i < count; i++ )
2443    {
2444
2445        char subscriber_user[] = "userXXX";
2446        char subscriber_pass[] = "passXXX";
2447        char *user = "", new_user[200] = "", *pass = "", new_pass[200] = "";
2448
2449        snprintf( subscriber_user, sizeof( subscriber_user ), "user%d", i );
2450        snprintf( subscriber_pass, sizeof( subscriber_pass ), "pass%d", i );
2451
2452        user = websGetVar( wp, subscriber_user, "" );
2453        pass = websGetVar( wp, subscriber_pass, "" );
2454
2455        which = &subscriber_variables[0];
2456        if( strcmp( user, "" ) )
2457        {
2458            if( !valid_name( wp, user, &which[0] ) )
2459            {
2460                continue;
2461            }
2462            else
2463            {
2464                httpd_filter_name( user, new_user, sizeof( new_user ), SET );
2465            }
2466        }
2467
2468        if( strcmp( pass, "" ) )
2469        {
2470            if( !valid_name( wp, pass, &which[1] ) )
2471            {
2472                continue;
2473            }
2474            else
2475            {
2476                httpd_filter_name( pass, new_pass, sizeof( new_pass ), SET );
2477            }
2478        }
2479        cur += snprintf( cur, buf + sof - cur, "%s%s:%s",
2480                         cur == buf ? "" : " ", new_user, new_pass );
2481
2482    }
2483    if( !error )
2484        nvram_set( v->name, buf );
2485    free( buf );
2486
2487}
2488#endif
2489
2490#ifdef HAVE_RADLOCAL
2491void validate_iradius( webs_t wp, char *value, struct variable *v )
2492{
2493    char username[32] = "iradiusxxx_name";
2494    char active[32] = "iradiusxxx_active";
2495    char del[32] = "iradiusxxx_delete";
2496
2497    char *sln = nvram_safe_get( "iradius_count" );
2498
2499    if( sln == NULL || strlen( sln ) == 0 )
2500        return;
2501    int leasenum = atoi( sln );
2502
2503    if( leasenum == 0 )
2504        return;
2505    char *leases;
2506    int i;
2507
2508    leases = ( char * )malloc( ( 128 * leasenum ) + 1 );
2509    memset( leases, 0, ( 128 * leasenum ) + 1 );
2510    int leasen = 0;
2511
2512    cprintf( "build mac list\n" );
2513
2514    struct timeval now;
2515
2516    gettimeofday( &now, NULL );
2517
2518    for( i = 0; i < leasenum; i++ )
2519    {
2520        snprintf( del, 31, "iradius%d_delete", i );
2521        char *d = websGetVar( wp, del, "" );
2522
2523        cprintf( "radius delete = %s\n", d );
2524        if( strcmp( d, "1" ) == 0 )
2525            continue;
2526
2527        snprintf( username, 31, "iradius%d_name", i );
2528        strcat( leases, websGetVar( wp, username, "00:00:00:00:00:00" ) );
2529        strcat( leases, " " );
2530
2531        snprintf( active, 31, "iradius%d_active", i );
2532        strcat( leases, websGetVar( wp, active, "0" ) );
2533        strcat( leases, " " );
2534
2535        snprintf( active, 31, "iradius%d_lease", i );
2536        char *time = websGetVar( wp, active, "-1" );
2537        int t = -1;
2538
2539        if( strcmp( time, "over" ) )
2540            t = atoi( time );
2541        if( t == -1 )
2542        {
2543            strcat( leases, "-1" );
2544        }
2545        else
2546        {
2547            char st[32];
2548
2549            sprintf( st, "%ld", ( now.tv_sec + t * 60 ) );
2550            strcat( leases, st );
2551        }
2552        strcat( leases, " " );
2553
2554        leasen++;
2555    }
2556
2557    cprintf( "done %s\n", leases );
2558    nvram_store_collection( "iradius", leases );
2559    cprintf( "stored\n" );
2560    char nr[16];
2561
2562    sprintf( nr, "%d", leasen );
2563    nvram_set( "iradius_count", nr );
2564    nvram_commit(  );
2565    free( leases );
2566}
2567#endif
2568
2569#ifdef HAVE_CHILLILOCAL
2570void validate_userlist( webs_t wp, char *value, struct variable *v )
2571{
2572    char username[32] = "fon_userxxx_name";
2573    char password[32] = "fon_userxxx_password";
2574    char *sln = nvram_safe_get( "fon_usernames" );
2575
2576    if( sln == NULL || strlen( sln ) == 0 )
2577        return;
2578    int leasenum = atoi( sln );
2579
2580    if( leasenum == 0 )
2581        return;
2582    char *leases;
2583    int i;
2584
2585    leases = ( char * )malloc( ( 128 * leasenum ) + 1 );
2586    memset( leases, 0, ( 128 * leasenum ) + 1 );
2587
2588    for( i = 0; i < leasenum; i++ )
2589    {
2590        snprintf( username, 31, "fon_user%d_name", i );
2591        strcat( leases, websGetVar( wp, username, "" ) );
2592        strcat( leases, "=" );
2593        snprintf( password, 31, "fon_user%d_password", i );
2594        strcat( leases, websGetVar( wp, password, "" ) );
2595        strcat( leases, " " );
2596    }
2597    nvram_set( "fon_userlist", leases );
2598    nvram_commit(  );
2599    free( leases );
2600}
2601
2602#endif
2603
2604void filterstring( char *str, char character )
2605{
2606    if( str == NULL )
2607        return;
2608    int c;
2609    int i;
2610    int len = strlen( str );
2611
2612    c = 0;
2613    for( i = 0; i < len; i++ )
2614    {
2615        if( str[i] != character )
2616            str[c++] = str[i];
2617    }
2618    str[c++] = 0;
2619}
2620
2621char *buildmac( char *in )
2622{
2623    char mac[20];
2624    char *outmac;
2625
2626    outmac = malloc( 20 );
2627    strncpy( mac, in, 20 );
2628    filterstring( mac, ':' );
2629    filterstring( mac, '-' );
2630    filterstring( mac, ' ' );
2631    if( strlen( mac ) != 12 )
2632    {
2633        free( outmac );
2634        return NULL;            // error. invalid mac
2635    }
2636    int i;
2637    int c = 0;
2638
2639    for( i = 0; i < 12; i += 2 )
2640    {
2641        outmac[c++] = mac[i];
2642        outmac[c++] = mac[i + 1];
2643        if( i < 10 )
2644            outmac[c++] = ':';
2645    }
2646    outmac[c++] = 0;
2647    return outmac;
2648}
2649
2650void validate_staticleases( webs_t wp, char *value, struct variable *v )
2651{
2652    char lease_hwaddr[32] = "leasexxx_hwaddr";
2653    char lease_hostname[32] = "leasexxx_hostname";
2654    char lease_ip[32] = "leasexxx_ip";
2655    char *sln = nvram_safe_get( "static_leasenum" );
2656    char *hwaddr;
2657
2658    if( sln == NULL || strlen( sln ) == 0 )
2659        return;
2660    int leasenum = atoi( sln );
2661
2662    if( leasenum == 0 )
2663        return;
2664    char *leases;
2665    int i;
2666
2667    leases = ( char * )malloc( ( 54 * leasenum ) + 1 );
2668    memset( leases, 0, ( 54 * leasenum ) + 1 );
2669
2670    for( i = 0; i < leasenum; i++ )
2671    {
2672        snprintf( lease_hwaddr, 31, "lease%d_hwaddr", i );
2673        hwaddr = websGetVar( wp, lease_hwaddr, NULL );
2674        if( hwaddr == NULL )
2675            break;
2676        char *mac = buildmac( hwaddr );
2677
2678        if( mac == NULL )
2679        {
2680            free( leases );
2681            websError( wp, 400, "%s is not a valid mac adress\n", hwaddr );
2682            return;
2683        }
2684        strcat( leases, mac );
2685        free( mac );
2686        snprintf( lease_hostname, 31, "lease%d_hostname", i );
2687        char *hostname = websGetVar( wp, lease_hostname, NULL );
2688
2689        snprintf( lease_ip, 31, "lease%d_ip", i );
2690        char *ip = websGetVar( wp, lease_ip, "" );
2691
2692        if( hostname == NULL || strlen( hostname ) == 0 || ip == NULL
2693            || strlen( ip ) == 0 )
2694            break;
2695        strcat( leases, "=" );
2696        strcat( leases, hostname );
2697        strcat( leases, "=" );
2698        strcat( leases, ip );
2699        strcat( leases, " " );
2700    }
2701    nvram_set( "static_leases", leases );
2702    nvram_commit(  );
2703    free( leases );
2704}
2705
2706void dhcp_check( webs_t wp, char *value, struct variable *v )
2707{
2708    return;                     // The udhcpd can valid lease table when
2709    // re-load udhcpd.leases. by honor 2003-08-05
2710}
2711
2712void validate_wds( webs_t wp, char *value, struct variable *v )
2713{
2714#ifdef HAVE_MADWIFI
2715    int h, i, devcount = 0;     // changed from 2 to 3
2716#elif HAVE_MSSID
2717    int h, i, devcount = 1;     // changed from 2 to 3
2718#else
2719    int h, i, devcount = 3;     // changed from 2 to 3
2720#endif
2721    struct variable wds_variables[] = {
2722      {argv:NULL},
2723      {argv:NULL},
2724      {argv:NULL},
2725      {argv:NULL},
2726      {argv:NULL},
2727    };
2728
2729    char *val = NULL;
2730    char wds[32] = "";
2731    char wdsif_var[32] = "";
2732    char enabled_var[32];
2733    char hwaddr_var[32] = "";
2734    char ipaddr_var[32] = "";
2735    char netmask_var[32] = "";
2736    char desc_var[32] = "";
2737    char hwaddr[18] = "";
2738    char ipaddr[16] = "";
2739    char netmask[16] = "";
2740    char desc[48] = "";
2741    char wds_if[32] = { 0 };
2742    char wds_list[199] = "";
2743    char *interface = websGetVar( wp, "interface", NULL );
2744
2745    if( interface == NULL )
2746        return;
2747
2748    char wl0wds[32];
2749
2750    sprintf( wl0wds, "%s_wds", interface );
2751    nvram_set( wl0wds, "" );
2752    snprintf( wds, 31, "%s_br1", interface );
2753    snprintf( enabled_var, 31, "%s_enable", wds );
2754    cprintf( "wds_validate\n" );
2755    /*
2756     * validate separate br1 bridge params
2757     */
2758    if( nvram_match( enabled_var, "1" ) )
2759    {
2760
2761        memset( ipaddr, 0, sizeof( ipaddr ) );
2762        memset( netmask, 0, sizeof( netmask ) );
2763
2764        // disable until validated
2765        nvram_set( enabled_var, "0" );
2766
2767        // subnet params validation
2768        for( i = 0; i < 4; i++ )
2769        {
2770
2771            snprintf( ipaddr_var, 31, "%s_%s%d", wds, "ipaddr", i );
2772            val = websGetVar( wp, ipaddr_var, NULL );
2773            if( val )
2774            {
2775                strcat( ipaddr, val );
2776                if( i < 3 )
2777                    strcat( ipaddr, "." );
2778            }
2779            else
2780                break;
2781
2782            snprintf( netmask_var, 31, "%s_%s%d", wds, "netmask", i );
2783            val = websGetVar( wp, netmask_var, NULL );
2784            if( val )
2785            {
2786                strcat( netmask, val );
2787
2788                if( i < 3 )
2789                    strcat( netmask, "." );
2790            }
2791            else
2792                break;
2793        }
2794
2795        if( !valid_ipaddr( wp, ipaddr, &wds_variables[1] ) ||
2796            !valid_netmask( wp, netmask, &wds_variables[2] ) )
2797            return;
2798
2799        snprintf( ipaddr_var, 31, "%s_%s", wds, "ipaddr" );
2800        snprintf( netmask_var, 31, "%s_%s", wds, "netmask" );
2801
2802        nvram_set( enabled_var, "1" );
2803        snprintf( ipaddr_var, 31, "%s_%s%d", wds, "ipaddr", i );
2804        nvram_set( ipaddr_var, ipaddr );
2805        snprintf( netmask_var, 31, "%s_%s%d", wds, "netmask", i );
2806        nvram_set( netmask_var, netmask );
2807    }
2808    else
2809        nvram_set( enabled_var, "0" );
2810
2811    for( h = 1; h <= MAX_WDS_DEVS; h++ )
2812    {
2813        memset( hwaddr, 0, sizeof( hwaddr ) );
2814        memset( desc, 0, sizeof( desc ) );
2815        snprintf( wds, 31, "%s_wds%d", interface, h );
2816        snprintf( enabled_var, 31, "%s_enable", wds );
2817
2818        for( i = 0; i < 6; i++ )
2819        {
2820
2821            snprintf( hwaddr_var, 31, "%s_%s%d", wds, "hwaddr", i );
2822            val = websGetVar( wp, hwaddr_var, NULL );
2823
2824            if( val )
2825            {
2826                strcat( hwaddr, val );
2827                if( i < 5 )
2828                    strcat( hwaddr, ":" );
2829            }
2830        }
2831
2832        if( !valid_hwaddr( wp, hwaddr, &wds_variables[0] ) )
2833        {
2834            return;
2835        }
2836
2837        snprintf( hwaddr_var, 31, "%s_%s", wds, "hwaddr" );
2838        nvram_set( hwaddr_var, hwaddr );
2839
2840        snprintf( desc_var, 31, "%s_%s", wds, "desc" );
2841        val = websGetVar( wp, desc_var, NULL );
2842        if( val )
2843        {
2844            strcat( desc, val );
2845            snprintf( desc_var, 31, "%s_%s", wds, "desc" );
2846            nvram_set( desc_var, desc );
2847        }
2848
2849        /*
2850         * <lonewolf>
2851         */
2852        snprintf( desc_var, 31, "%s_%s", wds, "ospf" );
2853        val = websGetVar( wp, desc_var, "" );
2854        if( val )
2855        {
2856            snprintf( desc_var, 31, "%s_%s", wds, "ospf" );
2857            nvram_set( desc_var, val );
2858        }
2859        /*
2860         * </lonewolf>
2861         */
2862
2863        if( strcmp( hwaddr, "00:00:00:00:00:00" )
2864            && nvram_invmatch( enabled_var, "0" ) )
2865        {
2866            snprintf( wds_list, 199, "%s %s", wds_list, hwaddr );
2867        }
2868
2869        if( nvram_match( enabled_var, "1" ) )
2870        {
2871
2872            memset( ipaddr, 0, sizeof( ipaddr ) );
2873            memset( netmask, 0, sizeof( netmask ) );
2874
2875            // disable until validated
2876            nvram_set( enabled_var, "0" );
2877
2878            // subnet params validation
2879            for( i = 0; i < 4; i++ )
2880            {
2881
2882                snprintf( ipaddr_var, 31, "%s_%s%d", wds, "ipaddr", i );
2883                val = websGetVar( wp, ipaddr_var, NULL );
2884                if( val )
2885                {
2886                    strcat( ipaddr, val );
2887                    if( i < 3 )
2888                        strcat( ipaddr, "." );
2889                }
2890                else
2891                    break;
2892
2893                snprintf( netmask_var, 31, "%s_%s%d", wds, "netmask", i );
2894                val = websGetVar( wp, netmask_var, NULL );
2895                if( val )
2896                {
2897                    strcat( netmask, val );
2898
2899                    if( i < 3 )
2900                        strcat( netmask, "." );
2901                }
2902                else
2903                    break;
2904            }
2905
2906            if( !valid_ipaddr( wp, ipaddr, &wds_variables[1] ) ||
2907                !valid_netmask( wp, netmask, &wds_variables[2] ) )
2908            {
2909                continue;
2910            }
2911
2912            snprintf( ipaddr_var, 31, "%s_%s", wds, "ipaddr" );
2913            snprintf( netmask_var, 31, "%s_%s", wds, "netmask" );
2914
2915            nvram_set( enabled_var, "1" );
2916            nvram_set( ipaddr_var, ipaddr );
2917            nvram_set( netmask_var, netmask );
2918        }
2919
2920        /*
2921         * keep the wds devices in sync w enabled entries
2922         */
2923        snprintf( wdsif_var, 31, "%s_if", wds );
2924        if( !nvram_match( enabled_var, "0" ) )
2925        {
2926#ifdef HAVE_MADWIFI
2927            snprintf( wds_if, 31, "%s.wds%d", interface, ( devcount++ ) );
2928#else
2929            // quick and dirty
2930            if( !strcmp( interface, "wl0" ) )
2931                snprintf( wds_if, 31, "wds0.%d", ( devcount++ ) );
2932            else if( !strcmp( interface, "wl1" ) )
2933                snprintf( wds_if, 31, "wds1.%d", ( devcount++ ) );
2934            else
2935                snprintf( wds_if, 31, "wds%d.%d",
2936                          get_wl_instance( interface ), ( devcount++ ) );
2937#endif
2938            nvram_set( wdsif_var, wds_if );
2939        }
2940        else
2941            nvram_unset( wdsif_var );
2942
2943    }
2944
2945    nvram_set( wl0wds, wds_list );
2946}
2947
2948void validate_filter_ip_grp( webs_t wp, char *value, struct variable *v )
2949{
2950    D( "validate_filter_ip_grp" );
2951    int i = 0;
2952    char buf[256] = "";
2953    char *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip_range0_0, *ip_range0_1,
2954        *ip_range1_0, *ip_range1_1;
2955    unsigned char ip[10] = { 0, 0, 0, 0, 0, 0, 0 };
2956    struct variable filter_ip_variables[] = {
2957      {argv:ARGV( "0", "255" )},
2958    }, *which;
2959    char _filter_ip[] = "filter_ip_grpXXX";
2960
2961    // char _filter_rule[] = "filter_ruleXXX";
2962    // char _filter_tod[] = "filter_todXXX";
2963
2964    which = &filter_ip_variables[0];
2965
2966    ip0 = websGetVar( wp, "ip0", "0" );
2967    ip1 = websGetVar( wp, "ip1", "0" );
2968    ip2 = websGetVar( wp, "ip2", "0" );
2969    ip3 = websGetVar( wp, "ip3", "0" );
2970    ip4 = websGetVar( wp, "ip4", "0" );
2971    ip5 = websGetVar( wp, "ip5", "0" );
2972    ip_range0_0 = websGetVar( wp, "ip_range0_0", "0" );
2973    ip_range0_1 = websGetVar( wp, "ip_range0_1", "0" );
2974    ip_range1_0 = websGetVar( wp, "ip_range1_0", "0" );
2975    ip_range1_1 = websGetVar( wp, "ip_range1_1", "0" );
2976
2977    if( !valid_range( wp, ip0, &which[0] ) ||
2978        !valid_range( wp, ip1, &which[0] ) ||
2979        !valid_range( wp, ip2, &which[0] ) ||
2980        !valid_range( wp, ip3, &which[0] ) ||
2981        !valid_range( wp, ip4, &which[0] ) ||
2982        !valid_range( wp, ip5, &which[0] ) ||
2983        !valid_range( wp, ip_range0_0, &which[0] ) ||
2984        !valid_range( wp, ip_range0_1, &which[0] ) ||
2985        !valid_range( wp, ip_range1_0, &which[0] ) ||
2986        !valid_range( wp, ip_range1_0, &which[0] ) )
2987    {
2988        D( "invalid range, return" );
2989        return;
2990    }
2991
2992    if( atoi( ip0 ) )
2993        ip[i++] = atoi( ip0 );
2994    if( atoi( ip1 ) )
2995        ip[i++] = atoi( ip1 );
2996    if( atoi( ip2 ) )
2997        ip[i++] = atoi( ip2 );
2998    if( atoi( ip3 ) )
2999        ip[i++] = atoi( ip3 );
3000    if( atoi( ip4 ) )
3001        ip[i++] = atoi( ip4 );
3002    if( atoi( ip5 ) )
3003        ip[i++] = atoi( ip5 );
3004
3005    if( atoi( ip_range0_0 ) > atoi( ip_range0_1 ) )
3006        SWAP( ip_range0_0, ip_range0_1 );
3007
3008    if( atoi( ip_range1_0 ) > atoi( ip_range1_1 ) )
3009        SWAP( ip_range1_0, ip_range1_1 );
3010
3011    sprintf( buf, "%d %d %d %d %d %d %s-%s %s-%s", ip[0], ip[1], ip[2], ip[3],
3012             ip[4], ip[5], ip_range0_0, ip_range0_1, ip_range1_0,
3013             ip_range1_1 );
3014
3015    snprintf( _filter_ip, sizeof( _filter_ip ), "filter_ip_grp%s",
3016              nvram_safe_get( "filter_id" ) );
3017    nvram_set( _filter_ip, buf );
3018
3019    // snprintf(_filter_rule, sizeof(_filter_rule), "filter_rule%s",
3020    // nvram_safe_get("filter_id"));
3021    // snprintf(_filter_tod, sizeof(_filter_tod), "filter_tod%s",
3022    // nvram_safe_get("filter_id"));
3023    // if(nvram_match(_filter_rule, "")){
3024    // nvram_set(_filter_rule, "$STAT:1$NAME:$$");
3025    // nvram_set(_filter_tod, "0:0 23:59 0-6");
3026    // }
3027    D( "success return" );
3028
3029}
3030
3031/*
3032 * Example: tcp:100-200 udp:210-220 both:250-260
3033 */
3034
3035void validate_filter_port( webs_t wp, char *value, struct variable *v )
3036{
3037    int i;
3038    char buf[1000] = "", *cur = buf;
3039    struct variable filter_port_variables[] = {
3040      {argv:ARGV( "0",
3041              "65535" )},
3042      {argv:ARGV( "0",
3043              "65535" )},
3044    }, *which;
3045    D( "validate_filter_port" );
3046    which = &filter_port_variables[0];
3047
3048    for( i = 0; i < FILTER_PORT_NUM; i++ )
3049    {
3050        char filter_port[] = "protoXXX";
3051        char filter_port_start[] = "startXXX";
3052        char filter_port_end[] = "endXXX";
3053        char *port, *start, *end;
3054        char *temp;
3055
3056        snprintf( filter_port, sizeof( filter_port ), "proto%d", i );
3057        snprintf( filter_port_start, sizeof( filter_port_start ), "start%d",
3058                  i );
3059        snprintf( filter_port_end, sizeof( filter_port_end ), "end%d", i );
3060        port = websGetVar( wp, filter_port, NULL );
3061        start = websGetVar( wp, filter_port_start, NULL );
3062        end = websGetVar( wp, filter_port_end, NULL );
3063
3064        if( !port || !start || !end )
3065            continue;
3066
3067        if( !*start && !*end )
3068            continue;
3069
3070        if( ( !strcmp( start, "0" ) || !strcmp( start, "" ) ) &&
3071            ( !strcmp( end, "0" ) || !strcmp( end, "" ) ) )
3072            continue;
3073
3074        if( !*start || !*end )
3075        {
3076            // websWrite(wp, "Invalid <b>%s</b>: must specify a LAN Port
3077            // Range<br>", v->longname);
3078            continue;
3079        }
3080        if( !valid_range( wp, start, &which[0] )
3081            || !valid_range( wp, end, &which[1] ) )
3082        {
3083            continue;
3084        }
3085        if( atoi( start ) > atoi( end ) )
3086        {
3087            temp = start;
3088            start = end;
3089            end = temp;
3090        }
3091        cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s:%d-%d",
3092                         cur == buf ? "" : " ", port, atoi( start ),
3093                         atoi( end ) );
3094    }
3095
3096    nvram_set( v->name, buf );
3097    D( "success return" );
3098}
3099
3100void validate_filter_dport_grp( webs_t wp, char *value, struct variable *v )
3101{
3102    int i;
3103    char buf[1000] = "", *cur = buf;
3104    struct variable filter_port_variables[] = {
3105      {argv:ARGV( "0",
3106              "65535" )},
3107      {argv:ARGV( "0",
3108              "65535" )},
3109    }, *which;
3110    char _filter_port[] = "filter_dport_grpXXX";
3111
3112    // char _filter_rule[] = "filter_ruleXXX";
3113    // char _filter_tod[] = "filter_todXXX";
3114    D( "validate_filter-dport-grp" );
3115    which = &filter_port_variables[0];
3116
3117    for( i = 0; i < FILTER_PORT_NUM; i++ )
3118    {
3119        char filter_port[] = "protoXXX";
3120        char filter_port_start[] = "startXXX";
3121        char filter_port_end[] = "endXXX";
3122        char *port, *start, *end;
3123        char *temp;
3124
3125        snprintf( filter_port, sizeof( filter_port ), "proto%d", i );
3126        snprintf( filter_port_start, sizeof( filter_port_start ), "start%d",
3127                  i );
3128        snprintf( filter_port_end, sizeof( filter_port_end ), "end%d", i );
3129        port = websGetVar( wp, filter_port, NULL );
3130        start = websGetVar( wp, filter_port_start, NULL );
3131        end = websGetVar( wp, filter_port_end, NULL );
3132
3133        if( !port || !start || !end )
3134            continue;
3135
3136        if( !*start && !*end )
3137            continue;
3138
3139        if( ( !strcmp( start, "0" ) || !strcmp( start, "" ) ) &&
3140            ( !strcmp( end, "0" ) || !strcmp( end, "" ) ) )
3141            continue;
3142
3143        if( !*start || !*end )
3144        {
3145            // websWrite(wp, "Invalid <b>%s</b>: must specify a LAN Port
3146            // Range<br>", v->longname);
3147            continue;
3148        }
3149        if( !valid_range( wp, start, &which[0] )
3150            || !valid_range( wp, end, &which[1] ) )
3151        {
3152            continue;
3153        }
3154        if( atoi( start ) > atoi( end ) )
3155        {
3156            temp = start;
3157            start = end;
3158            end = temp;
3159        }
3160        cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s:%d-%d",
3161                         cur == buf ? "" : " ", port, atoi( start ),
3162                         atoi( end ) );
3163    }
3164
3165    snprintf( _filter_port, sizeof( _filter_port ), "filter_dport_grp%s",
3166              nvram_safe_get( "filter_id" ) );
3167    nvram_set( _filter_port, buf );
3168
3169    // snprintf(_filter_rule, sizeof(_filter_rule), "filter_rule%s",
3170    // nvram_safe_get("filter_id"));
3171    // snprintf(_filter_tod, sizeof(_filter_tod), "filter_tod%s",
3172    // nvram_safe_get("filter_id"));
3173    // if(nvram_match(_filter_rule, "")){
3174    // nvram_set(_filter_rule, "$STAT:1$NAME:$$");
3175    // nvram_set(_filter_tod, "0:0 23:59 0-6");
3176    // }
3177    D( "success return" );
3178}
3179
3180/*
3181 * Example: 2 00:11:22:33:44:55 00:11:22:33:44:56
3182 */
3183
3184void validate_filter_mac_grp( webs_t wp, char *value, struct variable *v )
3185{
3186
3187    int i;
3188    char buf[1000] = "", *cur = buf;
3189    char _filter_mac[] = "filter_mac_grpXXX";
3190
3191    // char _filter_rule[] = "filter_ruleXXX";
3192    // har _filter_tod[] = "filter_todXXX";
3193    D( "validate_filter__mac_grp" );
3194
3195    for( i = 0; i < FILTER_MAC_NUM; i++ )
3196    {
3197        char filter_mac[] = "macXXX";
3198        char *mac, mac1[20] = "";
3199
3200        snprintf( filter_mac, sizeof( filter_mac ), "mac%d", i );
3201
3202        mac = websGetVar( wp, filter_mac, NULL );
3203        if( !mac )
3204            continue;
3205
3206        if( strcmp( mac, "" ) && strcmp( mac, "00:00:00:00:00:00" )
3207            && strcmp( mac, "000000000000" ) )
3208        {
3209            if( strlen( mac ) == 12 )
3210            {
3211                char hex[] = "XX";
3212                unsigned char h;
3213
3214                while( *mac )
3215                {
3216                    strncpy( hex, mac, 2 );
3217                    h = ( unsigned char )strtoul( hex, NULL, 16 );
3218                    if( strlen( mac1 ) )
3219                        sprintf( mac1 + strlen( mac1 ), ":" );
3220                    sprintf( mac1 + strlen( mac1 ), "%02X", h );
3221                    mac += 2;
3222                }
3223                mac1[17] = '\0';
3224            }
3225            else if( strlen( mac ) == 17 )
3226            {
3227                strcpy( mac1, mac );
3228            }
3229            if( !valid_hwaddr( wp, mac1, v ) )
3230            {
3231                continue;
3232            }
3233        }
3234        else
3235        {
3236            continue;
3237        }
3238        cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s",
3239                         cur == buf ? "" : " ", mac1 );
3240    }
3241
3242    snprintf( _filter_mac, sizeof( _filter_mac ), "filter_mac_grp%s",
3243              nvram_safe_get( "filter_id" ) );
3244    nvram_set( _filter_mac, buf );
3245
3246    // snprintf(_filter_rule, sizeof(_filter_rule), "filter_rule%s",
3247    // nvram_safe_get("filter_id"));
3248    // snprintf(_filter_tod, sizeof(_filter_tod), "filter_tod%s",
3249    // nvram_safe_get("filter_id"));
3250    // if(nvram_match(_filter_rule, "")){
3251    // nvram_set(_filter_rule, "$STAT:1$NAME:$$");
3252    // nvram_set(_filter_tod, "0:0 23:59 0-6");
3253    // }
3254    D( "success return" );
3255}
3256
3257/*
3258 * Format: url0=www.kimo.com.tw, ...  keywd0=sex, ...
3259 */
3260void validate_filter_web( webs_t wp, char *value, struct variable *v )
3261{
3262    int i;
3263    char buf[1000] = "", *cur = buf;
3264    char buf1[1000] = "", *cur1 = buf1;
3265    char filter_host[] = "filter_web_hostXXX";
3266    char filter_url[] = "filter_web_urlXXX";
3267
3268    D( "validate_filter_web" );
3269    /*
3270     * Handle Website Blocking by URL Address
3271     */
3272    for( i = 0; i < 9; i++ )
3273    {
3274        char filter_host[] = "hostXXX";
3275        char *host;
3276
3277        snprintf( filter_host, sizeof( filter_host ), "host%d", i );
3278        host = websGetVar( wp, filter_host, "" );
3279
3280        if( !strcmp( host, "" ) )
3281            continue;
3282        int offset = 0;
3283
3284        if( startswith( host, "http://" ) )
3285            offset = 7;
3286        cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s",
3287                         cur == buf ? "" : "<&nbsp;>", &host[offset] );
3288    }
3289
3290    if( strcmp( buf, "" ) )
3291        strcat( buf, "<&nbsp;>" );
3292
3293    snprintf( filter_host, sizeof( filter_host ), "filter_web_host%s",
3294              nvram_safe_get( "filter_id" ) );
3295    nvram_set( filter_host, buf );
3296
3297    /*
3298     * Handle Website Blocking by Keyword
3299     */
3300    for( i = 0; i < 8; i++ )
3301    {
3302        char filter_url[] = "urlXXX";
3303        char *url;
3304
3305        snprintf( filter_url, sizeof( filter_url ), "url%d", i );
3306        url = websGetVar( wp, filter_url, "" );
3307
3308        if( !strcmp( url, "" ) )
3309            continue;
3310
3311        cur1 += snprintf( cur1, buf1 + sizeof( buf1 ) - cur1, "%s%s",
3312                          cur1 == buf1 ? "" : "<&nbsp;>", url );
3313    }
3314    if( strcmp( buf1, "" ) )
3315        strcat( buf1, "<&nbsp;>" );
3316
3317    snprintf( filter_url, sizeof( filter_url ), "filter_web_url%s",
3318              nvram_safe_get( "filter_id" ) );
3319    nvram_set( filter_url, buf1 );
3320    D( "everything okay" );
3321}
3322
3323/*
3324 * Example: name:on:both:1000-2000>3000-4000
3325 */
3326
3327void validate_port_trigger( webs_t wp, char *value, struct variable *v )
3328{
3329    int i, error = 0;
3330    char *buf, *cur;
3331    int count, sof;
3332    struct variable trigger_variables[] = {
3333      {argv:ARGV( "12" )},
3334      {argv:ARGV( "0", "65535" )},
3335      {argv:ARGV( "0", "65535" )},
3336      {argv:ARGV( "0", "65535" )},
3337      {argv:ARGV( "0", "65535" )},
3338    }, *which;
3339
3340    buf = nvram_safe_get( "trigger_entries" );
3341    if( buf == NULL || strlen( buf ) == 0 )
3342        return;
3343    count = atoi( buf );
3344    sof = ( count * 46 ) + 1;
3345    buf = ( char * )malloc( sof );
3346    cur = buf;
3347    memset( buf, 0, sof );
3348
3349    for( i = 0; i < count; i++ )
3350    {
3351
3352        char trigger_name[] = "nameXXX";
3353        char trigger_enable[] = "enableXXX";
3354        char trigger_i_from[] = "i_fromXXX";
3355        char trigger_i_to[] = "i_toXXX";
3356        char trigger_o_from[] = "o_fromXXX";
3357        char trigger_o_to[] = "o_toXXX";
3358        char trigger_proto[] = "proXXX";
3359        char *name = "", *enable, new_name[200] = "", *i_from = "", *i_to =
3360            "", *o_from = "", *o_to = "", *proto = "both";
3361
3362        snprintf( trigger_name, sizeof( trigger_name ), "name%d", i );
3363        snprintf( trigger_enable, sizeof( trigger_enable ), "enable%d", i );
3364        snprintf( trigger_i_from, sizeof( trigger_i_from ), "i_from%d", i );
3365        snprintf( trigger_i_to, sizeof( trigger_i_to ), "i_to%d", i );
3366        snprintf( trigger_o_from, sizeof( trigger_o_from ), "o_from%d", i );
3367        snprintf( trigger_o_to, sizeof( trigger_o_to ), "o_to%d", i );
3368        snprintf( trigger_proto, sizeof( trigger_proto ), "pro%d", i );
3369
3370        name = websGetVar( wp, trigger_name, "" );
3371        enable = websGetVar( wp, trigger_enable, "off" );
3372        i_from = websGetVar( wp, trigger_i_from, NULL );
3373        i_to = websGetVar( wp, trigger_i_to, NULL );
3374        o_from = websGetVar( wp, trigger_o_from, NULL );
3375        o_to = websGetVar( wp, trigger_o_to, NULL );
3376        proto = websGetVar( wp, trigger_proto, "both" );
3377        which = &trigger_variables[0];
3378
3379        if( !i_from || !i_to || !o_from || !o_to )
3380            continue;
3381
3382        if( ( !strcmp( i_from, "0" ) || !strcmp( i_from, "" ) ) &&
3383            ( !strcmp( i_to, "0" ) || !strcmp( i_to, "" ) ) &&
3384            ( !strcmp( o_from, "0" ) || !strcmp( o_from, "" ) ) &&
3385            ( !strcmp( o_to, "0" ) || !strcmp( o_to, "" ) ) )
3386            continue;
3387
3388        if( !strcmp( i_from, "0" ) || !strcmp( i_from, "" ) )
3389            i_from = i_to;
3390        if( !strcmp( i_to, "0" ) || !strcmp( i_to, "" ) )
3391            i_to = i_from;
3392        if( !strcmp( o_from, "0" ) || !strcmp( o_from, "" ) )
3393            o_from = o_to;
3394        if( !strcmp( o_to, "0" ) || !strcmp( o_to, "" ) )
3395            o_to = o_from;
3396
3397        if( atoi( i_from ) > atoi( i_to ) )
3398            SWAP( i_from, i_to );
3399
3400        if( atoi( o_from ) > atoi( o_to ) )
3401            SWAP( o_from, o_to );
3402
3403        if( strcmp( name, "" ) )
3404        {
3405            if( !valid_name( wp, name, &which[0] ) )
3406            {
3407                error = 1;
3408                continue;
3409            }
3410            else
3411            {
3412                httpd_filter_name( name, new_name, sizeof( new_name ), SET );
3413            }
3414        }
3415
3416        if( !valid_range( wp, i_from, &which[1] )
3417            || !valid_range( wp, i_to, &which[2] )
3418            || !valid_range( wp, o_from, &which[3] )
3419            || !valid_range( wp, o_to, &which[4] ) )
3420        {
3421            error = 1;
3422            continue;
3423        }
3424
3425        cur += snprintf( cur, buf + sof - cur, "%s%s:%s:%s:%s-%s>%s-%s",
3426                         cur == buf ? "" : " ", new_name, enable, proto,
3427                         i_from, i_to, o_from, o_to );
3428
3429    }
3430
3431    if( !error )
3432        nvram_set( v->name, buf );
3433    free( buf );
3434}
3435
3436void validate_blocked_service( webs_t wp, char *value, struct variable *v )
3437{
3438    int i;
3439    char buf[1000] = "", *cur = buf;
3440    char port_grp[] = "filter_port_grpXXX";
3441
3442    D( "validate_blocked_service" );
3443    for( i = 0; i < BLOCKED_SERVICE_NUM; i++ )
3444    {
3445        char blocked_service[] = "blocked_serviceXXX";
3446        char *service;
3447
3448        snprintf( blocked_service, sizeof( blocked_service ),
3449                  "blocked_service%d", i );
3450        service = websGetVar( wp, blocked_service, NULL );
3451        if( !service || !strcmp( service, "None" ) )
3452            continue;
3453
3454        cur +=
3455            snprintf( cur, buf + sizeof( buf ) - cur, "%s%s", service,
3456                      "<&nbsp;>" );
3457        // cur == buf ? "" : "<&nbsp;>", service);
3458    }
3459
3460    snprintf( port_grp, sizeof( port_grp ), "filter_port_grp%s",
3461              nvram_safe_get( "filter_id" ) );
3462    nvram_set( port_grp, buf );
3463    D( "right" );
3464}
3465
3466/*
3467 * validates the p2p catchall filter
3468 */
3469void validate_catchall( webs_t wp, char *value, struct variable *v )
3470{
3471    char *p2p;
3472    char port_grp[] = "filter_p2p_grpXXX";
3473
3474    p2p = websGetVar( wp, "filter_p2p", NULL );
3475    if( p2p )
3476    {
3477        snprintf( port_grp, sizeof( port_grp ), "filter_p2p_grp%s",
3478                  nvram_safe_get( "filter_id" ) );
3479        nvram_set( port_grp, p2p );
3480    }
3481
3482    return;
3483}
3484
3485void save_olsrd( webs_t wp );
3486void addDeletion( char *word );
3487
3488void validate_static_route( webs_t wp, char *value, struct variable *v )
3489{
3490#ifdef HAVE_OLSRD
3491    save_olsrd( wp );
3492#endif
3493
3494    int i, tmp = 1;
3495    char word[256], *next;
3496    char buf[1000] = "", *cur = buf;
3497    char buf_name[1000] = "", *cur_name = buf_name;
3498    char old[STATIC_ROUTE_PAGE][60];
3499    char old_name[STATIC_ROUTE_PAGE][30];
3500    char backuproute[256];
3501    struct variable static_route_variables[] = {
3502      {argv:NULL},
3503      {argv:NULL},
3504      {argv:NULL},
3505      {argv:ARGV( "lan", "wan" )},
3506    };
3507
3508    char *name, ipaddr[20], netmask[20], gateway[20], *metric, *ifname, *page;
3509    char new_name[80];
3510    char temp[30], *val = NULL;
3511
3512    name = websGetVar( wp, "route_name", "" );  // default empty if no find
3513    // route_name
3514    metric = websGetVar( wp, "route_metric", "0" );
3515    /*
3516     * validate ip address
3517     */
3518    strcpy( ipaddr, "" );
3519    for( i = 0; i < 4; i++ )
3520    {
3521        snprintf( temp, sizeof( temp ), "%s_%d", "route_ipaddr", i );
3522        val = websGetVar( wp, temp, NULL );
3523        if( val )
3524        {
3525            strcat( ipaddr, val );
3526            if( i < 3 )
3527                strcat( ipaddr, "." );
3528        }
3529        else
3530        {
3531            // free (ipaddr);
3532            return;
3533        }
3534    }
3535
3536    /*
3537     * validate netmask
3538     */
3539    strcpy( netmask, "" );
3540    for( i = 0; i < 4; i++ )
3541    {
3542        snprintf( temp, sizeof( temp ), "%s_%d", "route_netmask", i );
3543        val = websGetVar( wp, temp, NULL );
3544        if( val )
3545        {
3546            strcat( netmask, val );
3547            if( i < 3 )
3548                strcat( netmask, "." );
3549        }
3550        else
3551        {
3552            // free (netmask);
3553            // free (ipaddr);
3554            return;
3555        }
3556    }
3557
3558    /*
3559     * validate gateway
3560     */
3561    strcpy( gateway, "" );
3562    for( i = 0; i < 4; i++ )
3563    {
3564        snprintf( temp, sizeof( temp ), "%s_%d", "route_gateway", i );
3565        val = websGetVar( wp, temp, NULL );
3566        if( val )
3567        {
3568            strcat( gateway, val );
3569            if( i < 3 )
3570                strcat( gateway, "." );
3571        }
3572        else
3573        {
3574            // free (gateway);
3575            // free (netmask);
3576            // free (ipaddr);
3577            return;
3578        }
3579    }
3580
3581    page = websGetVar( wp, "route_page", NULL );
3582    ifname = websGetVar( wp, "route_ifname", NULL );
3583
3584    if( !page || !ipaddr || !netmask || !gateway || !metric || !ifname )
3585        return;
3586
3587    // Allow Defaultroute here
3588
3589    if( !strcmp( ipaddr, "0.0.0.0" ) && !strcmp( netmask, "0.0.0.0" )
3590        && strcmp( gateway, "0.0.0.0" ) )
3591    {
3592        tmp = 1;
3593        goto write_nvram;
3594    }
3595    if( ( !strcmp( ipaddr, "0.0.0.0" ) || !strcmp( ipaddr, "" ) ) &&
3596        ( !strcmp( netmask, "0.0.0.0" ) || !strcmp( netmask, "" ) ) &&
3597        ( !strcmp( gateway, "0.0.0.0" ) || !strcmp( gateway, "" ) ) )
3598    {
3599        tmp = 0;
3600        goto write_nvram;
3601    }
3602
3603    // if (!valid_choice (wp, ifname, &static_route_variables[3]))
3604    // {
3605    // free (gateway);
3606    // free (netmask);
3607    // free (ipaddr);
3608
3609    // return;
3610    // }
3611
3612    if( !*ipaddr )
3613    {
3614        websDebugWrite( wp,
3615                        "Invalid <b>%s</b>: must specify an IP Address<br>",
3616                        v->longname );
3617        // free (gateway);
3618        // free (netmask);
3619        // free (ipaddr);
3620
3621        return;
3622    }
3623    if( !*netmask )
3624    {
3625        websDebugWrite( wp,
3626                        "Invalid <b>%s</b>: must specify a Subnet Mask<br>",
3627                        v->longname );
3628        // free (gateway);
3629        // free (netmask);
3630        // free (ipaddr);
3631
3632        return;
3633    }
3634    if( !valid_ipaddr( wp, ipaddr, &static_route_variables[0] ) ||
3635        !valid_netmask( wp, netmask, &static_route_variables[1] ) ||
3636        !valid_ipaddr( wp, gateway, &static_route_variables[2] ) )
3637    {
3638        // free (gateway);
3639        // free (netmask);
3640        // free (ipaddr);
3641
3642        return;
3643    }
3644
3645    /*
3646     * save old value in nvram
3647     */
3648
3649  write_nvram:
3650    if( !strcmp( ifname, "lan" ) )
3651    {
3652        ifname = nvram_safe_get( "lan_ifname" );
3653        static_route_variables[2].argv = NULL;
3654    }
3655    if( !strcmp( ifname, "wan" ) )
3656    {
3657        ifname = nvram_safe_get( "wan_ifname" );
3658        static_route_variables[2].argv = NULL;
3659    }
3660    else
3661    {
3662        static_route_variables[2].argv = NULL;
3663    }
3664
3665    for( i = 0; i < STATIC_ROUTE_PAGE; i++ )
3666    {
3667        strcpy( old[i], "" );
3668        strcpy( old_name[i], "" );
3669    }
3670    i = 0;
3671    foreach( word, nvram_safe_get( "static_route" ), next )
3672    {
3673        strcpy( old[i], word );
3674        i++;
3675    }
3676    i = 0;
3677    foreach( word, nvram_safe_get( "static_route_name" ), next )
3678    {
3679        strcpy( old_name[i], word );
3680        i++;
3681    }
3682
3683    strcpy( backuproute, old[atoi( page )] );
3684    if( !tmp )
3685    {
3686        char met[16];
3687        char ifn[16];
3688
3689        sscanf( old[atoi( page )], "%s:%s:%s:%s:%s", ipaddr, netmask, gateway,
3690                met, ifn );
3691        // fprintf (stderr, "deleting %s %s %s %s %s\n", ipaddr, netmask,
3692        // gateway,
3693        // met, ifn);
3694        route_del( ifn, atoi( met ) + 1, ipaddr, gateway, netmask );
3695
3696        snprintf( old[atoi( page )], sizeof( old[0] ), "%s", "" );
3697        snprintf( old_name[atoi( page )], sizeof( old_name[0] ), "%s", "" );
3698    }
3699    else
3700    {
3701        snprintf( old[atoi( page )], sizeof( old[0] ), "%s:%s:%s:%s:%s",
3702                  ipaddr, netmask, gateway, metric, ifname );
3703        httpd_filter_name( name, new_name, sizeof( new_name ), SET );
3704        snprintf( old_name[atoi( page )], sizeof( old_name[0] ), "$NAME:%s$$",
3705                  new_name );
3706    }
3707    if( strcmp( backuproute, old[atoi( page )] ) )
3708    {
3709        if( strlen( backuproute ) > 0 )
3710        {
3711            addAction( "static_route_del" );
3712            addDeletion( backuproute );
3713        }
3714    }
3715
3716    for( i = 0; i < STATIC_ROUTE_PAGE; i++ )
3717    {
3718        if( strcmp( old[i], "" ) )
3719            cur += snprintf( cur, buf + sizeof( buf ) - cur, "%s%s",
3720                             cur == buf ? "" : " ", old[i] );
3721        if( strcmp( old_name[i], "" ) )
3722            cur_name +=
3723                snprintf( cur_name, buf_name + sizeof( buf_name ) - cur_name,
3724                          "%s%s", cur_name == buf_name ? "" : " ",
3725                          old_name[i] );
3726    }
3727
3728    nvram_set( v->name, buf );
3729    nvram_set( "static_route_name", buf_name );
3730
3731    // if (ipaddr)
3732    // free (ipaddr);
3733    // if (netmask)
3734    // free (netmask);
3735    // if (gateway)
3736    // free (gateway);
3737}
Note: See TracBrowser for help on using the repository browser.