source: src/router/httpd/validate/webs.c @ 31714

Last change on this file since 31714 was 31714, checked in by brainslayer, 5 weeks ago

delete previous ddns values if service is changed. this prevents keeping of dead data within the nvram

File size: 101.9 KB
Line 
1#define VALIDSOURCE 1
2
3#ifdef WEBS
4#include <webs.h>
5#include <uemf.h>
6#include <ej.h>
7#else                           /* !WEBS */
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <ctype.h>
12#include <unistd.h>
13#include <limits.h>
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <sys/socket.h>
17#include <netinet/in.h>
18#include <arpa/inet.h>
19#include <httpd.h>
20#include <errno.h>
21#endif                          /* WEBS */
22
23#include <proto/ethernet.h>
24#include <fcntl.h>
25#include <signal.h>
26#include <time.h>
27#include <sys/klog.h>
28#include <sys/wait.h>
29#include <cyutils.h>
30#include <support.h>
31#include <cy_conf.h>
32// #ifdef EZC_SUPPORT
33#include <ezc.h>
34// #endif
35#include <broadcom.h>
36#include <wlutils.h>
37#include <netdb.h>
38#include <utils.h>
39#include <stdarg.h>
40#include <sha1.h>
41#ifdef HAVE_SAMBA_SERVER
42#include <jansson.h>
43#endif
44
45extern char *(*websGetVar) (webs_t wp, char *var, char *d);
46extern int get_merge_ipaddr(webs_t wp, char *name, char *ipaddr);
47
48void wan_proto(webs_t wp)
49{
50        char *enable;
51
52        enable = websGetVar(wp, "wan_proto", NULL);
53        nvram_set("wan_proto", enable);
54}
55
56#ifdef FILTER_DEBUG
57extern FILE *debout;
58
59#define D(a) fprintf(debout,"%s\n",a); fflush(debout);
60#else
61#define D(a)
62#endif
63
64void dhcpfwd(webs_t wp)
65{
66        char *enable;
67
68        enable = websGetVar(wp, "dhcpfwd_enable", NULL);
69        if (enable && !strcmp(enable, "1"))
70                nvram_set("lan_proto", "static");
71        nvram_set("dhcpfwd_enable", enable);
72
73}
74
75#ifdef HAVE_CCONTROL
76
77void execute(webs_t wp);
78
79{
80        char command[256];
81        char *var = websGetVar(wp, "command", "");
82
83        sysprintf("%s > /tmp/.result");
84}
85
86#endif
87void clone_mac(webs_t wp)
88{
89        nvram_seti("clone_wan_mac", 1);
90}
91
92/*
93 * Delete lease
94 */
95void delete_leases(webs_t wp)
96{
97        char *iface;
98        char *ip;
99        char *mac;
100
101        if (nvram_match("lan_proto", "static"))
102                return;
103
104        if (nvram_matchi("fon_enable", 1)
105            || (nvram_matchi("chilli_nowifibridge", 1)
106                && nvram_matchi("chilli_enable", 1))) {
107                iface = nvram_safe_get("wl0_ifname");
108        } else {
109                if (nvram_matchi("chilli_enable", 1))
110                        iface = nvram_safe_get("wl0_ifname");
111                else
112                        iface = nvram_safe_get("lan_ifname");
113        }
114        //todo. detect correct interface
115
116        ip = websGetVar(wp, "ip_del", NULL);
117        mac = websGetVar(wp, "mac_del", NULL);
118
119        eval("dhcp_release", iface, ip, mac);
120}
121
122#if defined(HAVE_PPTPD) || defined(HAVE_PPPOESERVER)
123void delete_pptp(webs_t wp)
124{
125        char *iface;
126        iface = websGetVar(wp, "if_del", NULL);
127        if (iface)
128                kill(iface, SIGTERM);
129}
130#endif
131void save_wifi(webs_t wp)
132{
133        // fprintf (stderr, "save wifi\n");
134        char *var = websGetVar(wp, "wifi_display", NULL);
135
136        if (var) {
137                if (has_ad(var))
138                        nvram_set("wifi_display", "giwifi");
139                else
140                        nvram_set("wifi_display", var);
141
142        }
143}
144
145void dhcp_renew(webs_t wp)
146{
147        killall("igmprt", SIGTERM);
148        killall("udhcpc", SIGUSR1);
149}
150
151void dhcp_release(webs_t wp)
152{
153
154        killall("igmprt", SIGTERM);
155        nvram_set("wan_ipaddr", "0.0.0.0");
156        nvram_set("wan_netmask", "0.0.0.0");
157        nvram_set("wan_gateway", "0.0.0.0");
158        nvram_set("wan_get_dns", "");
159        nvram_seti("wan_lease", 0);
160
161        unlink("/tmp/get_lease_time");
162        unlink("/tmp/lease_time");
163
164}
165
166void stop_ppp(webs_t wp)
167{
168        unlink("/tmp/ppp/log");
169        unlink("/tmp/ppp/link");
170}
171
172void validate_filter_tod(webs_t wp)
173{
174        char buf[256] = "";
175        char tod_buf[20];
176        struct variable filter_tod_variables[] = {
177              {argv:ARGV("20")},
178              {argv:ARGV("0", "1", "2")},
179
180        }, *which;
181
182        char *day_all, *week0, *week1, *week2, *week3, *week4, *week5, *week6;
183        char *time_all, *start_hour, *start_min, *end_hour, *end_min;
184        int _start_hour, _start_min, _end_hour, _end_min;
185        char time[20];
186        int week[7];
187        int i, flag = -1, dash = 0;
188        char filter_tod[] = "filter_todXXX";
189        char filter_tod_buf[] = "filter_tod_bufXXX";
190
191        which = &filter_tod_variables[0];
192
193        day_all = websGetVar(wp, "day_all", "0");
194        week0 = websGetVar(wp, "week0", "0");
195        week1 = websGetVar(wp, "week1", "0");
196        week2 = websGetVar(wp, "week2", "0");
197        week3 = websGetVar(wp, "week3", "0");
198        week4 = websGetVar(wp, "week4", "0");
199        week5 = websGetVar(wp, "week5", "0");
200        week6 = websGetVar(wp, "week6", "0");
201        time_all = websGetVar(wp, "time_all", "0");
202        start_hour = websGetVar(wp, "start_hour", "0");
203        start_min = websGetVar(wp, "start_min", "0");
204        // start_time = websGetVar (wp, "start_time", "0");
205        end_hour = websGetVar(wp, "end_hour", "0");
206        end_min = websGetVar(wp, "end_min", "0");
207        // end_time = websGetVar (wp, "end_time", "0");
208
209        // if(atoi(time_all) == 0)
210        // if(!start_hour || !start_min || !start_time || !end_hour || !end_min
211        // || !end_time)
212        // return 1;
213
214        if (atoi(day_all) == 1) {
215                strcpy(time, "0-6");
216                strcpy(tod_buf, "7");
217        } else {
218                week[0] = atoi(week0);
219                week[1] = atoi(week1);
220                week[2] = atoi(week2);
221                week[3] = atoi(week3);
222                week[4] = atoi(week4);
223                week[5] = atoi(week5);
224                week[6] = atoi(week6);
225                strcpy(time, "");
226
227                for (i = 0; i < 7; i++) {
228                        if (week[i] == 1) {
229                                if (i == 6) {
230                                        if (dash == 0 && flag == 1)
231                                                sprintf(time + strlen(time), "%c", '-');
232                                        sprintf(time + strlen(time), "%d", i);
233                                } else if (flag == 1 && dash == 0) {
234                                        sprintf(time + strlen(time), "%c", '-');
235                                        dash = 1;
236                                } else if (dash == 0) {
237                                        sprintf(time + strlen(time), "%d", i);
238                                        flag = 1;
239                                        dash = 0;
240                                }
241                        } else {
242                                if (!strcmp(time, ""))
243                                        continue;
244                                if (dash == 1)
245                                        sprintf(time + strlen(time), "%d", i - 1);
246                                if (flag != 0)
247                                        sprintf(time + strlen(time), "%c", ',');
248                                flag = 0;
249                                dash = 0;
250                        }
251                }
252                if (time[strlen(time) - 1] == ',')
253                        time[strlen(time) - 1] = '\0';
254
255                snprintf(tod_buf, sizeof(tod_buf), "%s %s %s %s %s %s %s", week0, week1, week2, week3, week4, week5, week6);
256        }
257        if (atoi(time_all) == 1) {
258                _start_hour = 0;
259                _start_min = 0;
260                _end_hour = 23;
261                _end_min = 59;
262        } else {
263                _start_hour = atoi(start_hour);
264                _start_min = atoi(start_min);
265                _end_hour = atoi(end_hour);
266                _end_min = atoi(end_min);
267        }
268
269        sprintf(buf, "%d:%d %d:%d %s", _start_hour, _start_min, _end_hour, _end_min, time);
270        snprintf(filter_tod, sizeof(filter_tod), "filter_tod%s", nvram_safe_get("filter_id"));
271        snprintf(filter_tod_buf, sizeof(filter_tod_buf), "filter_tod_buf%s", nvram_safe_get("filter_id"));
272
273        nvram_set(filter_tod, buf);
274        nvram_set(filter_tod_buf, tod_buf);
275        D("everything okay");
276
277}
278
279void applytake(char *value)
280{
281        if (value && !strcmp(value, "ApplyTake")) {
282                nvram_commit();
283                service_restart();
284        }
285}
286
287void save_policy(webs_t wp)
288{
289        char *f_id, *f_name, *f_status, *f_status2;
290        char buf[256] = "";
291        char *value = websGetVar(wp, "action", "");
292        struct variable filter_variables[] = {
293              {argv:ARGV("1", "10")},
294              {argv:ARGV("0", "1", "2")},
295              {argv:ARGV("deny", "allow")},
296
297        }, *which;
298        char filter_buf[] = "filter_ruleXXX";
299
300        D("save policy");
301        which = &filter_variables[0];
302        f_id = websGetVar(wp, "f_id", NULL);
303        f_name = websGetVar(wp, "f_name", NULL);
304        f_status = websGetVar(wp, "f_status", NULL);    // 0=>Disable /
305        // 1,2=>Enable
306        f_status2 = websGetVar(wp, "f_status2", NULL);  // deny=>Deny /
307        // allow=>Allow
308        if (!f_id || !f_name || !f_status || !f_status2) {
309                D("invalid");
310                return;
311        }
312        if (!valid_range(wp, f_id, &which[0])) {
313                D("invalid");
314                return;
315        }
316        if (!valid_choice(wp, f_status, &which[1])) {
317                D("invalid");
318                return;
319        }
320        if (!valid_choice(wp, f_status2, &which[2])) {
321                D("invalid");
322                return;
323        }
324
325        validate_filter_tod(wp);
326
327        snprintf(filter_buf, sizeof(filter_buf), "filter_rule%s", nvram_safe_get("filter_id"));
328
329        // Add $DENY to decide that users select Allow or Deny, if status is
330        // Disable // 2003/10/21
331        snprintf(buf, sizeof(buf), "$STAT:%s$NAME:%s$DENY:%d$$", f_status, f_name, !strcmp(f_status2, "deny") ? 1 : 0);
332
333        nvram_set(filter_buf, buf);
334        applytake(value);
335
336        D("okay");
337}
338
339void validate_filter_policy(webs_t wp, char *value, struct variable *v)
340{
341        char *f_id = websGetVar(wp, "f_id", NULL);
342
343        if (f_id)
344                nvram_set("filter_id", f_id);
345        else
346                nvram_seti("filter_id", 1);
347
348        save_policy(wp);
349}
350
351char *num_to_protocol(int num)
352{
353        switch (num) {
354        case 1:
355                return "icmp";
356        case 6:
357                return "tcp";
358        case 17:
359                return "udp";
360        case 23:
361                return "both";
362        case 99:
363                return "l7";
364        case 100:
365                return "p2p";
366#ifdef HAVE_OPENDPI
367        case 101:
368                return "dpi";
369#endif
370        default:
371                return "unknown";
372        }
373}
374
375/*
376 * Format: 21:21:tcp:FTP(&nbsp;)500:1000:both:TEST1
377 */
378
379void validate_services_port(webs_t wp)
380{
381        char *buf = (char *)calloc(8192, 1);
382        char *services = (char *)calloc(8192, 1);
383        char *cur = buf, *svcs = NULL;
384
385        char *services_array = websGetVar(wp, "services_array0", NULL);
386
387        // char *services_length = websGetVar (wp, "services_length0", NULL);
388        char word[1026], *next;
389        char delim[] = "(&nbsp;)";
390        char var[32] = "";
391        int index = 0;
392        do {
393                snprintf(var, 31, "services_array%d", index++);
394                svcs = websGetVar(wp, var, NULL);
395                if (svcs)
396                        strcat(services, svcs);
397
398        }
399        while (svcs);
400
401        services_array = services;
402
403        split(word, services_array, next, delim) {
404                int from, to, proto;
405                char name[80];
406
407                if (sscanf(word, "%d:%d:%d:%s", &from, &to, &proto, name) != 4)
408                        continue;
409
410                cur +=
411                    snprintf(cur, buf + 8192 - cur,
412                             "%s$NAME:%03d:%s$PROT:%03d:%s$PORT:%03d:%d:%d",
413                             cur == buf ? "" : "<&nbsp;>", strlen(name), name, strlen(num_to_protocol(proto)), num_to_protocol(proto), (int)(get_int_len(from) + get_int_len(to) + strlen(":")), from, to);
414        }
415
416        // segment filter_services into <= 1024 byte lengths
417        cur = buf;
418        // fprintf (stderr, "cur=%s\n", cur);
419
420        memcpy(word, cur, 1024);
421        word[1025] = 0;
422        nvram_set("filter_services", word);
423        cur += 1024;
424
425        if (strlen(cur) > 0) {
426                nvram_set("filter_services_1", cur);
427        }
428        free(services);
429        free(buf);
430        // nvram_set ("filter_services", cur);
431        D("okay");
432}
433
434void save_services_port(webs_t wp)
435{
436        validate_services_port(wp);
437        char *value = websGetVar(wp, "action", "");
438        applytake(value);
439}
440
441void delete_policy(webs_t wp, int which)
442{
443        D("delete policy");
444
445        nvram_nset("", "filter_rule%d", which);
446        nvram_nset("", "filter_tod%d", which);
447        nvram_nset("", "filter_tod_buf%d", which);
448        nvram_nset("", "filter_web_host%d", which);
449        nvram_nset("", "filter_web_url%d", which);
450        nvram_nset("", "filter_ip_grp%d", which);
451        nvram_nset("", "filter_mac_grp%d", which);
452        nvram_nset("", "filter_port_grp%d", which);
453        nvram_nset("", "filter_dport_grp%d", which);
454
455        D("okay");
456}
457
458void single_delete_policy(webs_t wp)
459{
460        char *id = nvram_safe_get("filter_id");
461
462        D("single delete policy");
463        delete_policy(wp, atoi(id));
464        D("okay");
465        return;
466}
467
468void summary_delete_policy(webs_t wp)
469{
470        int i;
471
472        D("summary delete policy");
473        for (i = 1; i <= 10; i++) {
474                char filter_sum[] = "sumXXX";
475                char *sum;
476
477                snprintf(filter_sum, sizeof(filter_sum), "sum%d", i);
478                sum = websGetVar(wp, filter_sum, NULL);
479                if (sum)
480                        delete_policy(wp, i);
481        }
482        D("okay");
483}
484
485void addDeletion(char *word)
486{
487        if (!word || !strlen(word))
488                return;
489
490        char *oldarg = nvram_get("action_service_arg1");
491
492        if (oldarg && strlen(oldarg) > 0) {
493                char *newarg = safe_malloc(strlen(oldarg) + strlen(word) + 2);
494
495                sprintf(newarg, "%s %s", oldarg, word);
496                nvram_set("action_service_arg1", newarg);
497                free(newarg);
498        } else
499                nvram_set("action_service_arg1", word);
500}
501
502void delete_old_routes(void)
503{
504        char word[256], *next;
505        char ipaddr[20], netmask[20], gateway[20], met[20], ifn[20];
506
507        sleep(1);
508        foreach(word, nvram_safe_get("action_service_arg1"), next) {
509                strcpy(ipaddr, strtok(word, ":"));
510                strcpy(netmask, strtok(NULL, ":"));
511                strcpy(gateway, strtok(NULL, ":"));
512                strcpy(met, strtok(NULL, ":"));
513                strcpy(ifn, strtok(NULL, ":"));
514
515                route_del(ifn, atoi(met) + 1, ipaddr, gateway, netmask);
516        }
517}
518
519void delete_static_route(webs_t wp)
520{
521        addAction("routing");
522        nvram_seti("nowebaction", 1);
523        char *buf = calloc(2500, 1);
524        char *buf_name = calloc(2500, 1);
525
526        char *cur = buf;
527        char *cur_name = buf_name;
528        char word[256], *next;
529        char word_name[256], *next_name;
530        char *page = websGetVar(wp, "route_page", NULL);
531        char *value = websGetVar(wp, "action", "");
532        int i = 0;
533        char *performance = nvram_safe_get("static_route");
534        char *performance2 = nvram_safe_get("static_route_name");
535
536        foreach(word, performance, next) {
537                if (i == atoi(page)) {
538                        addDeletion(word);
539                        i++;
540                        continue;
541                }
542
543                cur += snprintf(cur, buf + 2500 - cur, "%s%s", cur == buf ? "" : " ", word);
544
545                i++;
546        }
547
548        i = 0;
549        foreach(word_name, performance2, next_name) {
550                if (i == atoi(page)) {
551                        i++;
552                        continue;
553                }
554                cur_name += snprintf(cur_name, buf_name + 2500 - cur_name, "%s%s", cur_name == buf_name ? "" : " ", word_name);
555
556                i++;
557        }
558
559        nvram_set("static_route", buf);
560        nvram_set("static_route_name", buf_name);
561        free(buf_name);
562        free(buf);
563        applytake(value);
564        return;
565}
566
567extern void gen_key(char *genstr, int weptype);
568
569extern unsigned char key128[4][13];
570extern unsigned char key64[4][5];
571
572void generate_wep_key_single(char *prefix, char *passphrase, char *bit, char *tx)
573{
574
575        int i;
576        char buf[256];
577        char var[80];
578
579        if (!prefix || !bit || !passphrase || !tx)
580                return;
581
582        gen_key(passphrase, atoi(bit));
583
584        nvram_seti("generate_key", 1);
585
586        if (atoi(bit) == 64) {
587                char key1[27] = "";
588                char key2[27] = "";
589                char key3[27] = "";
590                char key4[27] = "";
591
592                for (i = 0; i < 5; i++)
593                        sprintf(key1 + (i << 1), "%02X", key64[0][i]);
594                for (i = 0; i < 5; i++)
595                        sprintf(key2 + (i << 1), "%02X", key64[1][i]);
596                for (i = 0; i < 5; i++)
597                        sprintf(key3 + (i << 1), "%02X", key64[2][i]);
598                for (i = 0; i < 5; i++)
599                        sprintf(key4 + (i << 1), "%02X", key64[3][i]);
600
601                snprintf(buf, sizeof(buf), "%s:%s:%s:%s:%s:%s", passphrase, key1, key2, key3, key4, tx);
602                // nvram_set("wl_wep_gen_64",buf);
603                cprintf("buf = %s\n", buf);
604                sprintf(var, "%s_wep_gen", prefix);
605
606                nvram_set(var, buf);
607                nvram_nset(key1, "%s_key1", prefix);
608                nvram_nset(key2, "%s_key2", prefix);
609                nvram_nset(key3, "%s_key3", prefix);
610                nvram_nset(key4, "%s_key4", prefix);
611        } else if (atoi(bit) == 128) {
612                char key1[27] = "";
613                char key2[27] = "";
614                char key3[27] = "";
615                char key4[27] = "";
616
617                for (i = 0; i < 13; i++)
618                        sprintf(key1 + (i << 1), "%02X", key128[0][i]);
619                key1[26] = 0;
620
621                for (i = 0; i < 13; i++)
622                        sprintf(key2 + (i << 1), "%02X", key128[1][i]);
623                key2[26] = 0;
624
625                for (i = 0; i < 13; i++)
626                        sprintf(key3 + (i << 1), "%02X", key128[2][i]);
627                key3[26] = 0;
628
629                for (i = 0; i < 13; i++)
630                        sprintf(key4 + (i << 1), "%02X", key128[3][i]);
631                key4[26] = 0;
632                // cprintf("passphrase[%s]\n", passphrase);
633                // filter_name(passphrase, new_passphrase, sizeof(new_passphrase),
634                // SET);
635                // cprintf("new_passphrase[%s]\n", new_passphrase);
636                cprintf("key1 = %s\n", key1);
637                cprintf("key2 = %s\n", key2);
638                cprintf("key3 = %s\n", key3);
639                cprintf("key4 = %s\n", key4);
640
641                snprintf(buf, sizeof(buf), "%s:%s:%s:%s:%s:%s", passphrase, key1, key2, key3, key4, tx);
642                cprintf("buf = %s\n", buf);
643                // nvram_set("wl_wep_gen_128",buf);
644                sprintf(var, "%s_wep_gen", prefix);
645                nvram_set(var, buf);
646                nvram_nset(key1, "%s_key1", prefix);
647                nvram_nset(key2, "%s_key2", prefix);
648                nvram_nset(key3, "%s_key3", prefix);
649                nvram_nset(key4, "%s_key4", prefix);
650        }
651        return;
652}
653
654void generate_wep_key(webs_t wp)
655{
656        char *prefix, *passphrase, *bit, *tx;
657
658#ifdef HAVE_MADWIFI
659        prefix = websGetVar(wp, "security_varname", "ath0");
660#else
661        prefix = websGetVar(wp, "security_varname", "wl");
662#endif
663        char var[80];
664
665        sprintf(var, "%s_wep_bit", prefix);
666        bit = websGetVar(wp, var, NULL);
667        if (bit != NULL)
668                nvram_set("wl_wep_bit", bit);
669        sprintf(var, "%s_passphrase", prefix);
670        passphrase = websGetVar(wp, var, NULL);
671        sprintf(var, "%s_key", prefix);
672        tx = websGetVar(wp, var, NULL);
673        cprintf("gen wep key: bits = %s\n", bit);
674
675        generate_wep_key_single(prefix, passphrase, bit, tx);
676}
677
678char *copytonv(webs_t wp, const char *fmt, ...)
679{
680        char varbuf[64];
681        va_list args;
682
683        va_start(args, (char *)fmt);
684        vsnprintf(varbuf, sizeof(varbuf), fmt, args);
685        va_end(args);
686
687        char *wl = websGetVar(wp, varbuf, NULL);
688
689        if (wl)
690                nvram_set(varbuf, wl);
691        return wl;
692}
693
694void copymergetonv(webs_t wp, const char *fmt, ...)
695{
696        char varbuf[64];
697        va_list args;
698
699        va_start(args, (char *)fmt);
700        vsnprintf(varbuf, sizeof(varbuf), fmt, args);
701        va_end(args);
702        char ipaddr[32];
703        if (get_merge_ipaddr(wp, varbuf, ipaddr)) {
704                nvram_set(varbuf, ipaddr);
705        }
706
707}
708
709void copytonv2(webs_t wp, char *prefix_get, char *prefix_set, char *name)
710{
711        char tmpname[64];
712
713        sprintf(tmpname, "%s_%s", prefix_get, name);
714
715        char *wl = websGetVar(wp, tmpname, NULL);
716
717        sprintf(tmpname, "%s_%s", prefix_set, name);
718
719        if (wl)
720                nvram_set(tmpname, wl);
721}
722
723void copytonv2_wme(webs_t wp, char *prefix_get, char *prefix_set, char *name, int maxindex)
724{
725        char tmpvalue[128] = "";
726        char tmpname[64];
727        char *next;
728        char *wl;
729        int i;
730
731        for (i = 0; i <= maxindex; i++) {
732                sprintf(tmpname, "%s_%s%d", prefix_get, name, i);
733                wl = websGetVar(wp, tmpname, NULL);
734                if (wl) {
735                        strcat(tmpvalue, wl);
736                        strcat(tmpvalue, " ");
737                }
738        }
739
740        sprintf(tmpname, "%s_%s", prefix_set, name);
741        strtrim_right(tmpvalue, ' ');
742        nvram_set(tmpname, tmpvalue);
743}
744
745static void save_secprefix(webs_t wp, char *prefix)
746{
747        char n[80];
748        char radius[80];
749        char p2[80];
750
751        strcpy(p2, prefix);
752        if (contains(prefix, '.'))
753                rep(p2, '.', 'X');      // replace invalid characters for sub ifs
754
755#ifdef HAVE_WPA_SUPPLICANT
756
757/*_8021xtype
758_8021xuser
759_8021xpasswd
760_8021xca
761_8021xpem
762_8021xprv
763*/
764        copytonv(wp, "%s_8021xtype", prefix);
765        copytonv(wp, "%s_tls8021xuser", prefix);
766        copytonv(wp, "%s_tls8021xanon", prefix);
767        copytonv(wp, "%s_tls8021xpasswd", prefix);
768        copytonv(wp, "%s_tls8021xphase2", prefix);
769        copytonv(wp, "%s_tls8021xca", prefix);
770        copytonv(wp, "%s_tls8021xpem", prefix);
771        copytonv(wp, "%s_tls8021xprv", prefix);
772        copytonv(wp, "%s_tls8021xaddopt", prefix);
773        copytonv(wp, "%s_peap8021xuser", prefix);
774        copytonv(wp, "%s_peap8021xanon", prefix);
775        copytonv(wp, "%s_peap8021xpasswd", prefix);
776        copytonv(wp, "%s_tls8021xkeyxchng", prefix);
777        copytonv(wp, "%s_peap8021xphase2", prefix);
778        copytonv(wp, "%s_peap8021xca", prefix);
779        copytonv(wp, "%s_peap8021xaddopt", prefix);
780        copytonv(wp, "%s_ttls8021xuser", prefix);
781        copytonv(wp, "%s_ttls8021xanon", prefix);
782        copytonv(wp, "%s_ttls8021xpasswd", prefix);
783        copytonv(wp, "%s_ttls8021xphase2", prefix);
784        copytonv(wp, "%s_ttls8021xca", prefix);
785        copytonv(wp, "%s_ttls8021xaddopt", prefix);
786        copytonv(wp, "%s_leap8021xuser", prefix);
787        copytonv(wp, "%s_leap8021xanon", prefix);
788        copytonv(wp, "%s_leap8021xpasswd", prefix);
789        copytonv(wp, "%s_leap8021xphase2", prefix);
790        copytonv(wp, "%s_leap8021xaddopt", prefix);
791
792#endif
793
794        copytonv(wp, "%s_crypto", prefix);
795        copytonv(wp, "%s_wpa_psk", prefix);
796        copytonv(wp, "%s_wpa_gtk_rekey", prefix);
797        copymergetonv(wp, "%s_radius_ipaddr", prefix);
798        copytonv(wp, "%s_radius_port", prefix);
799        copytonv(wp, "%s_radius_key", prefix);
800
801        copymergetonv(wp, "%s_local_ip", prefix);
802
803        copymergetonv(wp, "%s_radius2_ipaddr", prefix);
804        copytonv(wp, "%s_radius2_port", prefix);
805        copytonv(wp, "%s_radius2_key", prefix);
806#ifdef HAVE_MADWIFI
807        copytonv(wp, "%s_radius_retry", prefix);
808        copytonv(wp, "%s_acct", prefix);
809        copymergetonv(wp, "%s_acct_ipaddr", prefix);
810        copytonv(wp, "%s_acct_port", prefix);
811        copytonv(wp, "%s_acct_key", prefix);
812#endif
813        copytonv(wp, "%s_radmactype", prefix);
814
815        sprintf(n, "%s_authmode", prefix);
816        char *authmode = websGetVar(wp, n, "");
817        if (strlen(authmode) == 0) {
818                nvram_set(n, "open");
819        } else {
820                copytonv(wp, n);
821        }
822        sprintf(n, "%s_key1", prefix);
823        char *key1 = websGetVar(wp, n, "");
824
825        copytonv(wp, n);
826        sprintf(n, "%s_key2", prefix);
827        char *key2 = websGetVar(wp, n, "");
828
829        copytonv(wp, n);
830        sprintf(n, "%s_key3", prefix);
831        char *key3 = websGetVar(wp, n, "");
832
833        copytonv(wp, n);
834        sprintf(n, "%s_key4", prefix);
835        char *key4 = websGetVar(wp, n, "");
836
837        copytonv(wp, n);
838        sprintf(n, "%s_passphrase", prefix);
839        char *pass = websGetVar(wp, n, "");
840
841        copytonv(wp, n);
842        sprintf(n, "%s_key", prefix);
843        char *tx = websGetVar(wp, n, "");
844        if (strlen(tx) == 0) {
845                nvram_seti(n, 1);
846        } else {
847                copytonv(wp, n);
848        }
849        copytonv(wp, "%s_wep_bit", prefix);
850        char buf[128];
851
852        snprintf(buf, sizeof(buf), "%s:%s:%s:%s:%s:%s", pass, key1, key2, key3, key4, tx);
853        sprintf(n, "%s_wep_buf", prefix);
854        nvram_set(n, buf);
855
856        sprintf(n, "%s_security_mode", p2);
857        char n2[80];
858
859        sprintf(n2, "%s_akm", prefix);
860        char *v = websGetVar(wp, n, NULL);
861
862        if (v) {
863                char auth[32];
864                char wep[32];
865
866                sprintf(auth, "%s_auth_mode", prefix);
867                sprintf(wep, "%s_wep", prefix);
868                if (!strcmp(v, "wep")) {
869                        nvram_set(auth, "none");
870                        nvram_set(wep, "enabled");
871                } else if (!strcmp(v, "radius")) {
872                        nvram_set(auth, "radius");
873                        nvram_set(wep, "enabled");
874                } else {
875                        nvram_set(auth, "none");
876                        nvram_set(wep, "disabled");
877                }
878                nvram_set(n2, v);
879        }
880
881        copytonv(wp, n);
882#ifdef HAVE_MADWIFI
883        sprintf(n, "%s_config", p2);
884        sprintf(n2, "%s_config", prefix);
885        v = websGetVar(wp, n, NULL);
886        if (v && strlen(v) > 0)
887                nvram_set(n2, v);
888#endif
889
890}
891
892static int security_save_prefix(webs_t wp, char *prefix)
893{
894
895        save_secprefix(wp, prefix);
896        char *next;
897        char var[80];
898        char *vifs = nvram_nget("%s_vifs", prefix);
899
900        if (vifs == NULL)
901                return 0;
902        foreach(var, vifs, next) {
903                save_secprefix(wp, var);
904        }
905        // nvram_commit ();
906        return 0;
907}
908
909void security_save(webs_t wp)
910{
911        char *value = websGetVar(wp, "action", "");
912
913#ifdef HAVE_MADWIFI
914        int dc = getdevicecount();
915        int i;
916
917        for (i = 0; i < dc; i++) {
918                char b[16];
919
920                sprintf(b, "ath%d", i);
921                security_save_prefix(wp, b);
922        }
923#else
924        int dc = get_wl_instances();
925        int i;
926
927        for (i = 0; i < dc; i++) {
928                char b[16];
929
930                sprintf(b, "wl%d", i);
931                security_save_prefix(wp, b);
932        }
933#endif
934        applytake(value);
935}
936
937extern struct wl_client_mac *wl_client_macs;
938
939void add_active_mac(webs_t wp)
940{
941        int i, count = 0;
942        int msize = 4608;       // 18 chars * 256 entries
943        char *buf = calloc(msize, 1);
944        char *cur = buf;
945        char *ifname = websGetVar(wp, "ifname", NULL);
946
947        nvram_seti("wl_active_add_mac", 1);
948
949        for (i = 0; i < MAX_LEASES + 2; i++) {
950                char active_mac[] = "onXXX";
951                char *index = NULL;
952
953                snprintf(active_mac, sizeof(active_mac), "%s%d", "on", i);
954                index = websGetVar(wp, active_mac, NULL);
955                if (!index)
956                        continue;
957
958                count++;
959
960                cur += snprintf(cur, buf + msize - cur, "%s%s", cur == buf ? "" : " ", wl_client_macs[atoi(index)].hwaddr);
961        }
962        for (i = 0; i < MAX_LEASES + 2; i++) {
963                char active_mac[] = "offXXX";
964                char *index;
965
966                snprintf(active_mac, sizeof(active_mac), "%s%d", "off", i);
967                index = websGetVar(wp, active_mac, NULL);
968                if (!index)
969                        continue;
970
971                count++;
972                cur += snprintf(cur, buf + msize - cur, "%s%s", cur == buf ? "" : " ", wl_client_macs[atoi(index)].hwaddr);
973        }
974        char acmac[32];
975        sprintf(acmac, "%s_active_mac", ifname);
976        nvram_set(acmac, buf);
977        if (!strcmp(ifname, "wl0"))
978                nvram_set("wl_active_mac", buf);
979        free(buf);
980}
981
982void removeLineBreak(char *startup)
983{
984        int i = 0;
985        int c = 0;
986
987        for (i = 0; i < strlen(startup); i++) {
988                if (startup[i] == '\r')
989                        continue;
990                startup[c++] = startup[i];
991        }
992        startup[c++] = 0;
993
994}
995
996void ping_startup(webs_t wp)
997{
998        char *startup = websGetVar(wp, "ping_ip", NULL);
999        if (startup) {
1000                // filter Windows <cr>ud
1001                removeLineBreak(startup);
1002
1003                nvram_set("rc_startup", startup);
1004                nvram_commit();
1005                nvram2file("rc_startup", "/tmp/.rc_startup");
1006                chmod("/tmp/.rc_startup", 0700);
1007        }
1008        return;
1009
1010}
1011
1012void ping_shutdown(webs_t wp)
1013{
1014        char *shutdown = websGetVar(wp, "ping_ip", NULL);
1015        if (shutdown) {
1016                // filter Windows <cr>ud
1017                removeLineBreak(shutdown);
1018
1019                nvram_set("rc_shutdown", shutdown);
1020                nvram_commit();
1021                nvram2file("rc_shutdown", "/tmp/.rc_shutdown");
1022                chmod("/tmp/.rc_shutdown", 0700);
1023        }
1024        return;
1025
1026}
1027
1028void ping_firewall(webs_t wp)
1029{
1030        char *firewall = websGetVar(wp, "ping_ip", NULL);
1031        if (firewall) {
1032                // filter Windows <cr>ud
1033                removeLineBreak(firewall);
1034                nvram_set("rc_firewall", firewall);
1035                nvram_commit();
1036                nvram2file("rc_firewall", "/tmp/.rc_firewall");
1037                chmod("/tmp/.rc_firewall", 0700);
1038        }
1039        return;
1040}
1041
1042void ping_custom(webs_t wp)
1043{
1044        char *custom = websGetVar(wp, "ping_ip", NULL);
1045        if (custom) {
1046                // filter Windows <cr>ud
1047                unlink("/tmp/custom.sh");
1048                removeLineBreak(custom);
1049                nvram_set("rc_custom", custom);
1050                nvram_commit();
1051                if (nvram_invmatch("rc_custom", "")) {
1052                        nvram2file("rc_custom", "/tmp/custom.sh");
1053                        chmod("/tmp/custom.sh", 0700);
1054                }
1055        }
1056
1057        return;
1058}
1059
1060void ping_wol(webs_t wp)
1061{
1062        char *wol_type = websGetVar(wp, "wol_type", NULL);
1063
1064        unlink(PING_TMP);
1065
1066        if (!wol_type || !strcmp(wol_type, ""))
1067                return;
1068
1069        if (!strcmp(wol_type, "update")) {
1070                char *wol_hosts = websGetVar(wp, "wol_hosts", NULL);
1071
1072                if (!wol_hosts || !strcmp(wol_hosts, ""))
1073                        return;
1074
1075                nvram_set("wol_hosts", wol_hosts);
1076                nvram_set("wol_cmd", "");
1077                return;
1078        }
1079
1080        char *manual_wol_mac = websGetVar(wp, "manual_wol_mac", NULL);
1081        char *manual_wol_network = websGetVar(wp, "manual_wol_network", NULL);
1082        char *manual_wol_port = websGetVar(wp, "manual_wol_port", NULL);
1083
1084        if (!strcmp(wol_type, "manual")) {
1085                nvram_set("manual_wol_mac", manual_wol_mac);
1086                nvram_set("manual_wol_network", manual_wol_network);
1087                nvram_set("manual_wol_port", manual_wol_port);
1088        }
1089
1090        char wol_cmd[256] = { 0 };
1091        snprintf(wol_cmd, sizeof(wol_cmd), "/usr/sbin/wol -v -i %s -p %s %s", manual_wol_network, manual_wol_port, manual_wol_mac);
1092        nvram_set("wol_cmd", wol_cmd);
1093
1094        // use Wol.asp as a debugging console
1095#ifdef HAVE_REGISTER
1096        if (!isregistered_real())
1097                return;
1098#endif
1099        sysprintf("%s > %s 2>&1 &", wol_cmd, PING_TMP);
1100
1101}
1102
1103void diag_ping_start(webs_t wp)
1104{
1105        char *ip = websGetVar(wp, "ping_ip", NULL);
1106
1107        if (!ip || !strcmp(ip, ""))
1108                return;
1109
1110        unlink(PING_TMP);
1111        nvram_set("ping_ip", ip);
1112
1113        setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
1114#ifdef HAVE_REGISTER
1115        if (!isregistered_real())
1116                return;
1117#endif
1118        sysprintf("alias ping=\'ping -c 3\'; eval \"%s\" > %s 2>&1 &", ip, PING_TMP);
1119
1120        return;
1121}
1122
1123void diag_ping_stop(webs_t wp)
1124{
1125        killall("ping", SIGKILL);
1126}
1127
1128void diag_ping_clear(webs_t wp)
1129{
1130        unlink(PING_TMP);
1131}
1132
1133void save_wireless_advanced(webs_t wp)
1134{
1135        char set_prefix[8];
1136        char prefix[8];
1137        char *wlface = websGetVar(wp, "interface", NULL);
1138
1139        if (!strcmp(wlface, "wl0"))
1140                sprintf(set_prefix, "%s", "wl");
1141        else
1142                sprintf(set_prefix, "%s", wlface);
1143
1144        sprintf(prefix, wlface);
1145
1146        copytonv2(wp, prefix, set_prefix, "auth");
1147        copytonv2(wp, prefix, set_prefix, "rateset");
1148        copytonv2(wp, prefix, set_prefix, "nmcsidx");
1149        copytonv2(wp, prefix, set_prefix, "rate");
1150        copytonv2(wp, prefix, set_prefix, "gmode_protection");
1151        copytonv2(wp, prefix, set_prefix, "frameburst");
1152        copytonv2(wp, prefix, set_prefix, "bcn");
1153        copytonv2(wp, prefix, set_prefix, "dtim");
1154        copytonv2(wp, prefix, set_prefix, "frag");
1155        copytonv2(wp, prefix, set_prefix, "rts");
1156        copytonv2(wp, prefix, set_prefix, "maxassoc");
1157        copytonv2(wp, prefix, set_prefix, "ap_isolate");
1158        copytonv2(wp, prefix, set_prefix, "plcphdr");
1159        copytonv2(wp, prefix, set_prefix, "shortslot");
1160        copytonv2(wp, prefix, set_prefix, "afterburner");
1161        copytonv2(wp, prefix, set_prefix, "btc_mode");
1162        copytonv2(wp, prefix, set_prefix, "wme");
1163        copytonv2(wp, prefix, set_prefix, "wme_no_ack");
1164        copytonv2_wme(wp, prefix, set_prefix, "wme_ap_bk", 5);
1165        copytonv2_wme(wp, prefix, set_prefix, "wme_ap_be", 5);
1166        copytonv2_wme(wp, prefix, set_prefix, "wme_ap_vi", 5);
1167        copytonv2_wme(wp, prefix, set_prefix, "wme_ap_vo", 5);
1168        copytonv2_wme(wp, prefix, set_prefix, "wme_sta_bk", 5);
1169        copytonv2_wme(wp, prefix, set_prefix, "wme_sta_be", 5);
1170        copytonv2_wme(wp, prefix, set_prefix, "wme_sta_vi", 5);
1171        copytonv2_wme(wp, prefix, set_prefix, "wme_sta_vo", 5);
1172        copytonv2_wme(wp, prefix, set_prefix, "wme_txp_bk", 4);
1173        copytonv2_wme(wp, prefix, set_prefix, "wme_txp_be", 4);
1174        copytonv2_wme(wp, prefix, set_prefix, "wme_txp_vi", 4);
1175        copytonv2_wme(wp, prefix, set_prefix, "wme_txp_vo", 4);
1176
1177        return;
1178
1179}
1180
1181void save_wds(webs_t wp)
1182{
1183        char *wds_enable_val, wds_enable_var[32] = { 0 };
1184        int h = 0;
1185        char *interface = websGetVar(wp, "interface", NULL);
1186
1187        for (h = 1; h <= MAX_WDS_DEVS; h++) {
1188                sprintf(wds_enable_var, "%s_wds%d_enable", interface, h);
1189                wds_enable_val = websGetVar(wp, wds_enable_var, NULL);
1190                nvram_set(wds_enable_var, wds_enable_val);
1191        }
1192        sprintf(wds_enable_var, "%s_br1_enable", interface);
1193        wds_enable_val = websGetVar(wp, wds_enable_var, NULL);
1194        nvram_set(wds_enable_var, wds_enable_val);
1195
1196        sprintf(wds_enable_var, "%s_br1_nat", interface);
1197        wds_enable_val = websGetVar(wp, wds_enable_var, NULL);
1198        nvram_set(wds_enable_var, wds_enable_val);
1199
1200        return;
1201
1202}
1203
1204int get_svc(char *svc, char *protocol, char *ports)
1205{
1206        char word[1024], *next;
1207        char delim[] = "<&nbsp;>";
1208        char *services;
1209        // services = nvram_safe_get("filter_services");
1210        services = get_filter_services();
1211
1212        split(word, services, next, delim) {
1213                int len = 0;
1214                char *name, *prot, *port;
1215                int from = 0, to = 0;
1216
1217                if ((name = strstr(word, "$NAME:")) == NULL || (prot = strstr(word, "$PROT:")) == NULL || (port = strstr(word, "$PORT:")) == NULL)
1218                        continue;
1219
1220                /*
1221                 * $NAME
1222                 */
1223                if (sscanf(name, "$NAME:%3d:", &len) != 1)
1224                        return -1;
1225
1226                strncpy(name, name + sizeof("$NAME:nnn:") - 1, len);
1227                name[len] = '\0';
1228
1229                if (strcasecmp(svc, name))
1230                        continue;
1231
1232                /*
1233                 * $PROT
1234                 */
1235                if (sscanf(prot, "$PROT:%3d:", &len) != 1)
1236                        return -1;
1237
1238                strncpy(protocol, prot + sizeof("$PROT:nnn:") - 1, len);
1239                protocol[len] = '\0';
1240
1241                /*
1242                 * $PORT
1243                 */
1244                if (sscanf(port, "$PORT:%3d:", &len) != 1)
1245                        return -1;
1246
1247                strncpy(ports, port + sizeof("$PORT:nnn:") - 1, len);
1248                ports[len] = '\0';
1249
1250                if (sscanf(ports, "%d:%d", &from, &to) != 2) {
1251                        free(services);
1252                        return -1;
1253                }
1254
1255                if (strcasecmp(svc, name) == 0) {
1256                        free(services);
1257                        return 0;
1258                }
1259        }
1260        free(services);
1261
1262        return -1;
1263}
1264
1265void qos_add_svc(webs_t wp)
1266{
1267        char *var = websGetVar(wp, "wshaper_enable", NULL);
1268
1269        if (var != NULL)
1270                nvram_set("wshaper_enable", var);
1271
1272        char protocol[100] = { 0 }, ports[100] = {
1273        0};
1274        char *add_svc = websGetVar(wp, "add_svc", NULL);
1275        char *svqos_svcs = nvram_safe_get("svqos_svcs");
1276        char new_svcs[4096] = { 0 };
1277        int i = 0;
1278        if (!add_svc)
1279                return;
1280
1281        memset(new_svcs, 0, sizeof(new_svcs));
1282
1283        if (get_svc(add_svc, protocol, ports))
1284                return;
1285
1286        if (strcmp(protocol, "l7") == 0) {
1287                int slen = strlen(add_svc);
1288
1289                for (i = 0; i < slen; i++)
1290                        add_svc[i] = tolower(add_svc[i]);
1291        }
1292#ifdef HAVE_OPENDPI
1293        if (strcmp(protocol, "dpi") == 0) {
1294                int slen = strlen(add_svc);
1295
1296                for (i = 0; i < slen; i++)
1297                        add_svc[i] = tolower(add_svc[i]);
1298        }
1299#endif
1300
1301        /*
1302         * if this service exists, return an error
1303         */
1304        if (strstr(svqos_svcs, add_svc))
1305                return;
1306
1307        if (strlen(svqos_svcs) > 0)
1308                snprintf(new_svcs, 4095, "%s %s %s %s 30 |", svqos_svcs, add_svc, protocol, ports);
1309        else
1310                snprintf(new_svcs, 4095, "%s %s %s 30 |", add_svc, protocol, ports);
1311
1312        if (strlen(new_svcs) >= sizeof(new_svcs))
1313                return;
1314
1315        nvram_set("svqos_svcs", new_svcs);
1316        nvram_commit();
1317}
1318
1319void qos_add_dev(webs_t wp)
1320{
1321        char *var = websGetVar(wp, "wshaper_enable", NULL);
1322
1323        if (var != NULL)
1324                nvram_set("wshaper_enable", var);
1325
1326        char *add_dev = websGetVar(wp, "svqos_dev", NULL);
1327        char *svqos_ips = nvram_safe_get("svqos_devs");
1328        char new_ip[4096] = { 0 };
1329        if (!add_dev)
1330                return;
1331        /*
1332         * if this ip exists, return an error
1333         */
1334#ifdef HAVE_AQOS
1335        snprintf(new_ip, 4095, "%s %s 100 100 0 0 none |", svqos_ips, add_dev);
1336#else
1337        snprintf(new_ip, 4095, "%s %s 30 |", svqos_ips, add_dev);
1338#endif
1339        if (strlen(new_ip) >= sizeof(new_ip))
1340                return;
1341
1342        nvram_set("svqos_devs", new_ip);
1343
1344}
1345
1346void qos_add_ip(webs_t wp)
1347{
1348        char *var = websGetVar(wp, "wshaper_enable", NULL);
1349
1350        if (var != NULL)
1351                nvram_set("wshaper_enable", var);
1352
1353        char *add_ip0 = websGetVar(wp, "svqos_ipaddr0", NULL);
1354        char *add_ip1 = websGetVar(wp, "svqos_ipaddr1", NULL);
1355        char *add_ip2 = websGetVar(wp, "svqos_ipaddr2", NULL);
1356        char *add_ip3 = websGetVar(wp, "svqos_ipaddr3", NULL);
1357        char *add_nm = websGetVar(wp, "svqos_netmask", NULL);
1358        char add_ip[19] = { 0 };
1359        char *svqos_ips = nvram_safe_get("svqos_ips");
1360        char new_ip[4096] = { 0 };
1361        if (!svqos_ips || !add_ip0 || !add_ip1 || !add_ip2 || !add_ip3 || !add_nm)
1362                return;
1363
1364        memset(new_ip, 0, sizeof(new_ip));
1365
1366        snprintf(add_ip, 19, "%s.%s.%s.%s/%s", add_ip0, add_ip1, add_ip2, add_ip3, add_nm);
1367
1368        /*
1369         * if this ip exists, return an error
1370         */
1371        if (strstr(svqos_ips, add_ip))
1372                return;
1373#ifdef HAVE_AQOS
1374        snprintf(new_ip, 4095, "%s %s 100 100 0 0 |", svqos_ips, add_ip);
1375#else
1376        snprintf(new_ip, 4095, "%s %s 30 |", svqos_ips, add_ip);
1377#endif
1378
1379        nvram_set("svqos_ips", new_ip);
1380
1381}
1382
1383void qos_add_mac(webs_t wp)
1384{
1385        char *var = websGetVar(wp, "wshaper_enable", NULL);
1386
1387        if (var != NULL)
1388                nvram_set("wshaper_enable", var);
1389
1390        char *add_mac0 = websGetVar(wp, "svqos_hwaddr0", NULL);
1391        char *add_mac1 = websGetVar(wp, "svqos_hwaddr1", NULL);
1392        char *add_mac2 = websGetVar(wp, "svqos_hwaddr2", NULL);
1393        char *add_mac3 = websGetVar(wp, "svqos_hwaddr3", NULL);
1394        char *add_mac4 = websGetVar(wp, "svqos_hwaddr4", NULL);
1395        char *add_mac5 = websGetVar(wp, "svqos_hwaddr5", NULL);
1396        char add_mac[19] = { 0 };
1397        char *svqos_macs = nvram_safe_get("svqos_macs");
1398        char new_mac[4096] = { 0 };
1399        if (!svqos_macs || !add_mac0 || !add_mac1 || !add_mac2 || !add_mac3 || !add_mac4 || !add_mac5)
1400                return;
1401
1402        memset(new_mac, 0, sizeof(new_mac));
1403
1404        snprintf(add_mac, 18, "%s:%s:%s:%s:%s:%s", add_mac0, add_mac1, add_mac2, add_mac3, add_mac4, add_mac5);
1405
1406        /*
1407         * if this mac exists, return an error
1408         */
1409        if (strstr(svqos_macs, add_mac))
1410                return;
1411#ifdef HAVE_AQOS
1412        snprintf(new_mac, 4095, "%s %s 100 100 user 0 0 |", svqos_macs, add_mac);
1413#else
1414        snprintf(new_mac, 4095, "%s %s 30 |", svqos_macs, add_mac);
1415#endif
1416
1417        nvram_set("svqos_macs", new_mac);
1418
1419}
1420
1421void qos_save(webs_t wp)
1422{
1423        char *value = websGetVar(wp, "action", "");
1424        char svqos_var[4096] = { 0 };
1425        char svqos_pktstr[30] = { 0 };
1426        char field[32] = { 0 };
1427        char *name, *data, *level, *level2, *lanlevel, *prio, *delete, *pktopt, *proto;
1428        int no_svcs = atoi(websGetVar(wp, "svqos_nosvcs", "0"));
1429        int no_ips = atoi(websGetVar(wp, "svqos_noips", "0"));
1430        int no_devs = atoi(websGetVar(wp, "svqos_nodevs", "0"));
1431        int no_macs = atoi(websGetVar(wp, "svqos_nomacs", "0"));
1432        int i = 0, j = 0;
1433
1434        /*
1435         * reused wshaper fields - see src/router/rc/wshaper.c
1436         */
1437
1438        data = websGetVar(wp, "wshaper_enable", NULL);
1439        nvram_set("wshaper_enable", data);
1440
1441        if (strcmp(data, "0") == 0) {
1442                addAction("qos");
1443                nvram_seti("nowebaction", 1);
1444                applytake(value);
1445                return;
1446        }
1447//      nvram_set("enable_game", websGetVar(wp, "enable_game", NULL));
1448        nvram_set("svqos_defaults", websGetVar(wp, "svqos_defaults", "0"));
1449        nvram_set("default_uplevel", websGetVar(wp, "default_uplevel", "0"));
1450        nvram_set("default_downlevel", websGetVar(wp, "default_downlevel", "0"));
1451        nvram_set("default_lanlevel", websGetVar(wp, "default_lanlevel", "0"));
1452        nvram_set("wshaper_downlink", websGetVar(wp, "wshaper_downlink", "0"));
1453        nvram_set("wshaper_uplink", websGetVar(wp, "wshaper_uplink", "0"));
1454        nvram_set("wshaper_dev", websGetVar(wp, "wshaper_dev", "0"));
1455        nvram_set("qos_type", websGetVar(wp, "qos_type", "0"));
1456
1457#if defined(HAVE_CODEL) || defined(HAVE_FQ_CODEL) || defined(HAVE_PIE)
1458        nvram_set("svqos_aqd", websGetVar(wp, "qos_aqd", "0"));
1459#endif
1460
1461        // nvram_commit ();
1462
1463        /*
1464         * tcp-packet flags
1465         */
1466        memset(svqos_pktstr, 0, sizeof(svqos_pktstr));
1467
1468        pktopt = websGetVar(wp, "svqos_pktack", NULL);
1469        if (pktopt)
1470                strcat(svqos_pktstr, "ACK | ");
1471        pktopt = websGetVar(wp, "svqos_pktsyn", NULL);
1472        if (pktopt)
1473                strcat(svqos_pktstr, "SYN | ");
1474        pktopt = websGetVar(wp, "svqos_pktfin", NULL);
1475        if (pktopt)
1476                strcat(svqos_pktstr, "FIN | ");
1477        pktopt = websGetVar(wp, "svqos_pktrst", NULL);
1478        if (pktopt)
1479                strcat(svqos_pktstr, "RST | ");
1480
1481        nvram_set("svqos_pkts", svqos_pktstr);
1482
1483        /*
1484         * services priorities
1485         */
1486        memset(svqos_var, 0, sizeof(svqos_var));
1487
1488        for (i = 0; i < no_svcs; i++) {
1489                char protocol[100], ports[100];
1490
1491                memset(protocol, 0, 100);
1492                memset(ports, 0, 10);
1493
1494                snprintf(field, 31, "svqos_svcdel%d", i);
1495                delete = websGetVar(wp, field, NULL);
1496
1497                if (delete && strlen(delete) > 0)
1498                        continue;
1499
1500                snprintf(field, 31, "svqos_svcname%d", i);
1501                name = websGetVar(wp, field, NULL);
1502                if (!name)
1503                        continue;
1504
1505                snprintf(field, 31, "svqos_svcprio%d", i);
1506                level = websGetVar(wp, field, NULL);
1507
1508                if (!level)
1509                        continue;
1510
1511                if (get_svc(name, protocol, ports))
1512                        continue;
1513
1514                if (strcmp(protocol, "l7") == 0) {
1515                        int slen = strlen(name);
1516
1517                        for (j = 0; j < slen; j++)
1518                                name[j] = tolower(name[j]);
1519                }
1520#ifdef HAVE_OPENDPI
1521                if (strcmp(protocol, "dpi") == 0) {
1522                        int slen = strlen(name);
1523
1524                        for (j = 0; j < slen; j++)
1525                                name[j] = tolower(name[j]);
1526                }
1527#endif
1528                if (strlen(svqos_var) > 0) {
1529                        char *tmp;
1530                        asprintf(&tmp, "%s %s %s %s %s |", svqos_var, name, protocol, ports, level);
1531                        strcpy(svqos_var, tmp);
1532                        free(tmp);
1533                } else
1534                        sprintf(svqos_var, "%s %s %s %s |", name, protocol, ports, level);
1535
1536        }
1537
1538        nvram_set("svqos_svcs", svqos_var);
1539        // nvram_commit ();
1540        memset(svqos_var, 0, sizeof(svqos_var));
1541
1542        /*
1543         * DEV priorities
1544         */
1545        for (i = 0; i < no_devs; i++) {
1546
1547                snprintf(field, 31, "svqos_devdel%d", i);
1548                delete = websGetVar(wp, field, NULL);
1549
1550                if (delete && strlen(delete) > 0)
1551                        continue;
1552
1553                snprintf(field, 31, "svqos_dev%d", i);
1554                data = websGetVar(wp, field, NULL);
1555
1556                if (!data)
1557                        continue;
1558
1559#ifndef HAVE_AQOS
1560                snprintf(field, 31, "svqos_devprio%d", i);
1561                level = websGetVar(wp, field, NULL);
1562                if (!level)
1563                        continue;
1564                if (strlen(svqos_var) > 0) {
1565                        char *copy = malloc(4096);
1566                        snprintf(copy, 4096, "%s %s %s |", svqos_var, data, level);
1567                        strcpy(svqos_var, copy);
1568                        free(copy);
1569                } else {
1570                        char *copy = malloc(4096);
1571                        sprintf(copy, "%s %s |", data, level);
1572                        strcpy(svqos_var, copy);
1573                        free(copy);
1574                }
1575#else
1576                snprintf(field, 31, "svqos_devprio%d", i);
1577                prio = websGetVar(wp, field, NULL);
1578
1579                snprintf(field, 31, "svqos_devup%d", i);
1580                level = websGetVar(wp, field, NULL);
1581                if (!level)
1582                        continue;
1583                snprintf(field, 31, "svqos_devdown%d", i);
1584                level2 = websGetVar(wp, field, NULL);
1585                if (!level2)
1586                        continue;
1587
1588                snprintf(field, 31, "svqos_devservice%d", i);
1589                proto = websGetVar(wp, field, NULL);
1590                if (!proto)
1591                        continue;
1592
1593                snprintf(field, 31, "svqos_devlanlvl%d", i);
1594                lanlevel = websGetVar(wp, field, NULL);
1595                if (!lanlevel)
1596                        continue;
1597
1598                if (strlen(svqos_var) > 0) {
1599                        char *tmp;
1600                        asprintf(&tmp, "%s %s %s %s %s %s %s |", svqos_var, data, level, level2, lanlevel, prio, proto);
1601                        strcpy(svqos_var, tmp);
1602                        free(tmp);
1603                } else
1604                        sprintf(svqos_var, "%s %s %s %s %s %s |", data, level, level2, lanlevel, prio, proto);
1605
1606#endif
1607
1608        }
1609
1610        nvram_set("svqos_devs", svqos_var);
1611        memset(svqos_var, 0, sizeof(svqos_var));
1612
1613        /*
1614         * IP priorities
1615         */
1616        for (i = 0; i < no_ips; i++) {
1617
1618                snprintf(field, 31, "svqos_ipdel%d", i);
1619                delete = websGetVar(wp, field, NULL);
1620
1621                if (delete && strlen(delete) > 0)
1622                        continue;
1623
1624                snprintf(field, 31, "svqos_ip%d", i);
1625                data = websGetVar(wp, field, NULL);
1626                if (!data)
1627                        continue;
1628
1629#ifndef HAVE_AQOS
1630                snprintf(field, 31, "svqos_ipprio%d", i);
1631                level = websGetVar(wp, field, NULL);
1632                if (!level)
1633                        continue;
1634                if (strlen(svqos_var) > 0)
1635                        sprintf(svqos_var, "%s %s %s |", svqos_var, data, level);
1636                else
1637                        sprintf(svqos_var, "%s %s |", data, level);
1638#else
1639                snprintf(field, 31, "svqos_ipprio%d", i);
1640                prio = websGetVar(wp, field, NULL);
1641                if (!prio)
1642                        continue;
1643
1644                snprintf(field, 31, "svqos_ipup%d", i);
1645                level = websGetVar(wp, field, NULL);
1646                if (!level)
1647                        continue;
1648                snprintf(field, 31, "svqos_ipdown%d", i);
1649                level2 = websGetVar(wp, field, NULL);
1650                if (!level2)
1651                        continue;
1652                snprintf(field, 31, "svqos_iplanlvl%d", i);
1653                lanlevel = websGetVar(wp, field, NULL);
1654                if (!lanlevel)
1655                        continue;
1656
1657                if (strlen(svqos_var) > 0) {
1658                        char *tmp;
1659                        asprintf(&tmp, "%s %s %s %s %s %s |", svqos_var, data, level, level2, lanlevel, prio);
1660                        strcpy(svqos_var, tmp);
1661                        free(tmp);
1662                } else
1663                        sprintf(svqos_var, "%s %s %s %s %s |", data, level, level2, lanlevel, prio);
1664
1665#endif
1666
1667        }
1668
1669        nvram_set("svqos_ips", svqos_var);
1670        // nvram_commit ();
1671        memset(svqos_var, 0, sizeof(svqos_var));
1672
1673        /*
1674         * MAC priorities
1675         */
1676        for (i = 0; i < no_macs; i++) {
1677                snprintf(field, 31, "svqos_macdel%d", i);
1678                delete = websGetVar(wp, field, NULL);
1679
1680                if (delete && strlen(delete) > 0)
1681                        continue;
1682
1683                snprintf(field, 31, "svqos_mac%d", i);
1684                data = websGetVar(wp, field, NULL);
1685                if (!data)
1686                        continue;
1687
1688#ifndef HAVE_AQOS
1689                snprintf(field, 31, "svqos_macprio%d", i);
1690                level = websGetVar(wp, field, NULL);
1691                if (!level)
1692                        continue;
1693
1694                if (strlen(svqos_var) > 0)
1695                        sprintf(svqos_var, "%s %s %s |", svqos_var, data, level);
1696                else
1697                        sprintf(svqos_var, "%s %s |", data, level);
1698#else
1699                snprintf(field, 31, "svqos_macprio%d", i);
1700                prio = websGetVar(wp, field, NULL);
1701                if (!prio)
1702                        continue;
1703
1704                snprintf(field, 31, "svqos_macup%d", i);
1705                level = websGetVar(wp, field, NULL);
1706                if (!level)
1707                        continue;
1708                snprintf(field, 31, "svqos_macdown%d", i);
1709                level2 = websGetVar(wp, field, NULL);
1710                if (!level2)
1711                        continue;
1712                snprintf(field, 31, "svqos_maclanlvl%d", i);
1713                lanlevel = websGetVar(wp, field, NULL);
1714                if (!lanlevel)
1715                        continue;
1716
1717                if (strlen(svqos_var) > 0) {
1718                        char *tmp;
1719                        asprintf(&tmp, "%s %s %s %s user %s %s |", svqos_var, data, level, level2, lanlevel, prio);
1720                        strcpy(svqos_var, tmp);
1721                        free(tmp);
1722                } else
1723                        sprintf(svqos_var, "%s %s %s user %s %s |", data, level, level2, lanlevel, prio);
1724
1725#endif
1726
1727        }
1728
1729        nvram_set("svqos_macs", svqos_var);
1730        // nvram_commit ();
1731
1732        /*
1733         * adm6996 LAN port priorities
1734         */
1735        nvram_set("svqos_port1prio", websGetVar(wp, "svqos_port1prio", "0"));
1736        nvram_set("svqos_port2prio", websGetVar(wp, "svqos_port2prio", "0"));
1737        nvram_set("svqos_port3prio", websGetVar(wp, "svqos_port3prio", "0"));
1738        nvram_set("svqos_port4prio", websGetVar(wp, "svqos_port4prio", "0"));
1739
1740        nvram_set("svqos_port1bw", websGetVar(wp, "svqos_port1bw", "0"));
1741        nvram_set("svqos_port2bw", websGetVar(wp, "svqos_port2bw", "0"));
1742        nvram_set("svqos_port3bw", websGetVar(wp, "svqos_port3bw", "0"));
1743        nvram_set("svqos_port4bw", websGetVar(wp, "svqos_port4bw", "0"));
1744
1745        addAction("qos");
1746        nvram_seti("nowebaction", 1);
1747        applytake(value);
1748
1749}
1750
1751static void macro_add(char *a)
1752{
1753        cprintf("adding %s\n", a);
1754
1755        char *count;
1756        int c;
1757        char buf[20];
1758
1759        count = nvram_safe_get(a);
1760        cprintf("count = %s\n", count);
1761        if (count != NULL && strlen(count) > 0) {
1762                c = atoi(count);
1763                if (c > -1) {
1764                        c++;
1765                        sprintf(buf, "%d", c);
1766                        cprintf("set %s to %s\n", a, buf);
1767                        nvram_set(a, buf);
1768                }
1769        }
1770        return;
1771}
1772
1773static void macro_rem(char *a, char *nv)
1774{
1775        char *count;
1776        int c, i, cnt;
1777        char buf[20];
1778        char *buffer, *b;
1779
1780        cnt = 0;
1781        count = nvram_safe_get(a);
1782        if (count != NULL && strlen(count) > 0) {
1783                c = atoi(count);
1784                if (c > 0) {
1785                        c--;
1786                        sprintf(buf, "%d", c);
1787                        nvram_set(a, buf);
1788                        buffer = nvram_safe_get(nv);
1789                        if (buffer != NULL) {
1790                                int slen = strlen(buffer);
1791
1792                                b = safe_malloc(slen + 1);
1793
1794                                for (i = 0; i < slen; i++) {
1795                                        if (buffer[i] == ' ')
1796                                                cnt++;
1797                                        if (cnt == c)
1798                                                break;
1799                                        b[i] = buffer[i];
1800                                }
1801                                b[i] = 0;
1802                                nvram_set(nv, b);
1803                                free(b);
1804                        }
1805
1806                }
1807        }
1808        return;
1809}
1810
1811void forward_remove(webs_t wp)
1812{
1813        macro_rem("forward_entries", "forward_port");
1814}
1815
1816void forward_add(webs_t wp)
1817{
1818        macro_add("forward_entries");
1819}
1820
1821void filter_remove(webs_t wp)
1822{
1823        char filter[32];
1824        sprintf(filter, "numfilterservice%s", nvram_safe_get("filter_id"));
1825        int numfilters = nvram_default_geti(filter, 4);
1826        if (numfilters > 0)
1827                numfilters--;
1828        char num[32];
1829        sprintf(num, "%d", numfilters);
1830        nvram_set(filter, num);
1831}
1832
1833void filter_add(webs_t wp)
1834{
1835        char filter[32];
1836        sprintf(filter, "numfilterservice%s", nvram_safe_get("filter_id"));
1837        int numfilters = nvram_default_geti(filter, 4);
1838        numfilters++;
1839        char num[32];
1840        sprintf(num, "%d", numfilters);
1841        nvram_set(filter, num);
1842}
1843
1844void lease_remove(webs_t wp)
1845{
1846        macro_rem("static_leasenum", "static_leases");
1847}
1848
1849void lease_add(webs_t wp)
1850{
1851        macro_add("static_leasenum");
1852}
1853
1854#ifdef HAVE_PPPOESERVER
1855void chap_user_add(webs_t wp)
1856{
1857        char *var = websGetVar(wp, "pppoeserver_enabled", NULL);
1858
1859        if (var != NULL)
1860                nvram_set("pppoeserver_enabled", var);
1861        macro_add("pppoeserver_chapsnum");
1862}
1863
1864void chap_user_remove(webs_t wp)
1865{
1866        char *var = websGetVar(wp, "pppoeserver_enabled", NULL);
1867
1868        if (var != NULL)
1869                nvram_set("pppoeserver_enabled", var);
1870        macro_rem("pppoeserver_chapsnum", "pppoeserver_chaps");
1871}
1872#endif
1873
1874#ifdef HAVE_MILKFISH
1875void milkfish_user_add(webs_t wp)
1876{
1877        macro_add("milkfish_ddsubscribersnum");
1878}
1879
1880void milkfish_user_remove(webs_t wp)
1881{
1882        macro_rem("milkfish_ddsubscribersnum", "milkfish_ddsubscribers");
1883}
1884
1885void milkfish_alias_add(webs_t wp)
1886{
1887        macro_add("milkfish_ddaliasesnum");
1888}
1889
1890void milkfish_alias_remove(webs_t wp)
1891{
1892        macro_rem("milkfish_ddaliasesnum", "milkfish_ddaliases");
1893}
1894#endif
1895
1896void forwardspec_remove(webs_t wp)
1897{
1898        macro_rem("forwardspec_entries", "forward_spec");
1899}
1900
1901void forwardspec_add(webs_t wp)
1902{
1903        macro_add("forwardspec_entries");
1904}
1905
1906void trigger_remove(webs_t wp)
1907{
1908        macro_rem("trigger_entries", "port_trigger");
1909}
1910
1911void trigger_add(webs_t wp)
1912{
1913        macro_add("trigger_entries");
1914}
1915
1916int get_vifcount(char *prefix)
1917{
1918        char *next;
1919        char var[80];
1920        char wif[16];
1921
1922        sprintf(wif, "%s_vifs", prefix);
1923        char *vifs = nvram_safe_get(wif);
1924
1925        if (vifs == NULL)
1926                return 0;
1927        int count = 0;
1928
1929        foreach(var, vifs, next) {
1930                count++;
1931        }
1932        return count;
1933}
1934
1935#ifdef HAVE_GUESTPORT
1936int gp_action = 0;
1937
1938void add_mdhcpd(char *iface, int start, int max, int leasetime)
1939{
1940
1941        char mdhcpd[32];
1942        char *mdhcpds;
1943        int var[8];
1944
1945        // add mdhcpd
1946        if (nvram_geti("mdhcpd_count") > 0)
1947                sprintf(mdhcpd, " %s>On>%d>%d>%d", iface, start, max, leasetime);
1948        else
1949                sprintf(mdhcpd, "%s>On>%d>%d>%d", iface, start, max, leasetime);
1950        mdhcpds = safe_malloc(strlen(nvram_safe_get("mdhcpd")) + strlen(mdhcpd) + 2);
1951        sprintf(mdhcpds, "%s%s", nvram_safe_get("mdhcpd"), mdhcpd);
1952        nvram_set("mdhcpd", mdhcpds);
1953        free(mdhcpds);
1954
1955        sprintf(var, "%d", nvram_geti("mdhcpd_count") + 1);
1956        nvram_set("mdhcpd_count", var);
1957}
1958
1959void remove_mdhcp(char *iface)
1960{
1961
1962        char *start, *next, *pref, *suff;
1963        char *mdhcpds = safe_malloc(strlen(nvram_safe_get("mdhcpd")) + 1);
1964        int len;
1965        char var[4];
1966
1967        strcpy(mdhcpds, nvram_safe_get("mdhcpd"));
1968        start = strstr(mdhcpds, iface);
1969        //fprintf(stderr, "checking.... %s -> %s %s\n", mdhcpds, iface, start);
1970        if (start) {
1971                len = strlen(mdhcpds) - strlen(start);
1972                if (len > 0) {
1973                        pref = safe_malloc(len);
1974                        strncpy(pref, mdhcpds, len - 1);
1975                        pref[len - 1] = '\0';
1976                } else {
1977                        pref = safe_malloc(1);
1978                        pref[0] = '\0';
1979                }
1980                //fprintf(stderr, "[PREF] %s\n", pref);
1981
1982                next = strchr(start, ' ');
1983                if (next) {
1984                        // cut entry
1985                        len = strlen(next);
1986                        suff = strdup(next);
1987                        suff[len - 1] = '\0';
1988                } else {
1989                        // entry at the end?
1990                        suff = safe_malloc(1);
1991                        suff[0] = '\0';
1992                }
1993
1994                free(mdhcpds);
1995
1996                //fprintf(stderr, "[PREF/SUFF] %s %s\n", pref, suff);   
1997                len = strlen(pref) + strlen(suff);
1998                mdhcpds = safe_malloc(len + 2);
1999                sprintf(mdhcpds, "%s %s", pref, suff);
2000                mdhcpds[len + 1] = '\0';
2001                //fprintf(stderr, "[MDHCP] %s\n", mdhcpds);
2002                nvram_set("mdhcpd", mdhcpds);
2003
2004                len = nvram_geti("mdhcpd_count");
2005                if (len > 0) {
2006                        len--;
2007                        //fprintf(stderr, "[MDHCPDS] %d\n", len);
2008                        sprintf(var, "%d", len);
2009                        nvram_set("mdhcpd_count", var);
2010                }
2011
2012                free(mdhcpds);
2013                free(pref);
2014                free(suff);
2015        }
2016}
2017
2018void move_mdhcp(char *siface, char *tiface)
2019{
2020
2021        char *start;
2022        char *mdhcpds = NULL;
2023        int i, len, pos;
2024        char iface[16];
2025        mdhcpds = strdup(nvram_safe_get("mdhcpd"));
2026        start = strstr(mdhcpds, siface);
2027        if (start) {
2028                strcpy(iface, tiface);
2029                len = strlen(tiface);
2030                pos = strlen(mdhcpds) - strlen(start);
2031                for (i = 0; i < len; i++) {
2032                        mdhcpds[pos + i] = iface[i];
2033                }
2034                //fprintf(stderr, "[MDHCPD] %s->%s %d %s\n", siface, tiface, pos, mdhcpds);
2035                nvram_set("mdhcpd", mdhcpds);
2036                free(mdhcpds);
2037        }
2038}
2039
2040char *getFreeLocalIpNet()
2041{
2042        return "192.168.12.1";
2043}
2044#endif
2045void add_vifs_single(char *prefix, int device)
2046{
2047        int count = get_vifcount(prefix);
2048
2049        if (count == 16)
2050                return;
2051        char vif[16];
2052
2053        sprintf(vif, "%s_vifs", prefix);
2054        char *vifs = nvram_safe_get(vif);
2055
2056        if (vifs == NULL)
2057                return;
2058        char *n = (char *)safe_malloc(strlen(vifs) + 8);
2059        char v[80];
2060        char v2[80];
2061#ifdef HAVE_GUESTPORT
2062        char guestport[16];
2063        sprintf(guestport, "guestport_%s", prefix);
2064#endif
2065
2066#ifdef HAVE_MADWIFI
2067        // char *cou[] = { "a", "b", "c", "d", "e", "f" };
2068        sprintf(v, "ath%d.%d", device, count + 1);
2069#else
2070        sprintf(v, "wl%d.%d", device, count + 1);
2071#endif
2072        if (strlen(vifs) == 0)
2073                sprintf(n, "%s", v);
2074        else
2075                sprintf(n, "%s %s", vifs, v);
2076        sprintf(v2, "%s_closed", v);
2077        nvram_seti(v2, 0);
2078        sprintf(v2, "%s_mode", v);
2079        nvram_set(v2, "ap");
2080
2081        sprintf(v2, "%s_ap_isolate", v);
2082        nvram_seti(v2, 0);
2083        sprintf(v2, "%s_ssid", v);
2084#ifdef HAVE_MAKSAT
2085#ifdef HAVE_MAKSAT_BLANK
2086        nvram_set(v2, "default_vap");
2087#else
2088        nvram_set(v2, "maksat_vap");
2089#endif
2090#elif defined(HAVE_SANSFIL)
2091        nvram_set(v2, "sansfil_vap");
2092#elif defined(HAVE_TRIMAX)
2093        nvram_set(v2, "m2m_vap");
2094#elif defined(HAVE_WIKINGS)
2095        nvram_set(v2, "Excel Networks_vap");
2096#elif defined(HAVE_ESPOD)
2097        nvram_set(v2, "ESPOD Technologies_vap");
2098#elif defined(HAVE_NEXTMEDIA)
2099        nvram_set(v2, "nextmedia_vap");
2100#elif defined(HAVE_TMK)
2101        nvram_set(v2, "KMT_vap");
2102#elif defined(HAVE_CORENET)
2103        nvram_set(v2, "corenet.ap");
2104#elif defined(HAVE_ONNET)
2105        nvram_set(v2, "OTAi_vap");
2106#elif defined(HAVE_KORENRON)
2107        nvram_set(v2, "WBR2000_vap");
2108#elif defined(HAVE_HDWIFI)
2109        nvram_set(v2, "hdwifi_vap");
2110#elif defined(HAVE_RAYTRONIK)
2111        nvram_set(v2, "RN-150M");
2112#elif defined(HAVE_HOBBIT)
2113        nvram_set(v2, "hobb-it_vap");
2114#else
2115        nvram_set(v2, "dd-wrt_vap");
2116#endif
2117        sprintf(v2, "%s_vifs", prefix);
2118        nvram_set(v2, n);
2119        sprintf(v2, "%s_bridged", v);
2120        nvram_seti(v2, 1);
2121        sprintf(v2, "%s_nat", v);
2122        nvram_seti(v2, 1);
2123        sprintf(v2, "%s_ipaddr", v);
2124        nvram_set(v2, "0.0.0.0");
2125        sprintf(v2, "%s_netmask", v);
2126        nvram_set(v2, "0.0.0.0");
2127
2128        sprintf(v2, "%s_gtk_rekey", v);
2129        nvram_seti(v2, 3600);
2130
2131        sprintf(v2, "%s_radius_port", v);
2132        nvram_seti(v2, 1812);
2133
2134        sprintf(v2, "%s_radius_ipaddr", v);
2135        nvram_set(v2, "0.0.0.0");
2136
2137#ifdef HAVE_MADWIFI
2138
2139        sprintf(v2, "%s_radius2_ipaddr", v);
2140        nvram_set(v2, "0.0.0.0");
2141
2142        sprintf(v2, "%s_radius2_port", v);
2143        nvram_seti(v2, 1812);
2144
2145        sprintf(v2, "%s_local_ip", v);
2146        nvram_set(v2, "0.0.0.0");
2147#endif
2148#ifdef HAVE_GUESTPORT
2149        char v3[80];
2150        if (gp_action == 1) {
2151                nvram_set(guestport, v);
2152
2153                sprintf(v2, "%s_ssid", v);
2154#ifdef HAVE_WZRHPAG300NH
2155                if (has_5ghz(prefix))
2156                        nvram_set(v2, "GuestPort_A");
2157                else
2158                        nvram_set(v2, "GuestPort_G");
2159#else
2160                nvram_set(v2, "GuestPort");
2161#endif
2162
2163                sprintf(v2, "%s_bridged", v);
2164                nvram_seti(v2, 0);
2165
2166                sprintf(v2, "%s_ipaddr", v);
2167                nvram_set(v2, getFreeLocalIpNet());
2168
2169                sprintf(v2, "%s_netmask", v);
2170                nvram_set(v2, "255.255.255.0");
2171
2172                sprintf(v2, "%s_security_mode", v);
2173                nvram_set(v2, "psk psk2");
2174
2175                sprintf(v2, "%s_akm", v);
2176                nvram_set(v2, "psk psk2");
2177
2178                sprintf(v2, "%s_crypto", v);
2179                nvram_set(v2, "tkip+aes");
2180
2181                sprintf(v2, "%s_wpa_psk", v);
2182#ifdef HAVE_WZRHPAG300NH
2183                if (has_5ghz(prefix))
2184                        sprintf(v3, "DEF-p_wireless_%s0_11a-wpapsk", prefix);
2185                else
2186                        sprintf(v3, "DEF-p_wireless_%s0_11bg-wpapsk", prefix);
2187#else
2188                sprintf(v3, "DEF-p_wireless_%s_11bg-wpapsk", prefix);
2189#endif
2190                nvram_set(v2, getUEnv(v3));
2191
2192                add_mdhcpd(v, 20, 200, 3600);
2193                //required to use mdhcpd
2194                nvram_seti("dhcp_dnsmasq", 1);
2195
2196                rep(v, '.', 'X');
2197
2198                sprintf(v2, "%s_security_mode", v);
2199                nvram_set(v2, "psk psk2");
2200
2201                sprintf(v2, "%s_crypto", v);
2202                nvram_set(v2, "tkip+aes");
2203        }
2204        gp_action = 0;
2205#endif
2206
2207        // nvram_commit ();
2208        free(n);
2209}
2210
2211void add_vifs(webs_t wp)
2212{
2213        char *prefix = websGetVar(wp, "iface", NULL);
2214
2215        if (prefix == NULL)
2216                return;
2217        int devcount = prefix[strlen(prefix) - 1] - '0';
2218#ifdef HAVE_GUESTPORT
2219        if (!strcmp(websGetVar(wp, "gp_modify", ""), "add")) {
2220                gp_action = 1;
2221        }
2222#endif
2223        add_vifs_single(prefix, devcount);
2224}
2225
2226#ifdef HAVE_GUESTPORT
2227void move_vif(char *prefix, char *svif, char *tvif)
2228{
2229
2230        char filename[32];
2231        char command[64];
2232
2233        //fprintf(stderr, "[VIFS] move %s -> %s\n", svif, tvif);
2234        sprintf(filename, "/tmp/.nvram_%s", svif);
2235        sprintf(command, "nvram show | grep %s_ > /tmp/.nvram_%s", svif, svif);
2236        //fprintf(stderr, "[VIFS] %s\n", command);
2237        system(command);
2238
2239        FILE *fp;
2240        char line[80];
2241        char var[16];
2242        char tvifx[16];
2243        char nvram_var[32];
2244        char nvram_val[32];
2245        int len;
2246        int pos = 0;
2247        int xpos;
2248
2249        strcpy(tvifx, tvif);
2250        rep(tvifx, '.', 'X');
2251
2252        if ((fp = fopen(filename, "r"))) {
2253                while (fgets(line, sizeof(line), fp)) {
2254                        pos = strcspn(line, "=");
2255                        if (pos) {
2256                                xpos = strcspn(line, "X");
2257                                len = strlen(svif);
2258                                strncpy(var, line + len, pos - len);
2259                                var[pos - len] = '\0';
2260                                if (xpos > 0 && xpos < pos) {
2261                                        sprintf(nvram_var, "%s%s", tvifx, var);
2262                                } else {
2263                                        sprintf(nvram_var, "%s%s", tvif, var);
2264                                }
2265
2266                                strncpy(nvram_val, line + pos + 1, strlen(line) - pos);
2267                                nvram_val[strlen(line) - pos - 2] = '\0';
2268                                //fprintf(stderr, "[VIF] %s %s\n", nvram_var, nvram_val);
2269                                nvram_set(nvram_var, nvram_val);
2270                        }
2271                }
2272                fclose(fp);
2273                unlink(filename);
2274        }
2275}
2276#endif
2277void remove_vifs_single(char *prefix)
2278{
2279        char wif[16];
2280
2281        sprintf(wif, "%s_vifs", prefix);
2282        int o = -1;
2283        char *vifs = nvram_safe_get(wif);
2284        char copy[128];
2285
2286        strcpy(copy, vifs);
2287        int i;
2288        int slen = strlen(copy);
2289
2290#ifdef HAVE_GUESTPORT
2291        int q = 0;
2292        int j;
2293        int gp_found = 0;
2294        char vif[16], pvif[16];
2295        char guestport[16];
2296        sprintf(guestport, "guestport_%s", prefix);
2297
2298        if (nvram_get(guestport)) {
2299                if (gp_action == 2) {
2300                        for (i = 0; i <= slen; i++) {
2301                                if (copy[i] == 0x20 || i == slen) {
2302                                        if (gp_found)
2303                                                strcpy(pvif, vif);
2304                                        if (o > 0)
2305                                                q = o + 1;
2306                                        o = i;
2307                                        for (j = 0; j < o - q; j++) {
2308                                                vif[j] = copy[j + q];
2309                                        }
2310                                        vif[j] = '\0';
2311
2312                                        if (gp_found) {
2313                                                move_vif(prefix, vif, pvif);
2314                                        }
2315
2316                                        if (nvram_match(guestport, vif))
2317                                                gp_found = 1;
2318                                }
2319                        }
2320                        remove_mdhcp(nvram_get(guestport));
2321                        nvram_unset(guestport);
2322                } else {
2323                        o = slen;
2324                        for (i = slen; i >= 0; i--) {
2325                                if (copy[i] == 0x20 || i == 0) {
2326                                        if (gp_found)
2327                                                strcpy(pvif, vif);
2328                                        if (i == 0)
2329                                                q = i;
2330                                        else
2331                                                q = i + 1;
2332                                        for (j = 0; j < o - q; j++) {
2333                                                vif[j] = copy[j + q];
2334                                        }
2335                                        vif[j] = '\0';
2336
2337                                        if (gp_found == slen) {
2338                                                move_vif(prefix, pvif, vif);
2339                                                nvram_set(guestport, vif);
2340                                                move_mdhcp(pvif, vif);
2341                                                gp_found = 0;
2342                                        }
2343
2344                                        if (nvram_match(guestport, vif))
2345                                                gp_found = o;
2346                                        o = i;
2347                                }
2348                        }
2349                }
2350        }
2351        gp_action = 0;
2352#endif
2353        o = -1;
2354        for (i = 0; i < slen; i++) {
2355                if (copy[i] == 0x20)
2356                        o = i;
2357        }
2358
2359        if (o == -1) {
2360                nvram_set(wif, "");
2361        } else {
2362                copy[o] = 0;
2363                nvram_set(wif, copy);
2364        }
2365        // nvram_commit ();
2366#ifdef HAVE_AOSS
2367// must remove all aoss vap's if one of them is touched
2368        if (strlen(nvram_safe_get("aoss_vifs"))) {
2369                nvram_unset("ath0_vifs");
2370                nvram_unset("aoss_vifs");
2371                nvram_commit();
2372        }
2373        if (strlen(nvram_safe_get("aossa_vifs"))) {
2374                nvram_unset("ath1_vifs");
2375                nvram_unset("aossa_vifs");
2376                nvram_commit();
2377        }
2378#endif
2379}
2380
2381void remove_vifs(webs_t wp)
2382{
2383        char *prefix = websGetVar(wp, "iface", NULL);
2384#ifdef HAVE_GUESTPORT
2385        if (!strcmp(websGetVar(wp, "gp_modify", ""), "remove")) {
2386                gp_action = 2;
2387        }
2388#endif
2389        remove_vifs_single(prefix);
2390}
2391
2392#ifdef HAVE_BONDING
2393void add_bond(webs_t wp)
2394{
2395        char word[256];
2396        char *next, *wordlist;
2397        int count = 0;
2398        int realcount = nvram_geti("bonding_count");
2399
2400        if (realcount == 0) {
2401                wordlist = nvram_safe_get("bondings");
2402                foreach(word, wordlist, next) {
2403                        count++;
2404                }
2405                realcount = count;
2406        }
2407        realcount++;
2408        char var[32];
2409
2410        sprintf(var, "%d", realcount);
2411        nvram_set("bonding_count", var);
2412        nvram_commit();
2413        return;
2414}
2415
2416void del_bond(webs_t wp)
2417{
2418        char word[256];
2419        int realcount = 0;
2420        char *next, *wordlist, *newwordlist;
2421        char *val = websGetVar(wp, "del_value", NULL);
2422
2423        if (val == NULL)
2424                return;
2425        int todel = atoi(val);
2426
2427        wordlist = nvram_safe_get("bondings");
2428        newwordlist = (char *)calloc(strlen(wordlist) + 2, 1);
2429        int count = 0;
2430
2431        foreach(word, wordlist, next) {
2432                if (count != todel) {
2433                        strcat(newwordlist, word);
2434                        strcat(newwordlist, " ");
2435                }
2436                count++;
2437        }
2438
2439        char var[32];
2440
2441        realcount = nvram_geti("bonding_count") - 1;
2442        sprintf(var, "%d", realcount);
2443        nvram_set("bonding_count", var);
2444        nvram_set("bondings", newwordlist);
2445        nvram_commit();
2446        free(newwordlist);
2447
2448        return;
2449}
2450#endif
2451
2452#ifdef HAVE_OLSRD
2453void add_olsrd(webs_t wp)
2454{
2455        char *ifname = websGetVar(wp, "olsrd_ifname", NULL);
2456
2457        if (ifname == NULL)
2458                return;
2459        char *wordlist = nvram_safe_get("olsrd_interfaces");
2460        char *addition = ">5.0>90.0>2.0>270.0>15.0>90.0>15.0>90.0";
2461        char *newadd = (char *)safe_malloc(strlen(wordlist) + strlen(addition) + strlen(ifname) + 2);
2462        if (strlen(wordlist) > 0) {
2463                strcpy(newadd, wordlist);
2464                strcat(newadd, " ");
2465                strcat(newadd, ifname);
2466        } else {
2467                strcpy(newadd, ifname);
2468        }
2469        strcat(newadd, addition);
2470        nvram_set("olsrd_interfaces", newadd);
2471        nvram_commit();
2472        free(newadd);
2473        return;
2474}
2475
2476void del_olsrd(webs_t wp)
2477{
2478        char *del = websGetVar(wp, "olsrd_delcount", NULL);
2479
2480        if (del == NULL)
2481                return;
2482        int d = atoi(del);
2483        char *wordlist = nvram_safe_get("olsrd_interfaces");
2484        char *newlist = (char *)calloc(strlen(wordlist) + 2, 1);
2485
2486        char *next;
2487        char word[128];
2488        int count = 0;
2489
2490        foreach(word, wordlist, next) {
2491                if (count != d) {
2492                        strcat(newlist, " ");
2493                        strcat(newlist, word);
2494                }
2495                count++;
2496        }
2497        nvram_set("olsrd_interfaces", newlist);
2498        nvram_commit();
2499        free(newlist);
2500        return;
2501}
2502
2503void save_olsrd(webs_t wp)
2504{
2505        char *wordlist = nvram_safe_get("olsrd_interfaces");
2506        char *newlist = (char *)calloc(strlen(wordlist) + 512, 1);
2507
2508        char *next;
2509        char word[64];
2510
2511        foreach(word, wordlist, next) {
2512                char *interface = word;
2513                char *dummy = interface;
2514
2515                strsep(&dummy, ">");
2516                char valuename[32];
2517
2518                sprintf(valuename, "%s_hellointerval", interface);
2519                char *hellointerval = websGetVar(wp, valuename, "0");
2520
2521                sprintf(valuename, "%s_hellovaliditytime", interface);
2522                char *hellovaliditytime = websGetVar(wp, valuename, "0");
2523
2524                sprintf(valuename, "%s_tcinterval", interface);
2525                char *tcinterval = websGetVar(wp, valuename, "0");
2526
2527                sprintf(valuename, "%s_tcvaliditytime", interface);
2528                char *tcvaliditytime = websGetVar(wp, valuename, "0");
2529
2530                sprintf(valuename, "%s_midinterval", interface);
2531                char *midinterval = websGetVar(wp, valuename, "0");
2532
2533                sprintf(valuename, "%s_midvaliditytime", interface);
2534                char *midvaliditytime = websGetVar(wp, valuename, "0");
2535
2536                sprintf(valuename, "%s_hnainterval", interface);
2537                char *hnainterval = websGetVar(wp, valuename, "0");
2538
2539                sprintf(valuename, "%s_hnavaliditytime", interface);
2540                char *hnavaliditytime = websGetVar(wp, valuename, "0");
2541                char *tmp;
2542                asprintf(&tmp, "%s %s>%s>%s>%s>%s>%s>%s>%s>%s", newlist, interface, hellointerval, hellovaliditytime, tcinterval, tcvaliditytime, midinterval, midvaliditytime, hnainterval, hnavaliditytime);
2543                strcpy(newlist, tmp);
2544                free(tmp);
2545        }
2546        nvram_set("olsrd_interfaces", newlist);
2547        nvram_commit();
2548        free(newlist);
2549        return;
2550}
2551#endif
2552
2553#ifdef HAVE_VLANTAGGING
2554
2555static void trunkspaces(char *str)
2556{
2557        int len = strlen(str);
2558        int i;
2559        for (i = 0; i < len; i++) {
2560                if (str[i] == ' ') {
2561                        memmove(&str[i], &str[i + 1], len - i);
2562                        i--;
2563                        len = strlen(str);
2564                        continue;
2565                }
2566        }
2567}
2568
2569void save_networking(webs_t wp)
2570{
2571        char *value = websGetVar(wp, "action", "");
2572        int vlancount = nvram_geti("vlan_tagcount");
2573        int bridgescount = nvram_geti("bridges_count");
2574        int bridgesifcount = nvram_geti("bridgesif_count");
2575        int mdhcpd_count = nvram_geti("mdhcpd_count");
2576#ifdef HAVE_IPVS
2577        int ipvscount = nvram_geti("ipvs_count");
2578        int ipvstargetcount = nvram_geti("ipvstarget_count");
2579#endif
2580#ifdef HAVE_BONDING
2581        int bondcount = nvram_geti("bonding_count");
2582#endif
2583        int i;
2584
2585        // save vlan stuff
2586        char buffer[1024];
2587
2588        memset(buffer, 0, 1024);
2589        for (i = 0; i < vlancount; i++) {
2590                char *ifname, *tag, *prio;
2591                char var[32];
2592
2593                sprintf(var, "vlanifname%d", i);
2594                ifname = websGetVar(wp, var, NULL);
2595                if (!ifname)
2596                        break;
2597                sprintf(var, "vlantag%d", i);
2598                tag = websGetVar(wp, var, NULL);
2599                if (!tag)
2600                        break;
2601                sprintf(var, "vlanprio%d", i);
2602                prio = websGetVar(wp, var, NULL);
2603                if (!prio)
2604                        break;
2605                strcat(buffer, ifname);
2606                strcat(buffer, ">");
2607                strcat(buffer, tag);
2608                strcat(buffer, ">");
2609                strcat(buffer, prio);
2610                if (i < vlancount - 1)
2611                        strcat(buffer, " ");
2612        }
2613        nvram_set("vlan_tags", buffer);
2614        // save bonds
2615        memset(buffer, 0, 1024);
2616#ifdef HAVE_BONDING
2617        char *bondingnumber = websGetVar(wp, "bonding_number", NULL);
2618
2619        if (bondingnumber)
2620                nvram_set("bonding_number", bondingnumber);
2621        char *bondingtype = websGetVar(wp, "bonding_type", NULL);
2622
2623        if (bondingtype)
2624                nvram_set("bonding_type", bondingtype);
2625        for (i = 0; i < bondcount; i++) {
2626                char *ifname, *tag;
2627                char var[32];
2628
2629                sprintf(var, "bondingifname%d", i);
2630                ifname = websGetVar(wp, var, NULL);
2631                if (!ifname)
2632                        break;
2633                sprintf(var, "bondingattach%d", i);
2634                tag = websGetVar(wp, var, NULL);
2635                if (!tag)
2636                        break;
2637                strcat(buffer, ifname);
2638                strcat(buffer, ">");
2639                strcat(buffer, tag);
2640                if (i < bondcount - 1)
2641                        strcat(buffer, " ");
2642        }
2643        nvram_set("bondings", buffer);
2644        memset(buffer, 0, 1024);
2645#endif
2646#ifdef HAVE_IPVS
2647        {
2648                char var[32];
2649                sprintf(var, "ipvsrole");
2650                char *ipvsrole = websGetVar(wp, var, NULL);
2651                if (ipvsrole) {
2652                        if (!strcmp(ipvsrole, "Master"))
2653                                nvram_set("ipvs_role", "master");
2654                        else
2655                                nvram_set("ipvs_role", "backup");
2656                }
2657
2658        }
2659        for (i = 0; i < ipvscount; i++) {
2660                char *ipvsname;
2661                char *ipvsip;
2662                char *ipvsport;
2663                char *ipvsproto;
2664                char *ipvsscheduler;
2665                char var[32];
2666                sprintf(var, "ipvsname%d", i);
2667                ipvsname = websGetVar(wp, var, NULL);
2668                if (!ipvsname)
2669                        break;
2670                trunkspaces(ipvsname);
2671
2672                sprintf(var, "ipvsip%d", i);
2673                ipvsip = websGetVar(wp, var, NULL);
2674                if (!ipvsip)
2675                        break;
2676                trunkspaces(ipvsip);
2677
2678                sprintf(var, "ipvsport%d", i);
2679                ipvsport = websGetVar(wp, var, NULL);
2680                if (!ipvsport)
2681                        break;
2682                trunkspaces(ipvsport);
2683
2684                sprintf(var, "ipvsscheduler%d", i);
2685                ipvsscheduler = websGetVar(wp, var, NULL);
2686                if (!ipvsscheduler)
2687                        break;
2688                trunkspaces(ipvsscheduler);
2689
2690                sprintf(var, "ipvsproto%d", i);
2691                ipvsproto = websGetVar(wp, var, NULL);
2692                if (!ipvsproto)
2693                        break;
2694                trunkspaces(ipvsproto);
2695
2696                strcat(buffer, ipvsname);
2697                strcat(buffer, ">");
2698                strcat(buffer, ipvsip);
2699                strcat(buffer, ">");
2700                strcat(buffer, ipvsport);
2701                strcat(buffer, ">");
2702                strcat(buffer, ipvsscheduler);
2703                strcat(buffer, ">");
2704                strcat(buffer, ipvsproto);
2705                if (i < ipvscount - 1)
2706                        strcat(buffer, " ");
2707        }
2708        nvram_set("ipvs", buffer);
2709        memset(buffer, 0, 1024);
2710
2711        for (i = 0; i < ipvstargetcount; i++) {
2712                char *ipvsname;
2713                char *ipvsip;
2714                char *ipvsport;
2715                char *ipvsweight;
2716                char *ipvsnat;
2717                char var[32];
2718                sprintf(var, "target_ipvsname%d", i);
2719                ipvsname = websGetVar(wp, var, NULL);
2720                if (!ipvsname)
2721                        break;
2722                trunkspaces(ipvsname);
2723
2724                sprintf(var, "target_ipvsip%d", i);
2725                ipvsip = websGetVar(wp, var, NULL);
2726                if (!ipvsip)
2727                        break;
2728                trunkspaces(ipvsip);
2729
2730                sprintf(var, "target_ipvsport%d", i);
2731                ipvsport = websGetVar(wp, var, NULL);
2732                if (!ipvsport)
2733                        break;
2734                trunkspaces(ipvsport);
2735
2736                sprintf(var, "target_ipvsweight%d", i);
2737                ipvsweight = websGetVar(wp, var, NULL);
2738                if (!ipvsweight)
2739                        break;
2740                trunkspaces(ipvsweight);
2741                sprintf(var, "target_ipvsmasquerade%d", i);
2742                ipvsnat = websGetVar(wp, var, "0");
2743                if (!ipvsnat)
2744                        break;
2745                trunkspaces(ipvsnat);
2746
2747                strcat(buffer, ipvsname);
2748                strcat(buffer, ">");
2749                strcat(buffer, ipvsip);
2750                strcat(buffer, ">");
2751                strcat(buffer, ipvsport);
2752                strcat(buffer, ">");
2753                strcat(buffer, ipvsweight);
2754                strcat(buffer, ">");
2755                strcat(buffer, ipvsnat);
2756                if (i < ipvstargetcount - 1)
2757                        strcat(buffer, " ");
2758        }
2759        nvram_set("ipvstarget", buffer);
2760        memset(buffer, 0, 1024);
2761
2762#endif
2763
2764        // save bridges
2765
2766        for (i = 0; i < bridgescount; i++) {
2767                char *ifname, *tag, *prio, *mtu, *mcast;
2768                char var[32];
2769                char ipaddr[32];
2770                char netmask[32];
2771                char n[32];
2772
2773                memset(ipaddr, 0, 32);
2774                memset(netmask, 0, 32);
2775                sprintf(var, "bridgename%d", i);
2776                ifname = websGetVar(wp, var, NULL);
2777                if (!ifname)
2778                        break;
2779                sprintf(var, "bridgestp%d", i);
2780                tag = websGetVar(wp, var, NULL);
2781                if (!tag)
2782                        break;
2783                sprintf(var, "bridgemcastbr%d", i);
2784                mcast = websGetVar(wp, var, NULL);
2785                if (!mcast) {
2786                        break;
2787                } else {
2788                        sprintf(n, "%s_mcast", ifname);
2789                        if (!strcmp(mcast, "On"))
2790                                nvram_seti(n, 1);
2791                        else
2792                                nvram_seti(n, 0);
2793                }
2794                sprintf(var, "bridgeprio%d", i);
2795                prio = websGetVar(wp, var, NULL);
2796                if (!prio)
2797                        prio = "32768";
2798                if (strlen(prio) == 0)
2799                        prio = "32768";
2800
2801                sprintf(var, "bridgemtu%d", i);
2802                mtu = websGetVar(wp, var, NULL);
2803                if (!mtu)
2804                        mtu = "1500";
2805                if (strlen(prio) == 0)
2806                        mtu = "1500";
2807
2808                copymergetonv(wp, "%s_ipaddr", ifname);
2809
2810                copymergetonv(wp, "%s_netmask", ifname);
2811
2812                strcat(buffer, ifname);
2813                strcat(buffer, ">");
2814                if (!strcmp(tag, "On"))
2815                        strcat(buffer, "On");
2816                else
2817                        strcat(buffer, "Off");
2818                strcat(buffer, ">");
2819                strcat(buffer, prio);
2820                strcat(buffer, ">");
2821                strcat(buffer, mtu);
2822                if (i < bridgescount - 1)
2823                        strcat(buffer, " ");
2824
2825                char brname[32];
2826
2827                if (!strcmp(ifname, "br0"))
2828                        sprintf(brname, "lan_hwaddr");
2829                else
2830                        sprintf(brname, "%s_hwaddr", ifname);
2831
2832                nvram_set(brname, websGetVar(wp, brname, NULL));
2833        }
2834        nvram_set("bridges", buffer);
2835        // save bridge assignment
2836        memset(buffer, 0, 1024);
2837        for (i = 0; i < bridgesifcount; i++) {
2838                char *ifname, *tag, *prio;
2839                char var[32];
2840
2841                sprintf(var, "bridge%d", i);
2842                ifname = websGetVar(wp, var, NULL);
2843                if (!ifname)
2844                        break;
2845                sprintf(var, "bridgeif%d", i);
2846                tag = websGetVar(wp, var, NULL);
2847                if (!tag)
2848                        break;
2849                sprintf(var, "bridgeifprio%d", i);
2850                prio = websGetVar(wp, var, NULL);
2851                if (!prio)
2852                        prio = "128";
2853                if (strlen(prio) == 0)
2854                        prio = "128";
2855                strcat(buffer, ifname);
2856                strcat(buffer, ">");
2857                strcat(buffer, tag);
2858                strcat(buffer, ">");
2859                strcat(buffer, prio);
2860                if (i < bridgesifcount - 1)
2861                        strcat(buffer, " ");
2862        }
2863        nvram_set("bridgesif", buffer);
2864#ifdef HAVE_MDHCP
2865        // save multipe dhcp-servers
2866        memset(buffer, 0, 1024);
2867        // if (!interface || !start || !dhcpon || !max || !leasetime)
2868        for (i = 0; i < mdhcpd_count; i++) {
2869                char *mdhcpinterface, *mdhcpon, *mdhcpstart, *mdhcpmax, *mdhcpleasetime;
2870                char var[32];
2871
2872                sprintf(var, "mdhcpifname%d", i);
2873                mdhcpinterface = websGetVar(wp, var, NULL);
2874                if (!mdhcpinterface)
2875                        break;
2876
2877                sprintf(var, "mdhcpon%d", i);
2878                mdhcpon = websGetVar(wp, var, NULL);
2879                if (!mdhcpon)
2880                        break;
2881
2882                sprintf(var, "mdhcpstart%d", i);
2883                mdhcpstart = websGetVar(wp, var, NULL);
2884                if (!mdhcpstart)
2885                        break;
2886
2887                sprintf(var, "mdhcpmax%d", i);
2888                mdhcpmax = websGetVar(wp, var, NULL);
2889                if (!mdhcpmax)
2890                        break;
2891
2892                sprintf(var, "mdhcpleasetime%d", i);
2893                mdhcpleasetime = websGetVar(wp, var, NULL);
2894                if (!mdhcpleasetime)
2895                        break;
2896
2897                strcat(buffer, mdhcpinterface);
2898                strcat(buffer, ">");
2899                strcat(buffer, mdhcpon);
2900                strcat(buffer, ">");
2901                strcat(buffer, mdhcpstart);
2902                strcat(buffer, ">");
2903                strcat(buffer, mdhcpmax);
2904                strcat(buffer, ">");
2905                strcat(buffer, mdhcpleasetime);
2906                if (i < mdhcpd_count - 1)
2907                        strcat(buffer, " ");
2908        }
2909        nvram_set("mdhcpd", buffer);
2910#endif
2911#ifdef HAVE_PORTSETUP
2912        validate_portsetup(wp, NULL, NULL);
2913#endif
2914
2915        applytake(value);
2916}
2917
2918void add_vlan(webs_t wp)
2919{
2920        char word[256];
2921        char *next, *wordlist;
2922        int count = 0;
2923        int realcount = nvram_geti("vlan_tagcount");
2924
2925        if (realcount == 0) {
2926                wordlist = nvram_safe_get("vlan_tags");
2927                foreach(word, wordlist, next) {
2928                        count++;
2929                }
2930                realcount = count;
2931        }
2932        realcount++;
2933        char var[32];
2934
2935        sprintf(var, "%d", realcount);
2936        nvram_set("vlan_tagcount", var);
2937        nvram_commit();
2938        return;
2939}
2940
2941void del_vlan(webs_t wp)
2942{
2943        char word[256];
2944        int realcount = 0;
2945        char *next, *wordlist, *newwordlist;
2946        char *val = websGetVar(wp, "del_value", NULL);
2947
2948        if (val == NULL)
2949                return;
2950        int todel = atoi(val);
2951
2952        wordlist = nvram_safe_get("vlan_tags");
2953        newwordlist = (char *)calloc(strlen(wordlist) + 2, 1);
2954        int count = 0;
2955
2956        foreach(word, wordlist, next) {
2957                if (count != todel) {
2958                        strcat(newwordlist, word);
2959                        strcat(newwordlist, " ");
2960                } else {
2961                        char *port = word;
2962                        char *tag = strsep(&port, ">");
2963
2964                        if (!tag || !port)
2965                                break;
2966                        char names[32];
2967
2968                        sprintf(names, "%s.%s", tag, port);
2969                        eval("ifconfig", names, "down");
2970                        eval("vconfig", "rem", names);
2971                }
2972                count++;
2973        }
2974
2975        char var[32];
2976
2977        realcount = nvram_geti("vlan_tagcount") - 1;
2978        sprintf(var, "%d", realcount);
2979        nvram_set("vlan_tagcount", var);
2980        nvram_set("vlan_tags", newwordlist);
2981        nvram_commit();
2982        free(newwordlist);
2983
2984        return;
2985}
2986
2987void add_mdhcp(webs_t wp)
2988{
2989        char word[256];
2990        char *next, *wordlist;
2991        int count = 0;
2992        int realcount = nvram_geti("mdhcpd_count");
2993
2994        if (realcount == 0) {
2995                wordlist = nvram_safe_get("mdhcpd");
2996                foreach(word, wordlist, next) {
2997                        count++;
2998                }
2999                realcount = count;
3000        }
3001        realcount++;
3002        char var[32];
3003
3004        sprintf(var, "%d", realcount);
3005        nvram_set("mdhcpd_count", var);
3006        nvram_commit();
3007        return;
3008}
3009
3010void del_mdhcp(webs_t wp)
3011{
3012        char word[256];
3013        int realcount = 0;
3014        char *next, *wordlist, *newwordlist;
3015        char *val = websGetVar(wp, "del_value", NULL);
3016
3017        if (val == NULL)
3018                return;
3019        int todel = atoi(val);
3020
3021        wordlist = nvram_safe_get("mdhcpd");
3022        newwordlist = (char *)calloc(strlen(wordlist) + 2, 1);
3023        int count = 0;
3024
3025        foreach(word, wordlist, next) {
3026                if (count != todel) {
3027                        strcat(newwordlist, word);
3028                        strcat(newwordlist, " ");
3029                }
3030                count++;
3031        }
3032
3033        char var[32];
3034
3035        realcount = nvram_geti("mdhcpd_count") - 1;
3036        sprintf(var, "%d", realcount);
3037        nvram_set("mdhcpd_count", var);
3038        nvram_set("mdhcpd", newwordlist);
3039        nvram_commit();
3040        free(newwordlist);
3041
3042        return;
3043}
3044
3045void del_bridge(webs_t wp)
3046{
3047        char word[256];
3048        int realcount = 0;
3049        char *next, *wordlist, *newwordlist;
3050        char *val = websGetVar(wp, "del_value", NULL);
3051
3052        if (val == NULL)
3053                return;
3054        int todel = atoi(val);
3055
3056        wordlist = nvram_safe_get("bridges");
3057        newwordlist = (char *)calloc(strlen(wordlist) + 2, 1);
3058        int count = 0;
3059
3060        foreach(word, wordlist, next) {
3061                if (count != todel) {
3062                        strcat(newwordlist, word);
3063                        strcat(newwordlist, " ");
3064                } else {
3065                        char *port = word;
3066                        char *tag = strsep(&port, ">");
3067                        char *prio = port;
3068
3069                        strsep(&prio, ">");
3070                        if (!tag || !port)
3071                                continue;
3072                        eval("ifconfig", tag, "down");
3073                        eval("brctl", "delbr", tag);
3074                }
3075                count++;
3076        }
3077
3078        realcount = nvram_geti("bridges_count") - 1;
3079        char var[32];
3080
3081        sprintf(var, "%d", realcount);
3082        nvram_set("bridges_count", var);
3083        nvram_set("bridges", newwordlist);
3084        nvram_commit();
3085        free(newwordlist);
3086
3087        return;
3088}
3089
3090void add_bridge(webs_t wp)
3091{
3092        char word[256];
3093        char *next, *wordlist;
3094        int count = 0;
3095        int realcount = nvram_geti("bridges_count");
3096
3097        if (realcount == 0) {
3098                wordlist = nvram_safe_get("bridges");
3099                foreach(word, wordlist, next) {
3100                        count++;
3101                }
3102                realcount = count;
3103        }
3104        realcount++;
3105        char var[32];
3106
3107        sprintf(var, "%d", realcount);
3108        nvram_set("bridges_count", var);
3109        nvram_commit();
3110        return;
3111}
3112
3113void del_bridgeif(webs_t wp)
3114{
3115        char word[256];
3116        int realcount = 0;
3117        char *next, *wordlist, *newwordlist;
3118        char *val = websGetVar(wp, "del_value", NULL);
3119
3120        if (val == NULL)
3121                return;
3122        int todel = atoi(val);
3123
3124        wordlist = nvram_safe_get("bridgesif");
3125        newwordlist = (char *)calloc(strlen(wordlist) + 2, 1);
3126        int count = 0;
3127
3128        foreach(word, wordlist, next) {
3129                if (count != todel) {
3130                        strcat(newwordlist, word);
3131                        strcat(newwordlist, " ");
3132                }
3133                count++;
3134        }
3135
3136        char var[32];
3137
3138        realcount = nvram_geti("bridgesif_count") - 1;
3139        sprintf(var, "%d", realcount);
3140        nvram_set("bridgesif_count", var);
3141        nvram_set("bridgesif", newwordlist);
3142        nvram_commit();
3143        free(newwordlist);
3144
3145        return;
3146}
3147
3148void add_bridgeif(webs_t wp)
3149{
3150
3151        char word[256];
3152        char *next, *wordlist;
3153        int count = 0;
3154        int realcount = nvram_geti("bridgesif_count");
3155
3156        if (realcount == 0) {
3157                wordlist = nvram_safe_get("bridgesif");
3158                foreach(word, wordlist, next) {
3159                        count++;
3160                }
3161                realcount = count;
3162        }
3163        realcount++;
3164        char var[32];
3165
3166        sprintf(var, "%d", realcount);
3167        nvram_set("bridgesif_count", var);
3168        nvram_commit();
3169        return;
3170}
3171
3172#endif
3173#ifdef HAVE_IPVS
3174void add_ipvs(webs_t wp)
3175{
3176        char word[256];
3177        char *next, *wordlist;
3178        int count = 0;
3179        int realcount = nvram_geti("ipvs_count");
3180
3181        if (realcount == 0) {
3182                wordlist = nvram_safe_get("ipvs");
3183                foreach(word, wordlist, next) {
3184                        count++;
3185                }
3186                realcount = count;
3187        }
3188        realcount++;
3189        char var[32];
3190
3191        sprintf(var, "%d", realcount);
3192        nvram_set("ipvs_count", var);
3193        nvram_commit();
3194        return;
3195}
3196
3197void del_ipvs(webs_t wp)
3198{
3199        char word[256];
3200        int realcount = 0;
3201        char *next, *wordlist, *newwordlist;
3202        char *val = websGetVar(wp, "del_value", NULL);
3203
3204        if (val == NULL)
3205                return;
3206        int todel = atoi(val);
3207
3208        wordlist = nvram_safe_get("ipvs");
3209        newwordlist = (char *)calloc(strlen(wordlist), 1);
3210        int count = 0;
3211
3212        foreach(word, wordlist, next) {
3213                if (count != todel) {
3214                        strcat(newwordlist, word);
3215                        strcat(newwordlist, " ");
3216                }
3217                count++;
3218        }
3219
3220        realcount = nvram_geti("ipvs_count") - 1;
3221        char var[32];
3222
3223        sprintf(var, "%d", realcount);
3224        nvram_set("ipvs_count", var);
3225        nvram_set("ipvs", newwordlist);
3226        nvram_commit();
3227        free(newwordlist);
3228        return;
3229}
3230
3231void add_ipvstarget(webs_t wp)
3232{
3233        char word[256];
3234        char *next, *wordlist;
3235        int count = 0;
3236        int realcount = nvram_geti("ipvstarget_count");
3237
3238        if (realcount == 0) {
3239                wordlist = nvram_safe_get("ipvstarget");
3240                foreach(word, wordlist, next) {
3241                        count++;
3242                }
3243                realcount = count;
3244        }
3245        realcount++;
3246        char var[32];
3247
3248        sprintf(var, "%d", realcount);
3249        nvram_set("ipvstarget_count", var);
3250        nvram_commit();
3251        return;
3252}
3253
3254void del_ipvstarget(webs_t wp)
3255{
3256        char word[256];
3257        int realcount = 0;
3258        char *next, *wordlist, *newwordlist;
3259        char *val = websGetVar(wp, "del_value", NULL);
3260
3261        if (val == NULL)
3262                return;
3263        int todel = atoi(val);
3264
3265        wordlist = nvram_safe_get("ipvstarget");
3266        newwordlist = (char *)calloc(strlen(wordlist), 1);
3267        int count = 0;
3268
3269        foreach(word, wordlist, next) {
3270                if (count != todel) {
3271                        strcat(newwordlist, word);
3272                        strcat(newwordlist, " ");
3273                }
3274                count++;
3275        }
3276
3277        realcount = nvram_geti("ipvstarget_count") - 1;
3278        char var[32];
3279
3280        sprintf(var, "%d", realcount);
3281        nvram_set("ipvstarget_count", var);
3282        nvram_set("ipvstarget", newwordlist);
3283        nvram_commit();
3284        free(newwordlist);
3285        return;
3286}
3287
3288#endif
3289
3290static void save_prefix(webs_t wp, char *prefix)
3291{
3292        char n[80];
3293
3294#ifdef HAVE_RELAYD
3295        char gwaddr[32];
3296        copytonv(wp, "%s_relayd_gw_auto", prefix);
3297        copymergetonv(wp, "%s_relayd_gw_ipaddr", prefix);
3298#endif
3299#ifdef HAVE_IFL
3300#ifdef HAVE_NEXTMEDIA
3301        copytonv(wp, "%s_label", prefix);
3302#endif
3303        copytonv(wp, "%s_note", prefix);
3304#endif
3305#ifdef HAVE_MADWIFI
3306        char sifs[80];
3307        char turbo[80];
3308        char chanbw[80];
3309        char preamble[80];
3310        int cbwchanged = 0;
3311        copytonv(wp, "rate_control");
3312#endif
3313        sprintf(n, "%s_ssid", prefix);
3314        copytonv(wp, n);
3315        if (!strcmp(prefix, "wl0") || !strcmp(prefix, "wl1") || !strcmp(prefix, "wl2")) {
3316                char *wl = websGetVar(wp, n, NULL);
3317
3318                cprintf("copy value %s which is [%s] to nvram\n", n, wl);
3319                if (wl) {
3320                        if (!strcmp(prefix, "wl0"))
3321                                nvram_set("wl_ssid", wl);
3322                        else if (!strcmp(prefix, "wl1"))
3323                                nvram_set("wl1_ssid", wl);
3324                        else
3325                                nvram_set("wl2_ssid", wl);
3326                }
3327        }
3328        copytonv(wp, "%s_distance", prefix);
3329#ifdef HAVE_MADWIFI
3330        {
3331                sprintf(n, "%s_txpwrdbm", prefix);
3332                char *sl = websGetVar(wp, n, NULL);
3333
3334                if (sl) {
3335                        int base = atoi(sl);
3336#ifdef HAVE_WIKINGS
3337/*                      if (base > 28)
3338                                base = 28;
3339#ifdef HAVE_SUB3
3340                        if (base > 25)
3341                                base = 25;
3342#endif
3343#ifdef HAVE_SUB6
3344                        if (base > 22)
3345                                base = 22;
3346#endif*/
3347#endif
3348
3349#ifdef HAVE_ESPOD
3350                        if (base > 30)
3351                                base = 30;
3352#ifdef HAVE_SUB6
3353                        if (base > 30)
3354                                base = 30;
3355#endif
3356#ifdef HAVE_SUB3
3357                        if (base > 28)
3358                                base = 28;
3359#endif
3360#endif
3361                        int txpower = base - wifi_gettxpoweroffset(prefix);
3362
3363                        if (txpower < 1)
3364                                txpower = 1;
3365                        sprintf(turbo, "%d", txpower);
3366                        nvram_set(n, turbo);
3367                }
3368        }
3369        copytonv(wp, "%s_antgain", prefix);
3370        copytonv(wp, "%s_regulatory", prefix);
3371        sprintf(n, "%s_scanlist", prefix);
3372        {
3373                char *sl = websGetVar(wp, n, NULL);
3374
3375                if (sl) {
3376                        char *slc = (char *)safe_malloc(strlen(sl) + 1);
3377
3378                        strcpy(slc, sl);
3379                        int i, sllen = strlen(slc);
3380
3381                        for (i = 0; i < sllen; i++) {
3382                                if (slc[i] == ';')
3383                                        slc[i] = ' ';
3384                                if (slc[i] == ',')
3385                                        slc[i] = ' ';
3386                        }
3387                        nvram_set(n, slc);
3388                        free(slc);
3389                }
3390        }
3391#ifdef HAVE_MAKSAT
3392        copytonv(wp, "ath_specialmode");
3393#endif
3394        copytonv(wp, "%s_regdomain", prefix);
3395
3396        copytonv(wp, "%s_rts", prefix);
3397        if (nvram_nmatch("1", "%s_rts", prefix)) {
3398                sprintf(turbo, "%s_rtsvalue", prefix);
3399                char *tw = websGetVar(wp, turbo, NULL);
3400
3401                if (tw) {
3402                        if (atoi(tw) < 1)
3403                                tw = "1";
3404                        if (atoi(tw) > 2346)
3405                                tw = "2346";
3406                        nvram_nset(tw, "%s_rtsvalue", prefix);
3407                }
3408        }
3409        copytonv(wp, "%s_protmode", prefix);
3410        copytonv(wp, "%s_minrate", prefix);
3411        copytonv(wp, "%s_maxrate", prefix);
3412        copytonv(wp, "%s_xr", prefix);
3413        copytonv(wp, "%s_outdoor", prefix);
3414//    copytonv( wp, "%s_compression", prefix ); // Atheros SuperG header
3415        // compression
3416        copytonv(wp, "%s_ff", prefix);  // ff = 0, Atheros SuperG fast
3417        // framing disabled, 1 fast framing
3418        // enabled
3419        copytonv(wp, "%s_diversity", prefix);
3420        copytonv(wp, "%s_preamble", prefix);
3421#ifdef HAVE_ATH9K
3422        copytonv(wp, "%s_shortgi", prefix);
3423#endif
3424#ifdef HAVE_ATH10K
3425        copytonv(wp, "%s_subf", prefix);
3426        copytonv(wp, "%s_mubf", prefix);
3427#endif
3428        copytonv(wp, "%s_wmm", prefix);
3429        copytonv(wp, "%s_bcn", prefix);
3430        copytonv(wp, "%s_dtim", prefix);
3431        copytonv(wp, "%s_txantenna", prefix);
3432        copytonv(wp, "%s_rxantenna", prefix);
3433        copytonv(wp, "%s_intmit", prefix);
3434        copytonv(wp, "%s_csma", prefix);
3435        copytonv(wp, "%s_noise_immunity", prefix);
3436        copytonv(wp, "%s_ofdm_weak_det", prefix);
3437
3438        copytonv(wp, "%s_chanshift", prefix);
3439        copytonv(wp, "%s_doth", prefix);
3440        copytonv(wp, "%s_maxassoc", prefix);
3441
3442        sprintf(chanbw, "%s_channelbw", prefix);
3443        char *cbw = websGetVar(wp, chanbw, NULL);
3444
3445        if (cbw && !nvram_match(chanbw, cbw)) {
3446                cbwchanged = 1;
3447        }
3448        if (cbw)
3449                nvram_set(chanbw, cbw);
3450
3451        copytonv(wp, "%s_xr", prefix);
3452        copytonv(wp, "%s_sifstime", prefix);
3453        copytonv(wp, "%s_preambletime", prefix);
3454        copytonv(wp, "%s_mtikie", prefix);
3455        copytonv(wp, "%s_cardtype", prefix);
3456
3457#endif
3458        copytonv(wp, "%s_closed", prefix);
3459        if (has_ac(prefix) && has_2ghz(prefix)) {
3460                copytonv(wp, "%s_turbo_qam", prefix);
3461        }
3462#ifdef HAVE_80211AC
3463#ifndef HAVE_NOAC
3464        copytonv(wp, "%s_wmf_bss_enable", prefix);
3465        if (has_ac(prefix)) {
3466                copytonv(wp, "%s_nitro_qam", prefix);
3467        }
3468        if (has_beamforming(prefix)) {
3469                copytonv(wp, "%s_txbf", prefix);
3470                copytonv(wp, "%s_itxbf", prefix);
3471                copytonv(wp, "%s_atf", prefix);
3472        }
3473#endif
3474#endif
3475
3476#ifndef HAVE_MADWIFI
3477        char *ifname = "wl0";
3478
3479#ifndef HAVE_RT2880
3480
3481        if (!strcmp(prefix, "wl0"))
3482                ifname = get_wl_instance_name(0);
3483        else if (!strcmp(prefix, "wl1"))
3484                ifname = get_wl_instance_name(1);
3485        else if (!strcmp(prefix, "wl2"))
3486                ifname = get_wl_instance_name(2);
3487        else
3488                ifname = prefix;
3489#else
3490        ifname = getRADev(prefix);
3491#endif
3492        copytonv(wp, "%s_multicast", ifname);
3493        copytonv(wp, "%s_bridged", ifname);
3494        copytonv(wp, "%s_nat", ifname);
3495        copytonv(wp, "%s_isolation", ifname);
3496        copytonv(wp, "%s_dns_redirect", ifname);
3497
3498        copymergetonv(wp, "%s_dns_ipaddr", ifname);
3499        copymergetonv(wp, "%s_ipaddr", ifname);
3500        copymergetonv(wp, "%s_netmask", ifname);
3501
3502#else
3503
3504        copytonv(wp, "%s_multicast", prefix);
3505        copytonv(wp, "%s_bridged", prefix);
3506        copytonv(wp, "%s_nat", prefix);
3507        copytonv(wp, "%s_isolation", prefix);
3508        copytonv(wp, "%s_dns_redirect", prefix);
3509        copymergetonv(wp, "%s_dns_ipaddr", prefix);
3510        copymergetonv(wp, "%s_ipaddr", prefix);
3511        copymergetonv(wp, "%s_netmask", prefix);
3512
3513        copytonv(wp, "%s_duallink", prefix);
3514
3515        copymergetonv(wp, "%s_duallink_parent", prefix);
3516
3517#endif
3518
3519        copytonv(wp, "%s_ap_isolate", prefix);
3520        sprintf(n, "%s_mode", prefix);
3521        char *wl_newmode = websGetVar(wp, n, NULL);
3522        if (wl_newmode && (nvram_match(n, "sta") || nvram_match(n, "apsta")) && strcmp(wl_newmode, "sta") && strcmp(wl_newmode, "apsta"))
3523                notifywanChange();
3524
3525        if (wl_newmode && nvram_match(n, "ap") && (!strcmp(wl_newmode, "sta") || !strcmp(wl_newmode, "apsta")))
3526                notifywanChange();
3527
3528        if (nvram_match(n, "sta")) {
3529
3530                if (wl_newmode)
3531                        if ((!strcmp(wl_newmode, "ap") || !strcmp(wl_newmode, "wdsap")
3532                             || !strcmp(wl_newmode, "infra") || !strcmp(wl_newmode, "wdssta"))
3533                            && nvram_invmatch("wan_proto", "3g")) {
3534                                nvram_set("wan_proto", "disabled");
3535                        }
3536        }
3537        copytonv(wp, n);
3538        if (!strcmp(prefix, "wl0") || !strcmp(prefix, "wl1") || !strcmp(prefix, "wl2")) {
3539                char *wl = websGetVar(wp, n, NULL);
3540
3541                cprintf("copy value %s which is [%s] to nvram\n", n, wl);
3542                if (wl && !strcmp(prefix, "wl0"))
3543                        nvram_set("wl_mode", wl);
3544#ifndef HAVE_MADWIFI
3545                if (wl && strcmp(wl, "ap") && strcmp(wl, "apsta")
3546                    && strcmp(wl, "apstawet")) {
3547                        nvram_nset("", "%s_vifs", prefix);
3548                }
3549#endif
3550        }
3551        int chanchanged = 0;
3552
3553#ifdef HAVE_RT2880
3554        copytonv(wp, "%s_greenfield", prefix);
3555#endif
3556
3557#ifndef HAVE_MADWIFI
3558        if (!strcmp(prefix, "wl0") || !strcmp(prefix, "wl1") || !strcmp(prefix, "wl2"))
3559#endif
3560        {
3561                sprintf(n, "%s_net_mode", prefix);
3562                if (!nvram_match(n, websGetVar(wp, n, ""))) {
3563                        chanchanged = 1;
3564                        copytonv(wp, n);
3565                        char *value = websGetVar(wp, n, "");
3566                        if (!strcmp(prefix, "wl0"))
3567#ifndef HAVE_MADWIFI
3568                                convert_wl_gmode(value, "wl0");
3569#else
3570                                convert_wl_gmode(value, "wl");
3571#endif
3572                        else
3573                                convert_wl_gmode(value, prefix);
3574                }
3575        }
3576#ifdef HAVE_MADWIFI
3577        if (cbwchanged || chanchanged) {
3578                if (nvram_matchi(chanbw, 40)) {
3579                        nvram_seti(sifs, 8);
3580                        nvram_seti(preamble, 14);
3581                } else if (nvram_matchi(chanbw, 5)) {
3582                        nvram_seti(sifs, 64);
3583                        nvram_seti(preamble, 80);
3584                } else if (nvram_matchi(chanbw, 10)) {
3585                        nvram_seti(sifs, 32);
3586                        nvram_seti(preamble, 40);
3587                } else {
3588                        nvram_seti(sifs, 16);
3589                        nvram_seti(preamble, 20);
3590                }
3591
3592        }
3593#endif
3594
3595        copytonv(wp, "%s_nbw", prefix);
3596        copytonv(wp, "%s_nctrlsb", prefix);
3597
3598        sprintf(n, "%s_channel", prefix);
3599        if (!strcmp(prefix, "wl0") || !strcmp(prefix, "wl1") || !strcmp(prefix, "wl2")) {
3600                char *wl = websGetVar(wp, n, NULL);
3601
3602                cprintf("copy value %s which is [%s] to nvram\n", n, wl);
3603                if (wl && !strcmp(prefix, "wl0"))
3604                        nvram_set("wl_channel", wl);
3605                else if (wl && !strcmp(prefix, "wl1"))
3606                        nvram_set("wl1_channel", wl);
3607                else
3608                        nvram_set("wl2_channel", wl);
3609        }
3610        copytonv(wp, n);
3611
3612        sprintf(n, "%s_wchannel", prefix);
3613        if (!strcmp(prefix, "wl0") || !strcmp(prefix, "wl1") || !strcmp(prefix, "wl2")) {
3614                char *wl = websGetVar(wp, n, NULL);
3615
3616                cprintf("copy value %s which is [%s] to nvram\n", n, wl);
3617                if (wl && !strcmp(prefix, "wl0"))
3618                        nvram_set("wl_wchannel", wl);
3619                else if (wl && !strcmp(prefix, "wl1"))
3620                        nvram_set("wl1_wchannel", wl);
3621                else
3622                        nvram_set("wl2_wchannel", wl);
3623
3624        }
3625
3626        copytonv(wp, n);
3627        copytonv(wp, "wl_reg_mode");
3628        copytonv(wp, "wl_tpc_db");
3629
3630#if defined(HAVE_NORTHSTAR) || defined(HAVE_80211AC) && !defined(HAVE_BUFFALO)
3631        sprintf(n, "wl_regdomain");
3632        char *reg = websGetVar(wp, n, NULL);
3633        if (reg) {
3634                if (strcmp(nvram_safe_get("wl_regdomain"), reg)) {
3635                        setRegulationDomain(reg);
3636                        eval("startstop", "lan");
3637                }
3638        }
3639        copytonv(wp, "wl_regdomain");
3640#endif
3641
3642}
3643
3644void wireless_join(webs_t wp)
3645{
3646        char *value = websGetVar(wp, "action", "");
3647        char *ssid = websGetVar(wp, "wl_ssid", NULL);
3648        if (ssid) {
3649                char *wifi = nvram_safe_get("wifi_display");
3650                if (strlen(wifi) > 0) {
3651                        if (!strcmp(wifi, "ath0"))
3652                                nvram_set("wl_ssid", ssid);
3653                        if (!strcmp(wifi, "wl0"))
3654                                nvram_set("wl_ssid", ssid);
3655                        nvram_nset(ssid, "%s_ssid", wifi);
3656                        nvram_set("cur_ssid", ssid);
3657                        nvram_commit();
3658                }
3659
3660        }
3661        applytake(value);
3662}
3663
3664void wireless_save(webs_t wp)
3665{
3666        char *value = websGetVar(wp, "action", "");
3667
3668        char *next;
3669        char var[80];
3670
3671#ifndef HAVE_MADWIFI
3672        int c = get_wl_instances();
3673        int i;
3674
3675        for (i = 0; i < c; i++) {
3676                char buf[16];
3677
3678                sprintf(buf, "wl%d", i);
3679                save_prefix(wp, buf);
3680                char *vifs = nvram_nget("wl%d_vifs", i);
3681#else
3682        int c = getdevicecount();
3683        int i;
3684
3685        for (i = 0; i < c; i++) {
3686                char buf[16];
3687
3688                sprintf(buf, "ath%d", i);
3689                save_prefix(wp, buf);
3690                char *vifs = nvram_nget("ath%d_vifs", i);
3691
3692#endif
3693                if (vifs == NULL)
3694                        return;
3695                foreach(var, vifs, next) {
3696                        save_prefix(wp, var);
3697                }
3698        }
3699
3700#ifdef HAVE_ERC
3701        struct variable filter_variables[] = {
3702              {argv:ARGV("1", "0")},
3703              {argv:ARGV("1", "0")},
3704        }, *which;
3705
3706        char *rd_off, *rd_boot_off;
3707
3708        rd_off = websGetVar(wp, "radiooff_button", NULL);
3709        rd_off = websGetVar(wp, "radiooff_button", NULL);
3710        if (!rd_off && !valid_choice(wp, rd_off, &which[0])) {
3711                return;
3712        }
3713        nvram_set("radiooff_button", rd_off);
3714
3715        rd_boot_off = websGetVar(wp, "radiooff_boot_off", NULL);
3716        if (!rd_boot_off && !valid_choice(wp, rd_boot_off, &which[1])) {
3717                return;
3718        }
3719        nvram_set("radiooff_boot_off", rd_boot_off);
3720#endif
3721        // nvram_commit ();
3722        applytake(value);
3723#ifdef HAVE_GUESTPORT
3724        eval("stopservice", "firewall");
3725        eval("startservice", "firewall");
3726#endif
3727}
3728
3729void hotspot_save(webs_t wp)
3730{
3731#ifdef HAVE_TIEXTRA1
3732        chillispot_save(wp);
3733#endif
3734#ifdef HAVE_TIEXTRA2
3735        wifidogs_save(wp);
3736#endif
3737        validate_cgi(wp);
3738}
3739
3740#ifdef HAVE_WIVIZ
3741void set_wiviz(webs_t wp)
3742{
3743
3744        char *hopdwell = websGetVar(wp, "hopdwell", NULL);
3745        char *hopseq = websGetVar(wp, "hopseq", NULL);
3746        FILE *fp = fopen("/tmp/wiviz2-cfg", "wb");
3747
3748        if (strstr(hopseq, ","))
3749                fprintf(fp, "channelsel=hop&");
3750        else
3751                fprintf(fp, "channelsel=%s&", hopseq);
3752
3753        fprintf(fp, "hopdwell=%s&hopseq=%s\n", hopdwell, hopseq);
3754
3755        nvram_set("hopdwell", hopdwell);
3756        nvram_set("hopseq", hopseq);
3757
3758        fclose(fp);
3759        killall("wiviz", SIGUSR2);
3760
3761}
3762#endif
3763
3764void ttraff_erase(webs_t wp)
3765{
3766        char line[2048];
3767        char *name = NULL;
3768
3769        system2("nvram show | grep traff- > /tmp/.ttraff");
3770        FILE *fp = fopen("/tmp/.ttraff", "r");
3771
3772        if (fp == NULL) {
3773                return;
3774        }
3775        while (fgets(line, sizeof(line), fp) != NULL) {
3776                if (startswith(line, "traff-")) {
3777                        name = strtok(line, "=");
3778                        if (strlen(name) == 13) //only unset ttraf-XX-XXXX
3779                        {
3780                                nvram_unset(name);
3781                        }
3782                }
3783        }
3784        nvram_commit();
3785        unlink("/tmp/.ttraff");
3786}
3787
3788void changepass(webs_t wp)
3789{
3790        char *value = websGetVar(wp, "http_username", NULL);
3791        char *pass = websGetVar(wp, "http_passwd", NULL);
3792
3793        if (value && pass && strcmp(value, TMP_PASSWD)
3794            && valid_name(wp, value, NULL)) {
3795                char passout[MD5_OUT_BUFSIZE];
3796                nvram_set("http_username", zencrypt(value, passout));
3797
3798                eval("/sbin/setpasswd");
3799#ifdef HAVE_IAS
3800                nvram_set("http_userpln", value);
3801#endif
3802        }
3803
3804        if (pass && value && strcmp(pass, TMP_PASSWD)
3805            && valid_name(wp, pass, NULL)) {
3806                char passout[MD5_OUT_BUFSIZE];
3807                nvram_set("http_passwd", zencrypt(pass, passout));
3808
3809                eval("/sbin/setpasswd");
3810#ifdef HAVE_IAS
3811                nvram_set("http_pwdpln", pass);
3812#endif
3813        }
3814        nvram_commit();
3815}
3816
3817#ifdef HAVE_CHILLILOCAL
3818
3819void user_remove(webs_t wp)
3820{
3821        macro_rem("fon_usernames", "fon_userlist");
3822}
3823
3824void user_add(webs_t wp)
3825{
3826        macro_add("fon_usernames");
3827        // validate_userlist(wp);
3828}
3829#endif
3830
3831#ifdef HAVE_RADLOCAL
3832
3833void raduser_add(webs_t wp)
3834{
3835        int radcount = 0;
3836        char *radc = nvram_get("iradius_count");
3837
3838        if (radc != NULL)
3839                radcount = atoi(radc);
3840        radcount++;
3841        char count[16];
3842
3843        sprintf(count, "%d", radcount);
3844        nvram_set("iradius_count", count);
3845}
3846#endif
3847
3848#ifdef HAVE_MILKFISH
3849void milkfish_sip_message(webs_t wp)
3850{
3851        char *message = websGetVar(wp, "sip_message", NULL);
3852        char *dest = websGetVar(wp, "sip_message_dest", NULL);
3853        int i;
3854        FILE *fp = fopen("/tmp/sipmessage", "wb");
3855
3856        if (fp == NULL)
3857                return;
3858        char *host_key = message;
3859
3860        i = 0;
3861        do {
3862                if (host_key[i] != 0x0D)
3863                        fprintf(fp, "%c", host_key[i]);
3864        }
3865        while (host_key[++i]);
3866        putc(0xa, fp);
3867        fclose(fp);
3868        eval("milkfish_services", "simpledd", dest);
3869        return;
3870}
3871#endif
3872
3873void set_security(webs_t wp)
3874{
3875        char *var = websGetVar(wp, "security_varname", "security_mode");
3876
3877        cprintf("set security to %s\n", var);
3878        cprintf("security var = %s\n", websGetVar(wp, var, "disabled"));
3879        char *var2 = websGetVar(wp, var, "disabled");
3880
3881        // rep(var,'X','.');
3882        nvram_set(var, var2);
3883}
3884
3885void base64_encode(const unsigned char *in, size_t inlen, unsigned char *out, size_t outlen)
3886{
3887        static const char b64str[64] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
3888
3889        while (inlen && outlen) {
3890                *out++ = b64str[(in[0] >> 2) & 0x3f];
3891                if (!--outlen)
3892                        break;
3893                *out++ = b64str[((in[0] << 4) + (--inlen ? in[1] >> 4 : 0)) & 0x3f];
3894                if (!--outlen)
3895                        break;
3896                *out++ = (inlen ? b64str[((in[1] << 2) + (--inlen ? in[2] >> 6 : 0)) & 0x3f] : '=');
3897                if (!--outlen)
3898                        break;
3899                *out++ = inlen ? b64str[in[2] & 0x3f] : '=';
3900                if (!--outlen)
3901                        break;
3902                if (inlen)
3903                        inlen--;
3904                if (inlen)
3905                        in += 3;
3906        }
3907
3908        if (outlen)
3909                *out = '\0';
3910}
3911
3912char *request_freedns(char *user, char *password)
3913{
3914        unsigned char final[32];
3915        char un[128];
3916
3917        unlink("/tmp/.hash");
3918        sprintf(un, "%s|%s", user, password);
3919        sha1_ctx_t context;
3920
3921        sha1_begin(&context);
3922        sha1_hash(un, strlen(un), &context);
3923        sha1_end(final, &context);
3924        char request[128] = {
3925                0
3926        };
3927        int i;
3928
3929        for (i = 0; i < 20; i++)
3930                sprintf(request, "%s%02x", request, final[i]);
3931        unlink("/tmp/.hash");
3932        char url[128];
3933        snprintf(url, sizeof(url), "http://freedns.afraid.org/api/?action=getdyndns&sha=%s", request);
3934        eval("wget", url, "-O", "/tmp/.hash");
3935        FILE *in = fopen("/tmp/.hash", "rb");
3936
3937        if (in == NULL)
3938                return NULL;
3939        while (getc(in) != '?' && feof(in) == 0) ;
3940        i = 0;
3941        char *hash = safe_malloc(64);
3942
3943        if (feof(in)) {
3944                free(hash);
3945                fclose(in);
3946                return NULL;
3947        }
3948        for (i = 0; i < 63 && feof(in) == 0; i++) {
3949                hash[i] = getc(in);
3950                if (hash[i] == EOF)
3951                        break;
3952        }
3953        fclose(in);
3954        hash[i] = 0;
3955        return hash;
3956}
3957
3958static void getddns_userdata(int enable, char *_username, char *_passwd, char *_hostname)
3959{
3960
3961        switch (enable) {
3962        case 1:
3963                // dyndns
3964                snprintf(_username, sizeof(_username), "%s", "ddns_username");
3965                snprintf(_passwd, sizeof(_passwd), "%s", "ddns_passwd");
3966                snprintf(_hostname, sizeof(_hostname), "%s", "ddns_hostname");
3967
3968        case 2:
3969        case 3:         // zoneedit
3970        case 4:         // no-ip
3971        case 5:
3972        case 6:
3973        case 7:
3974        case 8:         // tzo
3975        case 9:         // dynSIP
3976        case 10:                // dtdns
3977        case 11:                //duiadns
3978                // 3322 dynamic : added botho 30/07/06
3979                // easydns
3980                snprintf(_username, sizeof(_username), "ddns_username_%d", enable);
3981                snprintf(_passwd, sizeof(_passwd), "ddns_passwd_%d", enable);
3982                snprintf(_hostname, sizeof(_hostname), "ddns_hostname_%d", enable);
3983
3984                break;
3985        }
3986
3987}
3988
3989void ddns_save_value(webs_t wp)
3990{
3991        char *username, *passwd, *hostname, *dyndnstype, *wildcard, *custom, *conf, *url, *wan_ip;
3992        int enable, force;
3993        char _username[] = "ddns_username_XX";
3994        char _passwd[] = "ddns_passwd_XX";
3995        char _hostname[] = "ddns_hostname_XX";
3996        char _dyndnstype[] = "ddns_dyndnstype_XX";
3997        char _wildcard[] = "ddns_wildcard_XX";
3998        char _custom[] = "ddns_custom_XX";
3999        char _conf[] = "ddns_conf";
4000        char _url[] = "ddns_url";
4001        char _force[] = "ddns_force";
4002        char _wan_ip[] = "ddns_wan_ip";
4003
4004        char *s_enable = websGetVar(wp, "ddns_enable", NULL);
4005        if (s_enable)
4006                enable = atoi(s_enable);
4007        if (!s_enable || enable > 11 || enable < 0) {
4008                return;
4009        }
4010        int gethash = 0;
4011
4012        int i;
4013        for (i = 1; i < 12; i++) {
4014                if (i == atoi(enable))
4015                        continue;
4016                getddns_userdata(i, _username, _passwd, _hostname);
4017                nvram_unset(_username);
4018                nvram_unset(_passwd);
4019                nvram_unset(_hostname);
4020        }
4021        getddns_userdata(atoi(enable), _username, _passwd, _hostname);
4022
4023        switch (enable) {
4024        case 0:
4025                // Disable
4026                nvram_set("ddns_enable", enable);
4027                return;
4028                break;
4029        case 1:
4030                // dyndns
4031
4032                snprintf(_dyndnstype, sizeof(_dyndnstype), "%s", "ddns_dyndnstype");
4033                snprintf(_wildcard, sizeof(_wildcard), "%s", "ddns_wildcard");
4034                break;
4035        case 2:
4036                // afraid
4037                gethash = 1;
4038                break;
4039        case 5:
4040                // custom
4041                snprintf(_custom, sizeof(_custom), "ddns_custom_%d", enable);
4042                snprintf(_conf, sizeof(_conf), "%s", "ddns_conf");
4043                snprintf(_url, sizeof(_url), "%s", "ddns_url");
4044                break;
4045        case 6:
4046                // 3322 dynamic : added botho 30/07/06
4047                snprintf(_dyndnstype, sizeof(_dyndnstype), "ddns_dyndnstype_%d", enable);
4048                snprintf(_wildcard, sizeof(_wildcard), "ddns_wildcard_%d", enable);
4049                break;
4050        case 7:
4051                // easydns
4052                snprintf(_wildcard, sizeof(_wildcard), "ddns_wildcard_%d", enable);
4053                break;
4054        }
4055
4056        username = websGetVar(wp, _username, NULL);
4057        passwd = websGetVar(wp, _passwd, NULL);
4058        hostname = websGetVar(wp, _hostname, NULL);
4059        dyndnstype = websGetVar(wp, _dyndnstype, NULL);
4060        wildcard = websGetVar(wp, _wildcard, NULL);
4061        custom = websGetVar(wp, _custom, NULL);
4062        conf = websGetVar(wp, _conf, NULL);
4063        url = websGetVar(wp, _url, NULL);
4064        force = atoi(websGetVar(wp, _force, "0"));
4065        wan_ip = websGetVar(wp, _wan_ip, NULL);
4066
4067        if (!username || !passwd || !hostname || !force || !wan_ip) {
4068                return;
4069        }
4070
4071        if (force < 1 || force > 60) {
4072                force = 10;
4073        }
4074
4075        nvram_seti("ddns_enable", enable);
4076        nvram_set(_username, username);
4077        if (strcmp(passwd, TMP_PASSWD)) {
4078                nvram_set(_passwd, passwd);
4079        }
4080        if (gethash && !contains(hostname, ',')) {
4081                char hostn[128];
4082                char *hash = request_freedns(username, nvram_safe_get(_passwd));
4083
4084                if (hash) {
4085                        sprintf(hostn, "%s,%s", hostname, hash);
4086                        nvram_set(_hostname, hostn);
4087                        free(hash);
4088                } else {
4089                        nvram_set(_hostname, "User/Password wrong");
4090                }
4091        } else
4092                nvram_set(_hostname, hostname);
4093        nvram_set(_dyndnstype, dyndnstype);
4094        nvram_set(_wildcard, wildcard);
4095        nvram_set(_custom, custom);
4096        nvram_set(_conf, conf);
4097        nvram_set(_url, url);
4098        nvram_seti(_force, force);
4099        nvram_set(_wan_ip, wan_ip);
4100
4101}
4102
4103void ddns_update_value(webs_t wp)
4104{
4105
4106}
4107
4108void port_vlan_table_save(webs_t wp)
4109{
4110        int port = 0, vlan = 0, vlans[22], i;
4111        char portid[32], portvlan[64], *portval, buff[32], *c, *next, br0vlans[64], br1vlans[64], br2vlans[64];
4112
4113        strcpy(portvlan, "");
4114
4115        for (vlan = 0; vlan < 22; vlan++)
4116                vlans[vlan] = 0;
4117
4118        vlans[16] = 1;
4119
4120        for (port = 0; port < 5; port++) {
4121                for (vlan = 0; vlan < 22; vlan++) {
4122                        snprintf(portid, 31, "port%dvlan%d", port, vlan);
4123                        portval = websGetVar(wp, portid, "");
4124
4125                        if (vlan < 17 || vlan > 21)
4126                                i = (strcmp(portval, "on") == 0);
4127                        else
4128                                i = (strcmp(portval, "on") != 0);
4129
4130                        if (i) {
4131                                if (strlen(portvlan) > 0)
4132                                        strcat(portvlan, " ");
4133
4134                                snprintf(buff, 4, "%d", vlan);
4135                                strcat(portvlan, buff);
4136                                vlans[vlan] = 1;
4137                        }
4138                }
4139
4140                snprintf(portid, 31, "port%dvlans", port);
4141                nvram_set(portid, portvlan);
4142                strcpy(portvlan, "");
4143        }
4144
4145        /*
4146         * done with ports 0-4, now set up #5 automaticly
4147         */
4148        /*
4149         * if a VLAN is used, it also gets assigned to port #5
4150         */
4151        for (vlan = 0; vlan < 17; vlan++) {
4152                if (vlans[vlan]) {
4153                        if (strlen(portvlan) > 0)
4154                                strcat(portvlan, " ");
4155
4156                        snprintf(buff, 4, "%d", vlan);
4157                        strcat(portvlan, buff);
4158                }
4159        }
4160
4161        nvram_set("port5vlans", portvlan);
4162
4163        strcpy(br0vlans, "");
4164        c = nvram_safe_get("lan_ifnames");
4165        if (c) {
4166                foreach(portid, c, next) {
4167                        if (!(strncmp(portid, "vlan", 4) == 0)
4168                            && !(strncmp(portid, "eth1", 4) == 0)) {
4169                                if (strlen(br0vlans) > 0)
4170                                        strcat(br0vlans, " ");
4171                                strcat(br0vlans, portid);
4172                        }
4173                }
4174        }
4175
4176        strcpy(br1vlans, "");
4177        c = nvram_safe_get("ub1_ifnames");
4178        if (c) {
4179                foreach(portid, c, next) {
4180                        if (!(strncmp(portid, "vlan", 4) == 0)
4181                            && !(strncmp(portid, "eth1", 4) == 0)) {
4182                                if (strlen(br1vlans) > 0)
4183                                        strcat(br1vlans, " ");
4184                                strcat(br1vlans, portid);
4185                        }
4186                }
4187        }
4188
4189        strcpy(br2vlans, "");
4190        c = nvram_safe_get("ub2_ifnames");
4191        if (c) {
4192                foreach(portid, c, next) {
4193                        if (!(strncmp(portid, "vlan", 4) == 0)
4194                            && !(strncmp(portid, "eth1", 4) == 0)) {
4195                                if (strlen(br2vlans) > 0)
4196                                        strcat(br2vlans, " ");
4197                                strcat(br2vlans, portid);
4198                        }
4199                }
4200        }
4201
4202        for (i = 0; i < 16; i++) {
4203                snprintf(buff, 31, "vlan%d", i);
4204                portval = websGetVar(wp, buff, "");
4205
4206                switch (atoi(portval)) {
4207                case 0:
4208                        if (strlen(br0vlans) > 0)
4209                                strcat(br0vlans, " ");
4210                        strcat(br0vlans, buff);
4211                        break;
4212                case 1:
4213                        if (strlen(br1vlans) > 0)
4214                                strcat(br1vlans, " ");
4215                        strcat(br1vlans, buff);
4216                        break;
4217                case 2:
4218                        if (strlen(br2vlans) > 0)
4219                                strcat(br2vlans, " ");
4220                        strcat(br2vlans, buff);
4221                        break;
4222                }
4223        }
4224
4225        strcpy(buff, "");
4226
4227        switch (atoi(websGetVar(wp, "wireless", ""))) {
4228        case 0:
4229                if (strlen(br0vlans) > 0)
4230                        strcat(br0vlans, " ");
4231                strcat(br0vlans, get_wdev());
4232                break;
4233        case 1:
4234                if (strlen(br1vlans) > 0)
4235                        strcat(br1vlans, " ");
4236                strcat(br1vlans, get_wdev());
4237                break;
4238        case 2:
4239                if (strlen(br2vlans) > 0)
4240                        strcat(br2vlans, " ");
4241                strcat(br2vlans, get_wdev());
4242                break;
4243        }
4244
4245        snprintf(buff, 3, "%s", websGetVar(wp, "trunking", ""));
4246
4247        nvram_set("lan_ifnames", br0vlans);
4248        // nvram_set("ub1_ifnames", br1vlans);
4249        // nvram_set("ub2_ifnames", br2vlans);
4250        nvram_set("trunking", buff);
4251        nvram_seti("vlans", 1);
4252
4253        nvram_commit();
4254
4255}
4256
4257static void save_macmode_if(webs_t wp, char *ifname)
4258{
4259
4260        char macmode[32];
4261        char macmode1[32];
4262
4263        sprintf(macmode, "%s_macmode", ifname);
4264        sprintf(macmode1, "%s_macmode1", ifname);
4265        rep(macmode1, '.', 'X');
4266        char *wl_macmode1, *wl_macmode;
4267
4268        wl_macmode = websGetVar(wp, macmode, NULL);
4269        wl_macmode1 = websGetVar(wp, macmode1, NULL);
4270
4271        if (!wl_macmode1)
4272                return;
4273
4274        if (!strcmp(wl_macmode1, "disabled")) {
4275                nvram_set(macmode1, "disabled");
4276                nvram_set(macmode, "disabled");
4277        } else if (!strcmp(wl_macmode1, "other")) {
4278                if (!wl_macmode)
4279                        nvram_set(macmode, "deny");
4280                else
4281                        nvram_set(macmode, wl_macmode);
4282                nvram_set(macmode1, "other");
4283        }
4284}
4285
4286void save_macmode(webs_t wp)
4287{
4288#ifndef HAVE_MADWIFI
4289        int c = get_wl_instances();
4290        char devs[32];
4291        int i;
4292
4293        for (i = 0; i < c; i++) {
4294                sprintf(devs, "wl%d", i);
4295                save_macmode_if(wp, devs);
4296        }
4297#else
4298        int c = getdevicecount();
4299        char devs[32];
4300        int i;
4301
4302        for (i = 0; i < c; i++) {
4303                sprintf(devs, "ath%d", i);
4304                save_macmode_if(wp, devs);
4305                char vif[32];
4306
4307                sprintf(vif, "%s_vifs", devs);
4308                char var[80], *next;
4309                char *vifs = nvram_safe_get(vif);
4310
4311                if (vifs != NULL)
4312                        foreach(var, vifs, next) {
4313                        save_macmode_if(wp, var);
4314                        }
4315        }
4316
4317#endif
4318        return;
4319
4320}
4321
4322// handle UPnP.asp requests / added 10
4323void tf_upnp(webs_t wp)
4324{
4325        char *v;
4326        char s[64];
4327
4328        if (((v = websGetVar(wp, "remove", NULL)) != NULL) && (*v)) {
4329                if (strcmp(v, "all") == 0) {
4330                        nvram_seti("upnp_clear", 1);
4331                } else {
4332                        int which = nvram_default_geti("forward_cur", 0);
4333                        int i = atoi(v);
4334                        char val[32];
4335
4336                        sprintf(val, "forward_port%d", i);
4337                        int a;
4338
4339                        nvram_unset(val);
4340                        for (a = i + 1; a < which; a++) {
4341                                nvram_nset(nvram_nget("forward_port%d", a), "forward_port%d", a - 1);
4342                        }
4343                        which--;
4344                        sprintf(val, "forward_port%d", which);
4345                        nvram_unset(val);
4346                        if (which < 0)
4347                                which = 0;
4348                        sprintf(val, "%d", which);
4349                        nvram_set("forward_cur", val);
4350                }
4351                eval("stopservice", "firewall");
4352                eval("startservice", "firewall");       //restart firewall
4353        }
4354
4355}
4356
4357#ifdef HAVE_MINIDLNA
4358#include <dlna.h>
4359static void dlna_save(webs_t wp)
4360{
4361        int c, j;
4362        char var[128], val[128];
4363        json_t *entry = NULL;
4364
4365        // dlna shares
4366        json_t *entries = json_array();
4367        int share_number = atoi(websGetVar(wp, "dlna_shares_count", "0"));
4368        for (c = 1; c <= share_number; c++) {
4369                entry = json_object();
4370                sprintf(var, "dlnashare_mp_%d", c);
4371                json_object_set_new(entry, "mp", json_string(websGetVar(wp, var, "")));
4372                sprintf(var, "dlnashare_subdir_%d", c);
4373                json_object_set_new(entry, "sd", json_string(websGetVar(wp, var, "")));
4374                int type = 0;
4375                sprintf(var, "dlnashare_audio_%d", c);
4376                if (atoi(websGetVar(wp, var, "0")))
4377                        type |= TYPE_AUDIO;
4378                sprintf(var, "dlnashare_video_%d", c);
4379                if (atoi(websGetVar(wp, var, "0")))
4380                        type |= TYPE_VIDEO;
4381                sprintf(var, "dlnashare_images_%d", c);
4382                if (atoi(websGetVar(wp, var, "0")))
4383                        type |= TYPE_IMAGES;
4384                json_object_set_new(entry, "types", json_integer(type));
4385                json_array_append(entries, entry);
4386        }
4387        nvram_set("dlna_shares", json_dumps(entries, JSON_COMPACT));
4388        json_array_clear(entries);
4389}
4390#endif
4391
4392#ifdef HAVE_NAS_SERVER
4393#include <samba3.h>
4394void nassrv_save(webs_t wp)
4395{
4396#ifdef HAVE_SAMBA_SERVER
4397        int c, j;
4398        char var[128], val[128];
4399        json_t *entry = NULL, *user_entries;
4400
4401        // samba shares
4402        json_t *entries = json_array();
4403        int share_number = atoi(websGetVar(wp, "samba_shares_count", "0"));
4404        int user_number = atoi(websGetVar(wp, "samba_users_count", "0"));
4405        for (c = 1; c <= share_number; c++) {
4406                entry = json_object();
4407                sprintf(var, "smbshare_mp_%d", c);
4408                json_object_set_new(entry, "mp", json_string(websGetVar(wp, var, "")));
4409                sprintf(var, "smbshare_subdir_%d", c);
4410                json_object_set_new(entry, "sd", json_string(websGetVar(wp, var, "")));
4411                sprintf(var, "smbshare_label_%d", c);
4412                json_object_set_new(entry, "label", json_string(websGetVar(wp, var, "")));
4413                sprintf(var, "smbshare_public_%d", c);
4414                json_object_set_new(entry, "public", json_integer(atoi(websGetVar(wp, var, "0"))));
4415                sprintf(var, "smbshare_access_perms_%d", c);
4416                sprintf(val, "%s", websGetVar(wp, var, "-"));
4417                if (!strcmp(val, "-")) {
4418                        sprintf(var, "smbshare_access_perms_prev_%d", c);
4419                        sprintf(val, "%s", websGetVar(wp, var, "x"));
4420                }
4421                json_object_set_new(entry, "perms", json_string(val));
4422                user_entries = json_array();
4423                for (j = 1; j <= user_number; j++) {
4424                        sprintf(var, "smbshare_%d_user_%d", c, j);
4425                        if (!strcmp(websGetVar(wp, var, ""), "1")) {
4426                                sprintf(var, "smbuser_username_%d", j);
4427                                json_array_append(user_entries, json_string(websGetVar(wp, var, "")));
4428                        }
4429                }
4430                json_object_set_new(entry, "users", user_entries);
4431                json_array_append(entries, entry);
4432        }
4433        //fprintf(stderr, "[SAVE NAS] %s\n", json_dumps( entries, JSON_COMPACT ) );
4434        nvram_set("samba3_shares", json_dumps(entries, JSON_COMPACT));
4435        json_array_clear(entries);
4436
4437        entries = json_array();
4438        for (c = 1; c <= user_number; c++) {
4439                entry = json_object();
4440                sprintf(var, "smbuser_username_%d", c);
4441                json_object_set_new(entry, "user", json_string(websGetVar(wp, var, "")));
4442                sprintf(var, "smbuser_password_%d", c);
4443                json_object_set_new(entry, "pass", json_string(websGetVar(wp, var, "")));
4444                int type = 0;
4445                sprintf(var, "smbuser_samba_%d", c);
4446                if (atoi(websGetVar(wp, var, "0")))
4447                        type |= SHARETYPE_SAMBA;
4448                sprintf(var, "smbuser_ftp_%d", c);
4449                if (atoi(websGetVar(wp, var, "0")))
4450                        type |= SHARETYPE_FTP;
4451                json_object_set_new(entry, "type", json_integer(type));
4452                json_array_append(entries, entry);
4453        }
4454        //fprintf(stderr, "[SAVE NAS USERS] %s\n", json_dumps( entries, JSON_COMPACT ) );
4455        nvram_set("samba3_users", json_dumps(entries, JSON_COMPACT));
4456        json_array_clear(entries);
4457#endif
4458        char *value = websGetVar(wp, "action", "");
4459
4460        // all other vars
4461        validate_cgi(wp);
4462
4463        addAction("nassrv");
4464        nvram_seti("nowebaction", 1);
4465#ifdef HAVE_MINIDLNA
4466        dlna_save(wp);
4467#endif
4468
4469        applytake(value);
4470}
4471#endif
4472
4473#ifdef HAVE_SPOTPASS
4474void nintendo_save(webs_t wp)
4475{
4476
4477        char prefix[16] = "ath0";
4478        char var[32], param[32];
4479        int device = 0;
4480
4481        int enabled = nvram_default_geti("spotpass", 0);
4482
4483        device = prefix[strlen(prefix) - 1] - '0';
4484
4485        // handle server list
4486        int count = 0;
4487        char *buffer = (char *)safe_malloc(strlen(websGetVar(wp, "spotpass_servers", "")) + 1);
4488        strcpy(buffer, websGetVar(wp, "spotpass_servers", ""));
4489
4490        char *ptr = strtok(buffer, "\n");
4491        while (ptr != NULL) {
4492                count++;
4493                ptr = strtok(NULL, "\n");
4494        }
4495        char *serverlist = (char *)safe_malloc(strlen(websGetVar(wp, "spotpass_servers", "")) + (count * 2) + 1);
4496        char line[256], url[128], proto[8], mode[16], ports[64];
4497        int port1, port2, lines = 0;
4498
4499        strcpy(buffer, websGetVar(wp, "spotpass_servers", ""));
4500        strcpy(serverlist, "\0");
4501        fprintf(stderr, "%s\n", buffer);
4502        ptr = strtok(buffer, "\n");
4503        while (ptr != NULL) {
4504                strcpy(line, "\0");
4505                if (sscanf(ptr, "%s %s %s %d %d", &url, &proto, &mode, &port1, &port2) == 5) {
4506                        sprintf(line, "%s %s %d,%d", url, proto, port1, port2);
4507                } else if (sscanf(ptr, "%s %s %d %d", &url, &proto, &port1, &port2) == 4) {
4508                        sprintf(line, "%s %s %d,%d", url, proto, port1, port2);
4509                } else if (sscanf(ptr, "%s %s %s", &url, &proto, &ports) == 3) {
4510                        sprintf(line, "%s %s %s", url, proto, ports);
4511                }
4512                lines++;
4513                if (strlen(line) > 0) {
4514                        strcat(serverlist, line);
4515                        if (lines < count) {
4516                                strcat(serverlist, "|");
4517                        }
4518                }
4519                ptr = strtok(NULL, "\n");
4520        }
4521        nvram_set("spotpass_servers", serverlist);
4522
4523        if (enabled == 0 && !strcmp(websGetVar(wp, "spotpass", "0"), "1")) {
4524
4525                // check if vap is set
4526                if (!strcmp(nvram_default_get("spotpass_vif", ""), "")) {
4527
4528                        int count = get_vifcount(prefix) + 1;
4529                        add_vifs_single(prefix, device);
4530                        sprintf(var, "%s.%d", prefix, count);
4531                        nvram_set("spotpass_vif", var);
4532
4533                        // set parameters for vap
4534                        sprintf(param, "%s_ssid", var);
4535                        nvram_set(param, "NintendoSpotPass1");
4536                        sprintf(param, "%s_bridged", var);
4537                        nvram_seti(param, 0);
4538                        sprintf(param, "%s_ipaddr", var);
4539                        nvram_set(param, "192.168.12.1");
4540                        sprintf(param, "%s_netmask", var);
4541                        nvram_set(param, "255.255.255.0");
4542                        sprintf(param, "%s_macmode", var);
4543                        nvram_set(param, "allow");
4544                        rep(param, '.', 'X');
4545                        nvram_set(param, "allow");
4546                        sprintf(param, "%s_macmode1", var);
4547                        rep(param, '.', 'X');
4548                        nvram_set(param, "other");
4549                        sprintf(param, "%s_maclist", var);
4550                        nvram_set(param, "A4:C0:E1:00:00:00/24");
4551
4552                        // dhcpd
4553                        sprintf(param, "%s>On>20>200>60", var);
4554                        nvram_set("mdhcpd", param);
4555                        nvram_seti("mdhcpd_count", 1);
4556                }
4557
4558        } else if (enabled == 1 && !strcmp(websGetVar(wp, "spotpass", "0"), "0")) {
4559
4560                if (strcmp(nvram_default_get("spotpass_vif", ""), "")) {
4561                        sprintf(var, "%s.%%d", prefix);
4562                        int index = 0;
4563                        if (sscanf(nvram_get("spotpass_vif"), var, &index) == 1) {
4564                                sprintf(var, "%s", nvram_get("spotpass_vif"));
4565                                int count = get_vifcount(prefix);
4566                                int index = var[strlen(var) - 1] - '0';
4567                                while (get_vifcount(prefix) >= index) {
4568                                        remove_vifs_single(prefix);
4569                                }
4570                                nvram_set("spotpass_vif", "");
4571
4572                                nvram_set("mdhcpd", "");
4573                                nvram_seti("mdhcpd_count", 0);
4574                        }
4575                }
4576        }
4577
4578        if (atoi(websGetVar(wp, "spotpass", "")) != enabled) {
4579                addAction("wireless");
4580                nvram_seti("nowebaction", 1);
4581        }
4582
4583        nvram_set("spotpass", websGetVar(wp, "spotpass", "0"));
4584
4585        char *value = websGetVar(wp, "action", "");
4586
4587        //addAction("spotpass_start");
4588        applytake(value);
4589}
4590#endif
Note: See TracBrowser for help on using the repository browser.