root/src/router/httpd/modules/broadcom.c

Revision 9745, 177.3 kB (checked in by eko, 1 year ago)

stupid typo in password change code

Line 
1
2 /*
3  * Broadcom Home Gateway Reference Design
4  * Web Page Configuration Support Routines
5  *
6  * Copyright 2001-2003, Broadcom Corporation
7  * All Rights Reserved.
8  *
9  * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
10  * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
11  * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
12  * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
13  * $Id: broadcom.c,v 1.9 2005/11/30 11:53:42 seg Exp $
14  */
15
16 #ifdef WEBS
17 #include <webs.h>
18 #include <uemf.h>
19 #include <ej.h>
20 #else /* !WEBS */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <unistd.h>
26 #include <limits.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <httpd.h>
33 #include <errno.h>
34 #endif /* WEBS */
35
36 #include <proto/ethernet.h>
37 #include <fcntl.h>
38 #include <signal.h>
39 #include <time.h>
40 #include <sys/klog.h>
41 #include <sys/wait.h>
42 #include <cyutils.h>
43 #include <support.h>
44 #include <cy_conf.h>
45 //#ifdef EZC_SUPPORT
46 #include <ezc.h>
47 //#endif
48 #include <broadcom.h>
49 #include <wlutils.h>
50 #include <netdb.h>
51 #include <utils.h>
52
53
54 int gozila_action = 0;
55 int error_value = 0;
56 int browser_method;
57 int debug_value = 0;
58
59
60 //static char * rfctime(const time_t *timep);
61 //static char * reltime(unsigned int seconds);
62
63 //#if defined(linux)
64
65 #include <fcntl.h>
66 #include <signal.h>
67 #include <time.h>
68 #include <sys/klog.h>
69 #include <sys/wait.h>
70 #define sys_stats(url) eval("stats", (url))
71
72
73 //tofu
74
75 #ifdef HAVE_UPNP
76 static void tf_upnp (webs_t wp);
77 static void ej_tf_upnp (webs_t wp, int argc, char_t ** argv);
78 #endif
79
80 /* Example:
81  * ISDIGIT("", 0); return true;
82  * ISDIGIT("", 1); return false;
83  * ISDIGIT("123", 1); return true;
84  */
85 int
86 ISDIGIT (char *value, int flag)
87 {
88   int i, tag = TRUE;
89
90
91   if (!strcmp (value, ""))
92     {
93       if (flag)
94         return 0;               // null
95       else
96         return 1;
97     }
98
99   for (i = 0; *(value + i); i++)
100     {
101       if (!isdigit (*(value + i)))
102         {
103           tag = FALSE;
104           break;
105         }
106     }
107   return tag;
108 }
109
110 /* Example:
111  * ISASCII("", 0); return true;
112  * ISASCII("", 1); return false;
113  * ISASCII("abc123", 1); return true;
114  */
115 int
116 ISASCII (char *value, int flag)
117 {
118   int i, tag = TRUE;
119
120 #if COUNTRY == JAPAN
121   return tag;                   // don't check for japan version
122 #endif
123
124   if (!strcmp (value, ""))
125     {
126       if (flag)
127         return 0;               // null
128       else
129         return 1;
130     }
131
132   for (i = 0; *(value + i); i++)
133     {
134       if (!isascii (*(value + i)))
135         {
136           tag = FALSE;
137           break;
138         }
139     }
140   return tag;
141 }
142
143 /* Example:
144  * legal_hwaddr("00:11:22:33:44:aB"); return true;
145  * legal_hwaddr("00:11:22:33:44:5"); return false;
146  * legal_hwaddr("00:11:22:33:44:HH"); return false;
147  */
148 int
149 legal_hwaddr (char *value)
150 {
151   unsigned int hwaddr[6];
152   int tag = TRUE;
153   int i, count;
154
155   /* Check for bad, multicast, broadcast, or null address */
156   for (i = 0, count = 0; *(value + i); i++)
157     {
158       if (*(value + i) == ':')
159         {
160           if ((i + 1) % 3 != 0)
161             {
162               tag = FALSE;
163               break;
164             }
165           count++;
166         }
167       else if (isxdigit (*(value + i))) /* one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F */
168         continue;
169       else
170         {
171           tag = FALSE;
172           break;
173         }
174     }
175
176   if (!tag || i != 17 || count != 5)    /* must have 17's characters and 5's ':' */
177     tag = FALSE;
178   else if (sscanf (value, "%x:%x:%x:%x:%x:%x",
179                    &hwaddr[0], &hwaddr[1], &hwaddr[2],
180                    &hwaddr[3], &hwaddr[4], &hwaddr[5]) != 6)
181     {
182       //(hwaddr[0] & 1) ||                // the bit 7 is 1
183       //(hwaddr[0] & hwaddr[1] & hwaddr[2] & hwaddr[3] & hwaddr[4] & hwaddr[5]) == 0xff ){ // FF:FF:FF:FF:FF:FF
184       //(hwaddr[0] | hwaddr[1] | hwaddr[2] | hwaddr[3] | hwaddr[4] | hwaddr[5]) == 0x00){ // 00:00:00:00:00:00
185       tag = FALSE;
186     }
187   else
188     tag = TRUE;
189
190
191   return tag;
192 }
193
194 /* Example:
195  * 255.255.255.0  (111111111111111111111100000000)  is a legal netmask
196  * 255.255.0.255  (111111111111110000000011111111)  is an illegal netmask
197  */
198 int
199 legal_netmask (char *value)
200 {
201   struct in_addr ipaddr;
202   int ip[4] = { 0, 0, 0, 0 };
203   int i, j;
204   int match0 = -1;
205   int match1 = -1;
206   int ret, tag;
207
208   ret = sscanf (value, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
209
210   if (ret == 4 && inet_aton (value, &ipaddr))
211     {
212       for (i = 3; i >= 0; i--)
213         {
214           for (j = 1; j <= 8; j++)
215             {
216               if ((ip[i] % 2) == 0)
217                 match0 = (3 - i) * 8 + j;
218               else if (((ip[i] % 2) == 1) && match1 == -1)
219                 match1 = (3 - i) * 8 + j;
220               ip[i] = ip[i] / 2;
221             }
222         }
223     }
224
225   if (match0 >= match1)
226     tag = FALSE;
227   else
228     tag = TRUE;
229
230
231   return tag;
232 }
233
234
235 /* Example:
236  * legal_ipaddr("192.168.1.1"); return true;
237  * legal_ipaddr("192.168.1.1111"); return false;
238  */
239 int
240 legal_ipaddr (char *value)
241 {
242   struct in_addr ipaddr;
243   int ip[4];
244   int ret, tag;
245
246   ret = sscanf (value, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
247
248   if (ret != 4 || !inet_aton (value, &ipaddr))
249     tag = FALSE;
250   else
251     tag = TRUE;
252
253
254   return tag;
255 }
256
257 /* Example:
258  * legal_ip_netmask("192.168.1.1","255.255.255.0","192.168.1.100"); return true;
259  * legal_ip_netmask("192.168.1.1","255.255.255.0","192.168.2.100"); return false;
260  */
261 int
262 legal_ip_netmask (char *sip, char *smask, char *dip)
263 {
264   struct in_addr ipaddr, netaddr, netmask;
265   int tag;
266
267   inet_aton (nvram_safe_get (sip), &netaddr);
268   inet_aton (nvram_safe_get (smask), &netmask);
269   inet_aton (dip, &ipaddr);
270
271   netaddr.s_addr &= netmask.s_addr;
272
273   if (netaddr.s_addr != (ipaddr.s_addr & netmask.s_addr))
274     tag = FALSE;
275   else
276     tag = TRUE;
277
278
279   return tag;
280 }
281
282
283 /* Example:
284  * wan_dns = 1.2.3.4 10.20.30.40 15.25.35.45
285  * get_dns_ip("wan_dns", 1, 2); produces "20"
286  */
287 int
288 get_dns_ip (char *name, int which, int count)
289 {
290   static char word[256];
291   char *next;
292   int ip;
293
294   foreach (word, nvram_safe_get (name), next)
295   {
296     if (which-- == 0)
297       {
298         ip = get_single_ip (word, count);
299         return ip;
300       }
301   }
302   return 0;
303 }
304
305
306 /* Example:
307  * wan_mac = 00:11:22:33:44:55
308  * get_single_mac("wan_mac", 1); produces "11"
309  */
310 int
311 get_single_mac (char *macaddr, int which)
312 {
313   int mac[6] = { 0, 0, 0, 0, 0, 0 };
314   int ret;
315
316   ret =
317     sscanf (macaddr, "%2X:%2X:%2X:%2X:%2X:%2X", &mac[0], &mac[1], &mac[2],
318             &mac[3], &mac[4], &mac[5]);
319   return mac[which];
320 }
321
322
323 /* Example:
324  * lan_ipaddr_0 = 192
325  * lan_ipaddr_1 = 168
326  * lan_ipaddr_2 = 1
327  * lan_ipaddr_3 = 1
328  * get_merge_ipaddr("lan_ipaddr", ipaddr); produces ipaddr="192.168.1.1"
329  */
330 int
331 get_merge_ipaddr (webs_t wp, char *name, char *ipaddr)
332 {
333   char ipname[30];
334   int i;
335   char buf[50] = { 0 };
336   char *ip[4];
337   char *tmp;
338   //cprintf("ip addr\n");
339   strcpy (ipaddr, "");
340   //cprintf("safe get\n");
341   char *ipa = nvram_safe_get (name);
342   //cprintf("strcpy\n");
343   if (ipa == NULL)
344     strcpy (buf, "0.0.0.0");
345   else
346     strcpy (buf, ipa);
347   //cprintf("strsep\n");
348   char *b = (char *) &buf;
349   ip[0] = strsep (&b, ".");
350   ip[1] = strsep (&b, ".");
351   ip[2] = strsep (&b, ".");
352   ip[3] = b;
353
354
355   for (i = 0; i < 4; i++)
356     {
357       //cprintf("merge %s_%d\n",name,i);
358       snprintf (ipname, sizeof (ipname), "%s_%d", name, i);
359       tmp = websGetVar (wp, ipname, ip[i]);
360       if (tmp == NULL)
361         return 0;
362       strcat (ipaddr, tmp);
363       if (i < 3)
364         strcat (ipaddr, ".");
365     }
366
367   return 1;
368
369 }
370
371
372 /* Example:
373  * wan_mac_0 = 00
374  * wan_mac_1 = 11
375  * wan_mac_2 = 22
376  * wan_mac_3 = 33
377  * wan_mac_4 = 44
378  * wan_mac_5 = 55
379  * get_merge_mac("wan_mac",mac); produces mac="00:11:22:33:44:55"
380  */
381 int
382 get_merge_mac (webs_t wp, char *name, char *macaddr)
383 {
384   char macname[30];
385   char *mac;
386   int i;
387
388   strcpy (macaddr, "");
389
390   for (i = 0; i < 6; i++)
391     {
392       snprintf (macname, sizeof (macname), "%s_%d", name, i);
393       mac = websGetVar (wp, macname, "00");
394       if (strlen (mac) == 1)
395         strcat (macaddr, "0");
396       strcat (macaddr, mac);
397       if (i < 5)
398         strcat (macaddr, ":");
399     }
400
401   return 1;
402
403 }
404
405 struct onload onloads[] = {
406   //{ "Filters", filter_onload },
407   {"WL_ActiveTable", wl_active_onload},
408   {"MACClone", macclone_onload},
409   {"FilterSummary", filtersummary_onload},
410   {"Ping", ping_onload},
411 //  {"Traceroute", traceroute_onload},
412 };
413
414 void
415 ej_onload (webs_t wp, int argc, char_t ** argv)
416 {
417   char *type, *arg;
418   struct onload *v;
419
420 #ifdef FASTWEB
421   ejArgs (argc, argv, "%s %s", &type, &arg);
422 #else
423   if (ejArgs (argc, argv, "%s %s", &type, &arg) < 2)
424     {
425       websError (wp, 400, "Insufficient args\n");
426       return;
427     }
428 #endif
429   for (v = onloads; v < &onloads[STRUCT_LEN (onloads)]; v++)
430     {
431       if (!strcmp (v->name, type))
432         {
433           v->go (wp, arg);
434           return;
435         }
436     }
437
438   return;
439 }
440
441 /* Meta tag command that will no allow page cached by browsers.
442  * The will force the page to be refreshed when visited.
443  */
444 void
445 ej_no_cache (webs_t wp, int argc, char_t ** argv)
446 {
447   websWrite (wp, "<meta http-equiv=\"expires\" content=\"0\">\n");
448   websWrite (wp,
449              "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n");
450   websWrite (wp, "<meta http-equiv=\"pragma\" content=\"no-cache\">\n");
451
452   return;
453 }
454
455
456 /*
457  * Example:
458  * lan_ipaddr=192.168.1.1
459  * <% prefix_ip_get("lan_ipaddr",1); %> produces "192.168.1."
460  */
461 void
462 ej_prefix_ip_get (webs_t wp, int argc, char_t ** argv)
463 {
464   char *name;
465   int type;
466
467 #ifdef FASTWEB
468   ejArgs (argc, argv, "%s %d", &name, &type);
469 #else
470   if (ejArgs (argc, argv, "%s %d", &name, &type) < 2)
471     {
472       websError (wp, 400, "Insufficient args\n");
473       return;
474     }
475 #endif
476
477   if (type == 1)
478     websWrite (wp, "%d.%d.%d.", get_single_ip (nvram_safe_get (name), 0),
479                get_single_ip (nvram_safe_get (name), 1),
480                get_single_ip (nvram_safe_get (name), 2));
481   if (type == 2)
482     websWrite (wp, "%d.%d.", get_single_ip (nvram_safe_get (name), 0),
483                get_single_ip (nvram_safe_get (name), 1));
484
485   return;
486 }
487
488 void
489 prefix_ip_get (char *name, char *buf, int type)
490 {
491   if (type == 1)
492     sprintf (buf, "%d.%d.%d.", get_single_ip (nvram_safe_get (name), 0),
493              get_single_ip (nvram_safe_get (name), 1),
494              get_single_ip (nvram_safe_get (name), 2));
495   if (type == 2)
496     sprintf (buf, "%d.%d.", get_single_ip (nvram_safe_get (name), 0),
497              get_single_ip (nvram_safe_get (name), 1));
498 }
499
500 /* Deal with side effects before committing */
501 int
502 sys_commit (void)
503 {
504   if (nvram_match ("dhcpnvram", "1"))
505     {
506       killall ("dnsmasq", SIGUSR2);     // update lease -- tofu
507       sleep (1);
508     }
509
510   //if (nvram_match("wan_proto", "pppoe") || nvram_match("wan_proto", "pptp") )
511   //      nvram_set("wan_ifname", "ppp0");
512   //else
513   //      nvram_set("wan_ifname", nvram_get("pppoe_ifname"));
514   return nvram_commit ();
515 }
516
517
518 char *
519 rfctime (const time_t * timep, char *s)
520 {
521   struct tm tm;
522   setenv ("TZ", nvram_safe_get ("time_zone"), 1);
523   memcpy (&tm, localtime (timep), sizeof (struct tm));
524   strftime (s, 200, "%a, %d %b %Y %H:%M:%S", &tm);      // spec for linksys
525   return s;
526 }
527
528
529 /*
530  * Example:
531  * lan_ipaddr = 192.168.1.1
532  * <% nvram_get("lan_ipaddr"); %> produces "192.168.1.1"
533  */
534 static void
535 ej_nvram_get (webs_t wp, int argc, char_t ** argv)
536 {
537   char *name;
538
539 #ifdef FASTWEB
540   ejArgs (argc, argv, "%s", &name);
541 #else
542   if (ejArgs (argc, argv, "%s", &name) < 1)
543     {
544       websError (wp, 400, "Insufficient args\n");
545       return;
546     }
547 #endif
548
549 #if COUNTRY == JAPAN
550   websWrite (wp, "%s", nvram_safe_get (name));
551 #else
552   /*for (c = nvram_safe_get (name); *c; c++)
553      {
554      if (isprint ((int) *c))    // &&
555      //                  *c != '"' && *c != '&' && *c != '<' && *c != '>')
556      ret += websWrite (wp, "%c", *c);
557      else
558      {
559      if (*c == '"')
560      ret += websWrite (wp, "&quot;");
561      else if (*c == '&')
562      ret += websWrite (wp, "&amp;");
563      else if (*c == '<')
564      ret += websWrite (wp, "&lt;");
565      else if (*c == '>')
566      ret += websWrite (wp, "&gt;");
567      else if (*c == 13)
568      continue;
569      else
570      ret += websWrite (wp, "&#%d", *c);
571      }
572      } */
573
574   tf_webWriteESCNV (wp, name);  // test: buffered version of above
575
576   return;
577 #endif
578
579   return;
580 }
581
582 static void
583 ej_nvram_real_get (webs_t wp, int argc, char_t ** argv)
584 {
585   char *name;
586
587 #ifdef FASTWEB
588   ejArgs (argc, argv, "%s", &name);
589 #else
590   if (ejArgs (argc, argv, "%s", &name) < 1)
591     {
592       websError (wp, 400, "Insufficient args\n");
593       return;
594     }
595 #endif
596
597   websWrite (wp, "%s", nvram_safe_get (name));
598
599   return;
600 }
601
602 /*
603  * Example:
604  * lan_ipaddr = 192.168.1.1, gozila_action = 0
605  * <% nvram_selget("lan_ipaddr"); %> produces "192.168.1.1"
606  * lan_ipaddr = 192.168.1.1, gozila_action = 1, websGetVar(wp, "lan_proto", NULL) = 192.168.1.2;
607  * <% nvram_selget("lan_ipaddr"); %> produces "192.168.1.2"
608  */
609 static void
610 ej_nvram_selget (webs_t wp, int argc, char_t ** argv)
611 {
612   char *name;
613
614 #ifdef FASTWEB
615   ejArgs (argc, argv, "%s", &name);
616 #else
617   if (ejArgs (argc, argv, "%s", &name) < 1)
618     {
619       websError (wp, 400, "Insufficient args\n");
620       return;
621     }
622 #endif
623   if (gozila_action)
624     {
625       char *buf = websGetVar (wp, name, NULL);
626       if (buf)
627         {
628           websWrite (wp, "%s", buf);
629           return;
630         }
631     }
632
633 /*  for (c = nvram_safe_get (name); *c; c++)
634     {
635       if (isprint ((int) *c) &&
636           *c != '"' && *c != '&' && *c != '<' && *c != '>')
637         ret += websWrite (wp, "%c", *c);
638       else
639         ret += websWrite (wp, "&#%d", *c);
640     }*/
641   tf_webWriteESCNV (wp, name);  // test: buffered version of above
642
643   return;
644 }
645
646 /*
647  * Example:
648  * wan_mac = 00:11:22:33:44:55
649  * <% nvram_mac_get("wan_mac"); %> produces "00-11-22-33-44-55"
650  */
651 static void
652 ej_nvram_mac_get (webs_t wp, int argc, char_t ** argv)
653 {
654   char *name, *c;
655   char *mac;
656   int i;
657
658 #ifdef FASTWEB
659   ejArgs (argc, argv, "%s", &name);
660 #else
661   if (ejArgs (argc, argv, "%s", &name) < 1)
662     {
663       websError (wp, 400, "Insufficient args\n");
664       return;
665     }
666 #endif
667   c = nvram_safe_get (name);
668
669   if (c)
670     {
671       mac = strdup (c);
672       for (i = 0; *(mac + i); i++)
673         {
674           if (*(mac + i) == ':')
675             *(mac + i) = '-';
676         }
677       websWrite (wp, "%s", mac);
678       free (mac);               // leak, thx tofu
679     }
680
681   return;
682
683 }
684
685 /*
686  * Example:
687  * wan_proto = dhcp; gozilla = 0;
688  * <% nvram_gozila_get("wan_proto"); %> produces "dhcp"
689  *
690  * wan_proto = dhcp; gozilla = 1; websGetVar(wp, "wan_proto", NULL) = static;
691  * <% nvram_gozila_get("wan_proto"); %> produces "static"
692  */
693 static void
694 ej_nvram_gozila_get (webs_t wp, int argc, char_t ** argv)
695 {
696   char *name, *type;
697
698 #ifdef FASTWEB
699   ejArgs (argc, argv, "%s", &name);
700 #else
701   if (ejArgs (argc, argv, "%s", &name) < 1)
702     {
703       websError (wp, 400, "Insufficient args\n");
704       return;
705     }
706 #endif
707   type = GOZILA_GET (name);
708
709   websWrite (wp, "%s", type);
710 }
711
712 static void
713 ej_webs_get (webs_t wp, int argc, char_t ** argv)
714 {
715   char *name, *value;
716
717 #ifdef FASTWEB
718   ejArgs (argc, argv, "%s", &name);
719 #else
720   if (ejArgs (argc, argv, "%s", &name) < 1)
721     {
722       websError (wp, 400, "Insufficient args\n");
723       return;
724     }
725 #endif
726
727   value = websGetVar (wp, name, NULL);
728
729   if (value)
730     websWrite (wp, "%s", value);
731
732   return;
733 }
734
735 /*
736  * Example:
737  * lan_ipaddr = 192.168.1.1
738  * <% get_single_ip("lan_ipaddr","1"); %> produces "168"
739  */
740 static void
741 ej_get_single_ip (webs_t wp, int argc, char_t ** argv)
742 {
743   char *name, *c;
744   int which;
745
746 #ifdef FASTWEB
747   ejArgs (argc, argv, "%s %d", &name, &which);
748 #else
749   if (ejArgs (argc, argv, "%s %d", &name, &which) < 1)
750     {
751       websError (wp, 400, "Insufficient args\n");
752       return;
753     }
754 #endif
755
756   c = nvram_safe_get (name);
757   if (c)
758     {
759       if (!strcmp (c, PPP_PSEUDO_IP) || !strcmp (c, PPP_PSEUDO_GW))
760         c = "0.0.0.0";
761       else if (!strcmp (c, PPP_PSEUDO_NM))
762         c = "255.255.255.0";
763
764       websWrite (wp, "%d", get_single_ip (c, which));
765     }
766   else
767     websWrite (wp, "0");
768
769   return;
770 }
771
772 /*
773  * Example:
774  * wan_mac = 00:11:22:33:44:55
775  * <% get_single_mac("wan_mac","1"); %> produces "11"
776  */
777 static void
778 ej_get_single_mac (webs_t wp, int argc, char_t ** argv)
779 {
780   char *name, *c;
781   int which;
782   int mac;
783
784 #ifdef FASTWEB
785   ejArgs (argc, argv, "%s %d", &name, &which);
786 #else
787   if (ejArgs (argc, argv, "%s %d", &name, &which) < 1)
788     {
789       websError (wp, 400, "Insufficient args\n");
790       return;
791     }
792 #endif
793
794   c = nvram_safe_get (name);
795   if (c)
796     {
797       mac = get_single_mac (c, which);
798       websWrite (wp, "%02X", mac);
799     }
800   else
801     websWrite (wp, "00");
802
803   return;
804 }
805
806 /*
807  * Example:
808  * wan_proto = dhcp; gozilla = 0;
809  * <% nvram_selmatch("wan_proto", "dhcp", "selected"); %> produces "selected"
810  *
811  * wan_proto = dhcp; gozilla = 1; websGetVar(wp, "wan_proto", NULL) = static;
812  * <% nvram_selmatch("wan_proto", "static", "selected"); %> produces "selected"
813  */
814
815 int
816 nvram_selmatch (webs_t wp, char *name, char *match)
817 {
818   char *type = GOZILA_GET (name);
819   if (!type)
820     {
821       if (nvram_match (name, match))
822         {
823           return 1;
824         }
825     }
826   else
827     {
828       if (!strcmp (type, match))
829         {
830           return 1;
831         }
832     }
833   return 0;
834 }
835
836 void
837 ej_nvram_selmatch (webs_t wp, int argc, char_t ** argv)
838 {
839   char *name, *match, *output;
840
841 #ifdef FASTWEB
842   ejArgs (argc, argv, "%s %s %s", &name, &match, &output);
843 #else
844   if (ejArgs (argc, argv, "%s %s %s", &name, &match, &output) < 3)
845     {
846       websError (wp, 400, "Insufficient args\n");
847       return;
848     }
849 #endif
850
851   if (nvram_selmatch (wp, name, match))
852     {
853       websWrite (wp, output);
854     }
855   return;
856 }
857
858 void
859 ej_nvram_else_selmatch (webs_t wp, int argc, char_t ** argv)
860 {
861   char *name, *match, *output1, *output2;
862   char *type;
863
864 #ifdef FASTWEB
865   ejArgs (argc, argv, "%s %s %s %s", &name, &match, &output1, &output2);
866 #else
867   if (ejArgs (argc, argv, "%s %s %s %s", &name, &match, &output1, &output2) <
868       4)
869     {
870       websError (wp, 400, "Insufficient args\n");
871       return;
872     }
873 #endif
874
875   type = GOZILA_GET (name);
876
877   if (!type)
878     {
879       if (nvram_match (name, match))
880         {
881           websWrite (wp, output1);
882         }
883       else
884         websWrite (wp, output2);
885     }
886   else
887     {
888       if (!strcmp (type, match))
889         {
890           websWrite (wp, output1);
891         }
892       else
893         websWrite (wp, output2);
894     }
895
896   return;
897 }
898
899 /*
900  * Example:
901  * wan_proto=dhcp
902  * <% nvram_else_match("wan_proto", "dhcp", "0","1"); %> produces "0"
903  * <% nvram_else_match("wan_proto", "static", "0","1"); %> produces "1"
904  */
905 static void
906 ej_nvram_else_match (webs_t wp, int argc, char_t ** argv)
907 {
908   char *name, *match, *output1, *output2;
909
910 #ifdef FASTWEB
911   ejArgs (argc, argv, "%s %s %s %s", &name, &match, &output1, &output2);
912 #else
913   if (ejArgs (argc, argv, "%s %s %s %s", &name, &match, &output1, &output2) <
914       4)
915     {
916       websError (wp, 400, "Insufficient args\n");
917       return;
918     }
919 #endif
920
921   if (nvram_match (name, match))
922     websWrite (wp, output1);
923   else
924     websWrite (wp, output2);
925
926   return;
927 }
928
929
930
931 static void
932 ej_startswith (webs_t wp, int argc, char_t ** argv)
933 {
934   char *name, *match, *output;
935
936 #ifdef FASTWEB
937   ejArgs (argc, argv, "%s %s %s", &name, &match, &output);
938 #else
939   if (ejArgs (argc, argv, "%s %s %s", &name, &match, &output) < 3)
940     {
941       websError (wp, 400, "Insufficient args\n");
942       return;
943     }
944 #endif
945   if (startswith (nvram_safe_get (name), match))
946     websWrite (wp, output);
947
948   return;
949 }
950
951 static void
952 ej_ifdef (webs_t wp, int argc, char_t ** argv)
953 {
954   char *name, *output;
955
956 #ifdef FASTWEB
957   ejArgs (argc, argv, "%s %s", &name, &output);
958 #else
959   if (ejArgs (argc, argv, "%s %s", &name, &output) < 2)
960     {
961       websError (wp, 400, "Insufficient args\n");
962       return;
963     }
964 #endif
965
966 #ifdef HAVE_MICRO
967   if (!strcmp (name, "MICRO"))
968     {
969       websWrite (wp, output);
970       return;
971     }
972 #endif
973   if (!strcmp (name, "MINI"))   //to include mini + mini-special
974     {
975       if (startswith (nvram_safe_get ("dist_type"), "mini"))
976         {
977           websWrite (wp, output);
978           return;
979         }
980     }
981   if (!strcmp (name, "VPN"))    //to include vpn + vpn-special
982     {
983       if (startswith (nvram_safe_get ("dist_type"), "vpn"))
984         {
985           websWrite (wp, output);
986           return;
987         }
988     }
989 #ifdef HAVE_MULTICAST
990   if (!strcmp (name, "MULTICAST"))
991     {
992       websWrite (wp, output);
993       return;
994     }
995 #endif
996 #ifdef HAVE_WIVIZ
997   if (!strcmp (name, "WIVIZ"))
998     {
999       websWrite (wp, output);
1000       return;
1001     }
1002 #endif
1003 #ifdef HAVE_RSTATS
1004   if (!strcmp (name, "RSTATS"))
1005     {
1006       websWrite (wp, output);
1007       return;
1008     }
1009 #endif
1010 #ifdef HAVE_ACK
1011   if (!strcmp (name, "ACK"))
1012     {
1013       websWrite (wp, output);
1014       return;
1015     }
1016 #endif
1017 #ifdef HAVE_SSHD
1018   if (!strcmp (name, "SSHD"))
1019     {
1020       websWrite (wp, output);
1021       return;
1022     }
1023 #endif
1024
1025   return;
1026 }
1027
1028 static void
1029 ej_ifndef (webs_t wp, int argc, char_t ** argv)
1030 {
1031   char *name, *output;
1032
1033 #ifdef FASTWEB
1034   ejArgs (argc, argv, "%s %s", &name, &output);
1035 #else
1036   if (ejArgs (argc, argv, "%s %s", &name, &output) < 2)
1037     {
1038       websError (wp, 400, "Insufficient args\n");
1039       return;
1040     }
1041 #endif
1042
1043 #ifdef HAVE_MICRO
1044   if (!strcmp (name, "MICRO"))
1045     return;
1046 #endif
1047 #ifdef HAVE_MULTICAST
1048   if (!strcmp (name, "MULTICAST"))
1049     return;
1050 #endif
1051 #ifdef HAVE_WIVIZ
1052   if (!strcmp (name, "WIVIZ"))
1053     return;
1054 #endif
1055 #ifdef HAVE_RSTATS
1056   if (!strcmp (name, "RSTATS"))
1057     return;
1058 #endif
1059 #ifdef HAVE_ACK
1060   if (!strcmp (name, "ACK"))
1061     return;
1062 #endif
1063 #ifdef HAVE_SAMBA
1064   if (!strcmp (name, "SAMBA"))
1065     return;
1066 #endif
1067 #ifdef HAVE_JFFS2
1068   if (!strcmp (name, "JFFS2"))
1069     return;
1070 #endif
1071 #ifdef HAVE_GPSI
1072   if (!strcmp (name, "GPSI"))
1073     return;
1074 #endif
1075 #ifdef HAVE_MMC
1076   if (!strcmp (name, "MMC"))
1077     return;
1078 #endif
1079 #ifdef HAVE_SPUTNIK_APD
1080   if (!strcmp (name, "SPUTNIK_APD"))
1081     return;
1082 #endif
1083 #ifdef HAVE_RFLOW
1084   if (!strcmp (name, "RFLOW"))
1085     return;
1086 #endif
1087 #ifdef HAVE_USB
1088   if (!strcmp (name, "USB"))
1089     return;
1090 #endif
1091 #ifdef HAVE_SSHD
1092   if (!strcmp (name, "SSHD"))
1093     return;
1094 #endif
1095 #ifdef HAVE_PPPOESERVER
1096   if (!strcmp (name, "PPPOESERVER"))
1097     return;
1098 #endif
1099 #ifdef HAVE_MILKFISH
1100   if (!strcmp (name, "MILKFISH"))
1101     return;
1102 #endif
1103 // HAVE_AFTERBURNER
1104   if (!strcmp (name, "AFTERBURNER"))
1105     {
1106 #ifdef HAVE_MADWIFI
1107       return;
1108 #else
1109       int afterburner = 0;
1110       char cap[WLC_IOCTL_SMLEN];
1111       char caps[WLC_IOCTL_SMLEN];
1112       char *name = nvram_safe_get ("wl0_ifname");
1113       char *next;
1114
1115       if (wl_iovar_get (name, "cap", (void *) caps, WLC_IOCTL_SMLEN) == 0)
1116         {
1117           foreach (cap, caps, next)
1118           {
1119             if (!strcmp (cap, "afterburner"))
1120               afterburner = 1;
1121           }
1122
1123           if (afterburner)
1124             return;
1125         }
1126 #endif
1127     }
1128 // end HAVE_AFTERBURNER
1129 // HAVE_HASWIFI
1130   if (!strcmp (name, "HASWIFI"))
1131     {
1132       if (haswifi ())
1133         return;
1134     }
1135 // end HAVE_HASWIFI
1136
1137   websWrite (wp, output);
1138
1139   return;
1140 }
1141
1142 /*
1143  * Example:
1144  * wan_proto=dhcp
1145  * <% nvram_match("wan_proto", "dhcp", "selected"); %> produces "selected"
1146  * <% nvram_match("wan_proto", "static", "selected"); %> does not produce
1147  */
1148 static void
1149 ej_nvram_match (webs_t wp, int argc, char_t ** argv)
1150 {
1151   char *name, *match, *output;
1152
1153 #ifdef FASTWEB
1154   ejArgs (argc, argv, "%s %s %s", &name, &match, &output);
1155 #else
1156   if (ejArgs (argc, argv, "%s %s %s", &name, &match, &output) < 3)
1157     {
1158       websError (wp, 400, "Insufficient args\n");
1159       return;
1160     }
1161 #endif
1162
1163   if (nvram_match (name, match))
1164     websWrite (wp, output);
1165
1166   return;
1167 }
1168
1169
1170 /*
1171  * Example:
1172  * wan_proto=dhcp
1173  * <% nvram_invmatch("wan_proto", "dhcp", "disabled"); %> does not produce
1174  * <% nvram_invmatch("wan_proto", "static", "disabled"); %> produces "disabled"
1175  */
1176 static void
1177 ej_nvram_invmatch (webs_t wp, int argc, char_t ** argv)
1178 {
1179   char *name, *invmatch, *output;
1180
1181 #ifdef FASTWEB
1182   ejArgs (argc, argv, "%s %s %s", &name, &invmatch, &output);
1183 #else
1184   if (ejArgs (argc, argv, "%s %s %s", &name, &invmatch, &output) < 3)
1185     {
1186       websError (wp, 400, "Insufficient args\n");
1187       return;
1188     }
1189 #endif
1190
1191   if (!nvram_match (name, invmatch))
1192     websWrite (wp, output);
1193
1194   return;
1195 }
1196
1197 /*
1198 static void
1199 ej_scroll (webs_t wp, int argc, char_t ** argv)
1200 {
1201   char *type;
1202   int y;
1203
1204 #ifdef FASTWEB
1205   ejArgs (argc, argv, "%s %d", &type, &y);
1206 #else
1207   if (ejArgs (argc, argv, "%s %d", &type, &y) < 2)
1208     {
1209       websError (wp, 400, "Insufficient args\n");
1210       return;
1211     }
1212 #endif
1213   if (gozila_action)
1214     websWrite (wp, "%d", y);
1215   else
1216     websWrite (wp, "0");
1217
1218   return;
1219 }
1220 */
1221 /*
1222  * Example:
1223  * filter_mac=00:12:34:56:78:00 00:87:65:43:21:00
1224  * <% nvram_list("filter_mac", 1); %> produces "00:87:65:43:21:00"
1225  * <% nvram_list("filter_mac", 100); %> produces ""
1226  */
1227 static void
1228 ej_nvram_list (webs_t wp, int argc, char_t ** argv)
1229 {
1230   char *name;
1231   int which;
1232   char word[256], *next;
1233
1234 #ifdef FASTWEB
1235   ejArgs (argc, argv, "%s %d", &name, &which);
1236 #else
1237   if (ejArgs (argc, argv, "%s %d", &name, &which) < 2)
1238     {
1239       websError (wp, 400, "Insufficient args\n");
1240       return;
1241     }
1242 #endif
1243
1244   foreach (word, nvram_safe_get (name), next)
1245   {
1246     if (which-- == 0)
1247       websWrite (wp, word);
1248   }
1249
1250   return;
1251 }
1252
1253 /* Example:
1254  * wan_dns = 168.95.1.1 210.66.161.125 168.95.192.1
1255  * <% get_dns_ip("wan_dns", "1", "2"); %> produces "161"
1256  * <% get_dns_ip("wan_dns", "2", "3"); %> produces "1"
1257  */
1258 void
1259 ej_get_dns_ip (webs_t wp, int argc, char_t ** argv)
1260 {
1261   char *name;
1262   int count, which;
1263   char word[256], *next;
1264
1265 #ifdef FASTWEB
1266   ejArgs (argc, argv, "%s %d %d", &name, &which, &count);
1267 #else
1268   if (ejArgs (argc, argv, "%s %d %d", &name, &which, &count) < 3)
1269     {
1270       websError (wp, 400, "Insufficient args\n");
1271       return;
1272     }
1273 #endif
1274
1275   foreach (word, nvram_safe_get (name), next)
1276   {
1277     if (which-- == 0)
1278       {
1279         websWrite (wp, "%d", get_single_ip (word, count));
1280         return;
1281       }
1282   }
1283
1284   websWrite (wp, "0");          // not find
1285 }
1286
1287 int
1288 valid_wep_key (webs_t wp, char *value, struct variable *v)
1289 {
1290   int i;
1291
1292   switch (strlen (value))
1293     {
1294     case 5:
1295     case 13:
1296       for (i = 0; *(value + i); i++)
1297         {
1298           if (isascii (*(value + i)))
1299             {
1300               continue;
1301             }
1302           else
1303             {
1304               websDebugWrite (wp,
1305                               "Invalid <b>%s</b> %s: must be ascii code<br>",
1306                               v->longname, value);
1307               return FALSE;
1308             }
1309         }
1310       break;
1311     case 10:
1312     case 26:
1313       for (i = 0; *(value + i); i++)
1314         {
1315           if (isxdigit (*(value + i)))
1316             {                   /* one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F */
1317               continue;
1318             }
1319           else
1320             {
1321               websDebugWrite (wp,
1322                               "Invalid <b>%s</b> %s: must be hexadecimal digits<br>",
1323                               v->longname, value);
1324               return FALSE;
1325             }
1326         }
1327       break;
1328
1329     default:
1330       websDebugWrite (wp,
1331                       "Invalid <b>%s</b>: must be 5 or 13 ASCII characters or 10 or 26 hexadecimal digits<br>",
1332                       v->longname);
1333       return FALSE;
1334
1335     }
1336
1337 /*
1338         for(i=0 ; *(value+i) ; i++){
1339                 if(isxdigit(*(value+i))){
1340                         continue;
1341                 }
1342                 else{
1343                         websDebugWrite(wp, "Invalid <b>%s</b> %s: must be hexadecimal digits<br>",
1344                                   v->longname, value);
1345                         return FALSE;
1346                 }
1347         }
1348
1349         if (i != length) {
1350                 websDebugWrite(wp, "Invalid <b>%s</b> %s: must be %d characters<br>",
1351                           v->longname, value,length);
1352                 return FALSE;
1353         }
1354 */
1355   return TRUE;
1356 }
1357
1358 void
1359 validate_statics (webs_t wp, char *value, struct variable *v)
1360 {
1361
1362   if (!sv_valid_statics (value))
1363     {
1364       websDebugWrite (wp,
1365                       "Invalid <b>%s</b> %s: not a legal statics entry<br>",
1366                       v->longname, value);
1367       return;
1368     }
1369
1370   nvram_set (v->name, value);
1371 }
1372
1373 int
1374 valid_netmask (webs_t wp, char *value, struct variable *v)
1375 {
1376
1377   if (!legal_netmask (value))
1378     {
1379       websDebugWrite (wp, "Invalid <b>%s</b> %s: not a legal netmask<br>",
1380                       v->longname, value);
1381       return FALSE;
1382     }
1383
1384   return TRUE;
1385
1386 }
1387
1388 static void
1389 validate_netmask (webs_t wp, char *value, struct variable *v)
1390 {
1391   if (valid_netmask (wp, value, v))
1392     nvram_set (v->name, value);
1393 }
1394
1395 static void
1396 validate_merge_netmask (webs_t wp, char *value, struct variable *v)
1397 {
1398   char netmask[20], maskname[30];
1399   char *mask;
1400   int i;
1401   strcpy (netmask, "");
1402   for (i = 0; i < 4; i++)
1403     {
1404       snprintf (maskname, sizeof (maskname), "%s_%d", v->name, i);
1405       mask = websGetVar (wp, maskname, NULL);
1406       if (mask)
1407         {
1408           strcat (netmask, mask);
1409           if (i < 3)
1410             strcat (netmask, ".");
1411         }
1412       else
1413         {
1414           return;
1415         }
1416     }
1417
1418
1419   if (valid_netmask (wp, netmask, v))
1420     nvram_set (v->name, netmask);
1421 }
1422
1423 //Added by Daniel(2004-07-29) for EZC
1424 //char webs_buf[5000];
1425 //int webs_buf_offset = 0;
1426
1427 static void
1428 validate_list (webs_t wp, char *value, struct variable *v,
1429                int (*valid) (webs_t, char *, struct variable *))
1430 {
1431   int n, i;
1432   char name[100];
1433   char buf[1000] = "", *cur = buf;
1434
1435   n = atoi (value);
1436
1437   for (i = 0; i < n; i++)
1438     {
1439       snprintf (name, sizeof (name), "%s%d", v->name, i);
1440       if (!(value = websGetVar (wp, name, NULL)))
1441         return;
1442       if (!*value && v->nullok)
1443         continue;
1444       if (!valid (wp, value, v))
1445         continue;
1446       cur += snprintf (cur, buf + sizeof (buf) - cur, "%s%s",
1447                        cur == buf ? "" : " ", value);
1448     }
1449   nvram_set (v->name, buf);
1450
1451 }
1452
1453 int
1454 valid_ipaddr (webs_t wp, char *value, struct variable *v)
1455 {
1456   struct in_addr netaddr, netmask;
1457
1458   if (!legal_ipaddr (value))
1459     {
1460       websDebugWrite (wp, "Invalid <b>%s</b> %s: not an IP address<br>",
1461                       v->longname, value);
1462       return FALSE;
1463     }
1464
1465   if (v->argv)
1466     {
1467       if (!strcmp (v->argv[0], "lan"))
1468         {
1469           if (*(value + strlen (value) - 2) == '.'
1470               && *(value + strlen (value) - 1) == '0')
1471             {
1472               websDebugWrite (wp,
1473                               "Invalid <b>%s</b> %s: not an IP address<br>",
1474                               v->longname, value);
1475               return FALSE;
1476             }
1477         }
1478
1479       else if (!legal_ip_netmask (v->argv[0], v->argv[1], value))
1480         {
1481           (void) inet_aton (nvram_safe_get (v->argv[0]), &netaddr);
1482           (void) inet_aton (nvram_safe_get (v->argv[1]), &netmask);
1483           websDebugWrite (wp, "Invalid <b>%s</b> %s: not in the %s/",
1484                           v->longname, value, inet_ntoa (netaddr));
1485           websDebugWrite (wp, "%s network<br>", inet_ntoa (netmask));
1486           return FALSE;
1487         }
1488     }
1489
1490   return TRUE;
1491 }
1492
1493 static void
1494 validate_ipaddr (webs_t wp, char *value, struct variable *v)
1495 {
1496   if (valid_ipaddr (wp, value, v))
1497     nvram_set (v->name, value);
1498 }
1499
1500 static void
1501 validate_ipaddrs (webs_t wp, char *value, struct variable *v)
1502 {
1503   validate_list (wp, value, v, valid_ipaddr);
1504 }
1505
1506 int
1507 valid_merge_ip_4 (webs_t wp, char *value, struct variable *v)
1508 {
1509   char ipaddr[20];
1510
1511   if (atoi (value) == 255)
1512     {
1513       websDebugWrite (wp, "Invalid <b>%s</b> %s: out of range 0 - 254 <br>",
1514                       v->longname, value);
1515       return FALSE;
1516     }
1517
1518   sprintf (ipaddr, "%d.%d.%d.%s",
1519            get_single_ip (nvram_safe_get ("lan_ipaddr"), 0),
1520            get_single_ip (nvram_safe_get ("lan_ipaddr"), 1),
1521            get_single_ip (nvram_safe_get ("lan_ipaddr"), 2), value);
1522
1523   if (!valid_ipaddr (wp, ipaddr, v))
1524     {
1525       return FALSE;
1526     }
1527
1528
1529   return TRUE;
1530 }
1531
1532 /*static void
1533 validate_merge_ip_4 (webs_t wp, char *value, struct variable *v)
1534 {
1535   if (!strcmp (value, ""))
1536     {
1537       nvram_set (v->name, "0");
1538       return;
1539     }
1540
1541   if (valid_merge_ip_4 (wp, value, v))
1542     nvram_set (v->name, value);
1543 }
1544 */
1545 static void
1546 validate_merge_ipaddrs (webs_t wp, char *value, struct variable *v)
1547 {
1548   char ipaddr[20];
1549
1550   get_merge_ipaddr (wp, v->name, ipaddr);
1551
1552   if (valid_ipaddr (wp, ipaddr, v))
1553     nvram_set (v->name, ipaddr);
1554 }
1555
1556 static void
1557 validate_merge_mac (webs_t wp, char *value, struct variable *v)
1558 {
1559   char macaddr[20];
1560
1561   get_merge_mac (wp, v->name, macaddr);
1562
1563   if (valid_hwaddr (wp, macaddr, v))
1564     nvram_set (v->name, macaddr);
1565
1566 }
1567
1568 static void
1569 validate_dns (webs_t wp, char *value, struct variable *v)
1570 {
1571   char buf[100] = "", *cur = buf;
1572   char ipaddr[20], ipname[30];
1573   char *ip;
1574   int i, j;
1575
1576   for (j = 0; j < 3; j++)
1577     {
1578       strcpy (ipaddr, "");
1579       for (i = 0; i < 4; i++)
1580         {
1581           snprintf (ipname, sizeof (ipname), "%s%d_%d", v->name, j, i);
1582           ip = websGetVar (wp, ipname, NULL);
1583           if (ip)
1584             {
1585               strcat (ipaddr, ip);
1586               if (i < 3)
1587                 strcat (ipaddr, ".");
1588             }
1589           else
1590             return;
1591         }
1592
1593       if (!strcmp (ipaddr, "0.0.0.0"))
1594         continue;
1595       if (!valid_ipaddr (wp, ipaddr, v))
1596         continue;
1597       cur += snprintf (cur, buf + sizeof (buf) - cur, "%s%s",
1598                        cur == buf ? "" : " ", ipaddr);
1599     }
1600   nvram_set (v->name, buf);
1601
1602   dns_to_resolv ();
1603 }
1604
1605 int
1606 valid_choice (webs_t wp, char *value, struct variable *v)
1607 {
1608   char **choice;
1609
1610   for (choice = v->argv; *choice; choice++)
1611     {
1612       if (!strcmp (value, *choice))
1613         return TRUE;
1614     }
1615
1616   websDebugWrite (wp, "Invalid <b>%s</b> %s: not one of ", v->longname,
1617                   value);
1618   for (choice = v->argv; *choice; choice++)
1619     websDebugWrite (wp, "%s%s", choice == v->argv ? "" : "/", *choice);
1620   websDebugWrite (wp, "<br>");
1621   return FALSE;
1622 }
1623
1624 void
1625 validate_choice (webs_t wp, char *value, struct variable *v)
1626 {
1627   if (valid_choice (wp, value, v))
1628     nvram_set (v->name, value);
1629 }
1630
1631 int
1632 valid_range (webs_t wp, char *value, struct variable *v)
1633 {
1634   int n, start, end;
1635
1636   n = atoi (value);
1637   start = atoi (v->argv[0]);
1638   end = atoi (v->argv[1]);
1639
1640
1641   if (!ISDIGIT (value, 1) || n < start || n > end)
1642     {
1643       websDebugWrite (wp, "Invalid <b>%s</b> %s: out of range %d-%d<br>",
1644                       v->longname, value, start, end);
1645       return FALSE;
1646     }
1647
1648   return TRUE;
1649 }
1650
1651 static void
1652 validate_range (webs_t wp, char *value, struct variable *v)
1653 {
1654   char buf[20];
1655   int range;
1656   if (valid_range (wp, value, v))
1657     {
1658       range = atoi (value);
1659       snprintf (buf, sizeof (buf), "%d", range);
1660       nvram_set (v->name, buf);
1661     }
1662 }
1663
1664 int
1665 valid_name (webs_t wp, char *value, struct variable *v)
1666 {
1667   int n, max;
1668
1669   n = atoi (value);
1670
1671
1672   if (!ISASCII (value, 1))
1673     {
1674       return FALSE;
1675     }
1676   if (v)
1677     {
1678       max = atoi (v->argv[0]);
1679       if (strlen (value) > max)
1680         {
1681           return FALSE;
1682         }
1683     }
1684   return TRUE;
1685 }
1686
1687 static void
1688 validate_name (webs_t wp, char *value, struct variable *v)
1689 {
1690   if (valid_name (wp, value, v))
1691     nvram_set (v->name, value);
1692 }
1693
1694 int do_reboot = 0;
1695 static void
1696 validate_reboot (webs_t wp, char *value, struct variable *v)
1697 {
1698   if (value && v)
1699     {
1700       nvram_set (v->name, value);
1701       do_reboot = 1;
1702     }
1703 }
1704
1705 /* the html always show "d6nw5v1x2pc7st9m"
1706  * so we must filter it.
1707  */
1708 static void
1709 validate_password (webs_t wp, char *value, struct variable *v)
1710 {
1711   if (strcmp (value, TMP_PASSWD) && valid_name (wp, value, v))
1712     {
1713       nvram_set (v->name, zencrypt (value));
1714
1715       system2 ("/sbin/setpasswd");
1716     }
1717 }
1718
1719 static void
1720 validate_password2 (webs_t wp, char *value, struct variable *v)
1721 {
1722   if (strcmp (value, TMP_PASSWD) && valid_name (wp, value, v))
1723     {
1724       nvram_set (v->name, value);
1725     }
1726 }
1727
1728
1729 int
1730 valid_hwaddr (webs_t wp, char *value, struct variable *v)
1731 {
1732   /* Make exception for "NOT IMPLELEMENTED" string */
1733   if (!strcmp (value, "NOT_IMPLEMENTED"))
1734     return (TRUE);
1735
1736   /* Check for bad, multicast, broadcast, or null address */
1737   if (!legal_hwaddr (value))
1738     {
1739       websDebugWrite (wp, "Invalid <b>%s</b> %s: not a legal MAC address<br>",
1740                       v->longname, value);
1741       return FALSE;
1742     }
1743
1744   return TRUE;
1745 }
1746
1747 static void
1748 validate_hwaddr (webs_t wp, char *value, struct variable *v)
1749 {
1750   if (valid_hwaddr (wp, value, v))
1751     nvram_set (v->name, value);
1752 }
1753
1754 static void
1755 validate_hwaddrs (webs_t wp, char *value, struct variable *v)
1756 {
1757   validate_list (wp, value, v, valid_hwaddr);
1758 }
1759
1760 void
1761 ej_get_http_prefix (webs_t wp, int argc, char_t ** argv)
1762 {
1763   char http[10];
1764   char ipaddr[20];
1765   char port[10];
1766
1767   char *http_enable = websGetVar (wp, "http_enable", NULL);
1768 #ifdef HAVE_HTTPS
1769   char *https_enable = websGetVar (wp, "https_enable", NULL);
1770
1771   if (do_ssl && http_enable == NULL && https_enable == NULL)
1772     {
1773       strcpy (http, "https");
1774     }
1775   else if (do_ssl && http_enable && https_enable)
1776     {
1777       if (atoi (https_enable) && atoi (http_enable))
1778         strcpy (http, "https");
1779       else if (atoi (https_enable) && !atoi (http_enable))
1780         strcpy (http, "https");
1781       else                      // !atoi(https_enable) && atoi(http_enable)
1782         strcpy (http, "http");
1783     }
1784   else if (do_ssl && !http_enable && !https_enable)
1785     {
1786       strcpy (http, "http");
1787     }
1788   else if (!do_ssl && http_enable && https_enable)
1789     {
1790       if (atoi (https_enable) && atoi (http_enable))
1791         strcpy (http, "http");
1792       else if (atoi (https_enable) && !atoi (http_enable))
1793         strcpy (http, "https");
1794       else                      // !atoi(https_enable) && atoi(http_enable)
1795         strcpy (http, "http");
1796     }
1797   else
1798 #endif
1799     strcpy (http, "http");
1800
1801   if (browser_method == USE_LAN)
1802     {                           // Use LAN to browser
1803       if (nvram_match ("restore_defaults", "1")
1804           || nvram_match ("sv_restore_defaults", "1"))
1805         {
1806
1807
1808           strcpy (http, "http");
1809         }
1810       else
1811         strcpy (ipaddr, nvram_safe_get ("lan_ipaddr"));
1812       strcpy (port, "");
1813     }
1814   else
1815     {
1816
1817       if (nvram_match ("wan_proto", "pptp"))
1818         strcpy (ipaddr, nvram_safe_get ("pptp_get_ip"));
1819       else if (nvram_match ("wan_proto", "l2tp"))
1820         strcpy (ipaddr, nvram_safe_get ("l2tp_get_ip"));
1821       else
1822         strcpy (ipaddr, nvram_safe_get ("wan_ipaddr"));
1823
1824       sprintf (port, ":%s", nvram_safe_get ("http_wanport"));
1825     }
1826
1827   websWrite (wp, "%s://%s%s/", http, ipaddr, port);
1828
1829   return;
1830 }
1831
1832 void
1833 ej_get_mtu (webs_t wp, int argc, char_t ** argv)
1834 {
1835   struct mtu_lists *mtu_list;
1836   char *type;
1837   char *proto = GOZILA_GET ("wan_proto");
1838
1839   if (ejArgs (argc, argv, "%s", &type) < 1)
1840     {
1841       websError (wp, 400, "Insufficient args\n");
1842       return;
1843     }
1844
1845   mtu_list = get_mtu (proto);
1846
1847   if (!strcmp (type, "min"))
1848     websWrite (wp, "%s", mtu_list->min);
1849   else if (!strcmp (type, "max"))
1850     websWrite (wp, "%s", mtu_list->max);
1851
1852   return;
1853 }
1854
1855 /*
1856  * Variables are set in order (put dependent variables later). Set
1857  * nullok to TRUE to ignore zero-length values of the variable itself.
1858  * For more complicated validation that cannot be done in one pass or
1859  * depends on additional form components or can throw an error in a
1860  * unique painful way, write your own validation routine and assign it
1861  * to a hidden variable (e.g. filter_ip).
1862  */
1863 /*
1864 DD-WRT enhancement by seg
1865 This functions parses all /etc/config/xxxxx.nvramconfig files and creates the
1866 web var tab. so these vars arent defined anymore staticly
1867 */
1868
1869 #include <stdlib.h>
1870 #include <malloc.h>
1871 #include <dirent.h>
1872 #include <stdlib.h>
1873
1874
1875 int
1876 endswith (char *str, char *cmp)
1877 {
1878   int cmp_len, str_len, i;
1879   if (cmp == NULL)
1880     return 0;
1881   if (str == NULL)
1882     return 0;
1883   cmp_len = strlen (cmp);
1884   str_len = strlen (str);
1885   if (cmp_len > str_len)
1886     return (0);
1887   for (i = 0; i < cmp_len; i++)
1888     {
1889       if (str[(str_len - 1) - i] != cmp[(cmp_len - 1) - i])
1890         return (0);
1891     }
1892   return (1);
1893 }
1894
1895 char *
1896 toUP (char *a)
1897 {
1898   int i;
1899   int slen = strlen (a);
1900   for (i = 0; i < slen; i++)
1901     {
1902       if (a[i] > 'a' - 1 && a[i] < 'z' + 1)
1903         a[i] -= 'a' + 'A';
1904     }
1905   return a;
1906 }
1907
1908 int
1909 stricmp (char *a, char *b)
1910 {
1911   if (strlen (a) != strlen (b))
1912     return -1;
1913   return strcmp (toUP (a), toUP (b));
1914 }
1915
1916 void
1917 StringStart (FILE * in)
1918 {
1919   while (getc (in) != '"')
1920     {
1921       if (feof (in))
1922         return;
1923     }
1924 }
1925
1926 char *
1927 getFileString (FILE * in)
1928 {
1929   char *buf;
1930   int i, b;
1931   buf = malloc (1024);
1932   StringStart (in);
1933   for (i = 0; i < 1024; i++)
1934     {
1935       b = getc (in);
1936       if (b == EOF)
1937         return NULL;
1938       if (b == '"')
1939         {
1940           buf[i] = 0;
1941           buf = realloc (buf, strlen (buf) + 1);
1942           return buf;
1943         }
1944       buf[i] = b;
1945     }
1946   return buf;
1947 }
1948
1949 void
1950 skipFileString (FILE * in)
1951 {
1952   int i, b;
1953   StringStart (in);
1954   for (i = 0; i < 1024; i++)
1955     {
1956       b = getc (in);
1957       if (b == EOF)
1958         return;
1959       if (b == '"')
1960         {
1961           return;
1962         }
1963     }
1964   return;
1965 }
1966
1967 static char *directories[] = {
1968   "/etc/config",
1969   "/jffs/etc/config",
1970   "/mmc/etc/config"
1971 };
1972
1973 struct variable **variables;
1974 void
1975 Initnvramtab ()
1976 {
1977   struct dirent *entry;
1978   DIR *directory;
1979   FILE *in;
1980   int varcount = 0, len, i;
1981   char *tmpstr;
1982   struct variable *tmp;
1983   variables = NULL;
1984   char buf[1024];
1985 // format = VARNAME VARDESC VARVALID VARVALIDARGS FLAGS FLAGS
1986 //open config directory directory =
1987   int idx;
1988   for (idx = 0; idx < 3; idx++)
1989     {
1990       directory = opendir (directories[idx]);
1991       if (directory == NULL)
1992         continue;
1993 //list all files in this directory
1994       while ((entry = readdir (directory)) != NULL)
1995         {
1996           if (endswith (entry->d_name, ".nvramconfig"))
1997             {
1998               sprintf (buf, "%s/%s", directories[idx], entry->d_name);
1999               in = fopen (buf, "rb");
2000               if (in == NULL)
2001                 {
2002                   return;
2003                 }
2004               while (1)
2005                 {
2006                   tmp = (struct variable *) malloc (sizeof (struct variable));
2007                   tmp->name = getFileString (in);
2008                   tmp->validate = NULL;
2009                   tmp->validate2 = NULL;
2010                   if (tmp->name == NULL)
2011                     break;
2012                   skipFileString (in);  //long string
2013                   tmpstr = getFileString (in);
2014                   tmp->argv = NULL;
2015                   if (!stricmp (tmpstr, "RANGE"))
2016                     {
2017                       tmp->validate = validate_range;
2018                       tmp->argv = (char **) malloc (sizeof (char **) * 3);
2019                       tmp->argv[0] = getFileString (in);
2020                       tmp->argv[1] = getFileString (in);
2021                       tmp->argv[2] = NULL;
2022                     }
2023                   if (!stricmp (tmpstr, "CHOICE"))
2024                     {
2025                       tmp->validate = validate_choice;
2026                       free (tmpstr);
2027                       tmpstr = getFileString (in);
2028                       len = atoi (tmpstr);
2029                       tmp->argv =
2030                         (char **) malloc (sizeof (char **) * (len + 1));
2031                       for (i = 0; i < len; i++)
2032                         {
2033                           tmp->argv[i] = getFileString (in);
2034                         }
2035                       tmp->argv[i] = NULL;
2036                     }
2037 #ifdef HAVE_SPUTNIK_APD
2038                   if (!stricmp (tmpstr, "MJIDTYPE"))
2039                     {
2040                       tmp->validate = validate_choice;
2041                       free (tmpstr);
2042                       tmpstr = getFileString (in);
2043                       len = atoi (tmpstr);
2044                       tmp->argv =
2045                         (char **) malloc (sizeof (char **) * (len + 1));
2046                       for (i = 0; i < len; i++)
2047                         {
2048                           tmp->argv[i] = getFileString (in);
2049                         }
2050                       tmp->argv[i] = NULL;
2051                       nvram_set ("sputnik_rereg", "1");
2052                     }
2053 #endif
2054                   if (!stricmp (tmpstr, "NOACK"))
2055                     {
2056                       tmp->validate = validate_noack;
2057                       len = 2;
2058                       tmp->argv =
2059                         (char **) malloc (sizeof (char **) * (len + 1));
2060                       for (i = 0; i < len; i++)
2061                         {
2062                           tmp->argv[i] = getFileString (in);
2063                         }
2064                       tmp->argv[i] = NULL;
2065                     }
2066                   if (!stricmp (tmpstr, "NAME"))
2067                     {
2068                       tmp->validate = validate_name;
2069                       tmp->argv = (char **) malloc (sizeof (char **) * 2);
2070                       tmp->argv[0] = getFileString (in);
2071                       tmp->argv[1] = NULL;
2072                     }
2073                   if (!stricmp (tmpstr, "NULL"))
2074                     {
2075                       tmp->validate = NULL;
2076                       tmp->validate2 = NULL;
2077                     }
2078                   if (!stricmp (tmpstr, "WMEPARAM"))
2079                     {
2080                       tmp->validate = validate_wl_wme_params;
2081                     }
2082                   if (!stricmp (tmpstr, "PASSWORD"))
2083                     {
2084                       tmp->validate = validate_password;
2085                       tmp->argv = (char **) malloc (sizeof (char **) * 2);
2086                       tmp->argv[0] = getFileString (in);
2087                       tmp->argv[1] = NULL;
2088                     }
2089                   if (!stricmp (tmpstr, "PASSWORD2"))
2090                     {
2091                       tmp->validate = validate_password2;
2092                       tmp->argv = (char **) malloc (sizeof (char **) * 2);
2093                       tmp->argv[0] = getFileString (in);
2094                       tmp->argv[1] = NULL;
2095                     }
2096                   if (!stricmp (tmpstr, "LANIPADDR"))
2097                     {
2098                       tmp->validate = validate_lan_ipaddr;
2099                       tmp->argv = (char **) malloc (sizeof (char **) * 2);
2100                       tmp->argv[0] = getFileString (in);
2101                       tmp->argv[1] = NULL;
2102                     }
2103                   if (!stricmp (tmpstr, "WANIPADDR"))
2104                     {
2105                       tmp->validate = validate_wan_ipaddr;
2106                     }
2107                   if (!stricmp (tmpstr, "MERGEIPADDRS"))
2108                     {
2109                       tmp->validate = validate_merge_ipaddrs;
2110                     }
2111                   if (!stricmp (tmpstr, "DNS"))
2112                     {
2113                       tmp->validate = validate_dns;
2114                     }
2115                   if (!stricmp (tmpstr, "SAVEWDS"))
2116                     {
2117                       tmp->validate = NULL;
2118                       tmp->validate2 = save_wds;
2119                     }
2120                   if (!stricmp (tmpstr, "DHCP"))
2121                     {
2122                       tmp->validate = &dhcp_check;
2123                     }
2124                   if (!stricmp (tmpstr, "WPAPSK"))
2125                     {
2126                       tmp->validate = validate_wpa_psk;
2127                       tmp->argv = (char **) malloc (sizeof (char **) * 2);
2128                       tmp->argv[0] = getFileString (in);
2129                       tmp->argv[1] = NULL;
2130                     }
2131                   if (!stricmp (tmpstr, "STATICS"))
2132                     {
2133                       tmp->validate = validate_statics;
2134                     }
2135 #ifdef HAVE_PORTSETUP
2136                   if (!stricmp (tmpstr, "PORTSETUP"))
2137                     {
2138                       tmp->validate = validate_portsetup;
2139                     }
2140 #endif
2141                   if (!stricmp (tmpstr, "REBOOT"))
2142                     {
2143                       tmp->validate = validate_reboot;
2144                     }
2145                   if (!stricmp (tmpstr, "IPADDR"))
2146                     {
2147                       tmp->validate = validate_ipaddr;
2148                     }
2149                   if (!stricmp (tmpstr, "STATICLEASES"))
2150                     {
2151                       tmp->validate = validate_staticleases;
2152                     }
2153 #ifdef HAVE_CHILLILOCAL
2154                   if (!stricmp (tmpstr, "USERLIST"))
2155                     {
2156                       tmp->validate = validate_userlist;
2157                     }
2158 #endif
2159 #ifdef HAVE_RADLOCAL
2160                   if (!stricmp (tmpstr, "IRADIUSUSERLIST"))
2161                     {
2162                       tmp->validate = validate_iradius;
2163                     }
2164 #endif
2165                   if (!stricmp (tmpstr, "IPADDRS"))
2166                     {
2167                       tmp->validate = validate_ipaddrs;
2168                     }
2169                   if (!stricmp (tmpstr, "NETMASK"))
2170                     {
2171                       tmp->validate = validate_netmask;
2172                     }
2173                   if (!stricmp (tmpstr, "MERGENETMASK"))
2174                     {
2175                       tmp->validate = validate_merge_netmask;
2176                     }
2177                   if (!stricmp (tmpstr, "WDS"))
2178                     {
2179                       tmp->validate = validate_wds;
2180                     }
2181                   if (!stricmp (tmpstr, "STATICROUTE"))
2182                     {
2183                       tmp->validate = validate_static_route;
2184                     }
2185                   if (!stricmp (tmpstr, "MERGEMAC"))
2186                     {
2187                       tmp->validate = validate_merge_mac;
2188                     }
2189                   if (!stricmp (tmpstr, "FILTERPOLICY"))
2190                     {
2191                       tmp->validate = validate_filter_policy;
2192                     }
2193                   if (!stricmp (tmpstr, "FILTERIPGRP"))
2194                     {
2195                       tmp->validate = validate_filter_ip_grp;
2196                     }
2197                   if (!stricmp (tmpstr, "FILTERPORT"))
2198                     {
2199                       tmp->validate = validate_filter_port;
2200                     }
2201                   if (!stricmp (tmpstr, "FILTERDPORTGRP"))
2202                     {
2203                       tmp->validate = validate_filter_dport_grp;
2204                     }
2205                   if (!stricmp (tmpstr, "BLOCKEDSERVICE"))
2206                     {
2207                       tmp->validate = validate_blocked_service;
2208                     }
2209                   if (!stricmp (tmpstr, "FILTERP2P"))
2210                     {
2211                       tmp->validate = validate_catchall;
2212                     }
2213                   if (!stricmp (tmpstr, "FILTERMACGRP"))
2214                     {
2215                       tmp->validate = validate_filter_mac_grp;
2216                     }
2217                   if (!stricmp (tmpstr, "FILTERWEB"))
2218                     {
2219                       tmp->validate = validate_filter_web;
2220                     }
2221                   if (!stricmp (tmpstr, "WLHWADDRS"))
2222                     {
2223                       tmp->validate = validate_wl_hwaddrs;
2224                     }
2225                   if (!stricmp (tmpstr, "FORWARDPROTO"))
2226                     {
2227                       tmp->validate = validate_forward_proto;
2228                     }
2229                   if (!stricmp (tmpstr, "FORWARDSPEC"))
2230                     {
2231                       tmp->validate = validate_forward_spec;
2232                     }
2233 // changed by steve
2234                   /*if (!stricmp (tmpstr, "FORWARDUPNP"))
2235                      {
2236                      tmp->validate = validate_forward_upnp;
2237                      } */
2238 // end changed by steve
2239                   if (!stricmp (tmpstr, "PORTTRIGGER"))
2240                     {
2241                       tmp->validate = validate_port_trigger;
2242                     }
2243                   if (!stricmp (tmpstr, "HWADDR"))
2244                     {
2245                       tmp->validate = validate_hwaddr;
2246                     }
2247                   if (!stricmp (tmpstr, "HWADDRS"))
2248                     {
2249                       tmp->validate = validate_hwaddrs;
2250                     }
2251                   if (!stricmp (tmpstr, "WLWEPKEY"))
2252                     {
2253                       tmp->validate = validate_wl_wep_key;
2254                     }
2255
2256                   if (!stricmp (tmpstr, "WLAUTH"))
2257                     {
2258                       tmp->validate = validate_wl_auth;
2259                       tmp->argv = (char **) malloc (sizeof (char **) * 3);
2260                       tmp->argv[0] = getFileString (in);
2261                       tmp->argv[1] = getFileString (in);
2262                       tmp->argv[2] = NULL;
2263                     }
2264                   if (!stricmp (tmpstr, "WLWEP"))
2265                     {
2266                       tmp->validate = validate_wl_wep;
2267                       free (tmpstr);
2268                       tmpstr = getFileString (in);
2269                       len = atoi (tmpstr);
2270                       tmp->argv =
2271                         (char **) malloc (sizeof (char **) * (len + 1));
2272                       for (i = 0; i < len; i++)
2273                         {
2274                           tmp->argv[i] = getFileString (in);
2275                         }
2276                       tmp->argv[i] = NULL;
2277                     }
2278
2279                   if (!stricmp (tmpstr, "DYNAMICROUTE"))
2280                     {
2281                       tmp->validate = validate_dynamic_route;
2282                       free (tmpstr);
2283                       tmpstr = getFileString (in);
2284                       len = atoi (tmpstr);
2285                       tmp->argv =
2286                         (char **) malloc (sizeof (char **) * (len + 1));
2287                       for (i = 0; i < len; i++)
2288                         {
2289                           tmp->argv[i] = getFileString (in);
2290                         }
2291                       tmp->argv[i] = NULL;
2292                     }
2293                   if (!stricmp (tmpstr, "WLGMODE"))
2294                     {
2295                       tmp->validate = validate_wl_gmode;
2296                       free (tmpstr);
2297                       tmpstr = getFileString (in);
2298                       len = atoi (tmpstr);
2299                       tmp->argv =
2300                         (char **) malloc (sizeof (char **) * (len + 1));
2301                       for (i = 0; i < len; i++)
2302                         {
2303                           tmp->argv[i] = getFileString (in);
2304                         }
2305                       tmp->argv[i] = NULL;
2306                     }
2307                   if (!stricmp (tmpstr, "WLNETMODE"))
2308                     {
2309                       tmp->validate = validate_wl_net_mode;
2310                       free (tmpstr);
2311                       tmpstr = getFileString (in);
2312                       len = atoi (tmpstr);
2313                       tmp->argv =
2314                         (char **) malloc (sizeof (char **) * (len + 1));
2315                       for (i = 0; i < len; i++)
2316                         {
2317                           tmp->argv[i] = getFileString (in);
2318                         }
2319                       tmp->argv[i] = NULL;
2320                     }
2321                   if (!stricmp (tmpstr, "AUTHMODE"))
2322                     {
2323                       tmp->validate = validate_auth_mode;
2324                       free (tmpstr);
2325                       tmpstr = getFileString (in);
2326                       len = atoi (tmpstr);
2327                       tmp->argv =
2328                         (char **) malloc (sizeof (char **) * (len + 1));
2329                       for (i = 0; i < len; i++)
2330                         {
2331                           tmp->argv[i] = getFileString (in);
2332                         }
2333                       tmp->argv[i] = NULL;
2334                     }
2335 #ifndef HAVE_MSSID
2336                   if (!stricmp (tmpstr, "SECURITYMODE"))
2337                     {
2338                       tmp->validate = validate_security_mode;
2339                       free (tmpstr);
2340                       tmpstr = getFileString (in);
2341                       len = atoi (tmpstr);
2342                       tmp->argv =
2343                         (char **) malloc (sizeof (char **) * (len + 1));
2344                       for (i = 0; i < len; i++)
2345                         {
2346                           tmp->argv[i] = getFileString (in);
2347                         }
2348                       tmp->argv[i] = NULL;
2349                     }
2350 #endif
2351 #ifdef HAVE_PPPOESERVER
2352                   if (!stricmp (tmpstr, "CHAPTABLE"))
2353                     {
2354                       tmp->validate = validate_chaps;
2355                     }
2356 #endif
2357
2358 #ifdef HAVE_MILKFISH
2359                   if (!stricmp (tmpstr, "MFSUBSCRIBERS"))
2360                     {
2361                       tmp->validate = validate_subscribers;
2362                     }
2363                   if (!stricmp (tmpstr, "MFALIASES"))
2364                     {
2365                       tmp->validate = validate_aliases;
2366                     }
2367 #endif
2368
2369
2370                   free (tmpstr);
2371                   tmpstr = getFileString (in);
2372                   if (!stricmp (tmpstr, "TRUE"))
2373                     {
2374                       tmp->nullok = TRUE;
2375                     }
2376                   else
2377                     {
2378                       tmp->nullok = FALSE;
2379                     }
2380                   free (tmpstr);
2381                   skipFileString (in);  //todo: remove it
2382 //                tmpstr = getFileString (in);
2383 //                tmp->ezc_flags = atoi (tmpstr);
2384 //                free (tmpstr);
2385                   variables =
2386                     (struct variable **) realloc (variables,
2387                                                   sizeof (struct variable **)
2388                                                   * (varcount + 2));
2389                   variables[varcount++] = tmp;
2390                   variables[varcount] = NULL;
2391                 }
2392               fclose (in);
2393             }
2394         }
2395       closedir (directory);
2396     }
2397 }
2398
2399 /*
2400         { "lan_ipaddr", "LAN IP Address", validate_lan_ipaddr, ARGV("lan"), FALSE },
2401
2402         { "router_name", "Routert Name", validate_name, ARGV("255"), TRUE, 0 },
2403         { "wan_hostname","WAN Host Name", validate_name, ARGV("255"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2404         { "wan_domain", "WAN Domain Name", validate_name, ARGV("255"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2405         { "wan_ipaddr", "WAN IP Address", validate_wan_ipaddr, NULL, FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2406         //{ "wan_ipaddr", "WAN IP Address", validate_merge_ipaddrs, NULL, FALSE },
2407         //{ "wan_netmask", "WAN Subnet Mask", validate_merge_netmask, FALSE },
2408         //{ "wan_gateway", "WAN Gateway", validate_merge_ipaddrs, ARGV("wan_ipaddr","wan_netmask"), FALSE },
2409         { "wan_proto", "WAN Protocol", validate_choice, ARGV("disabled", "dhcp", "static", "pppoe", "pptp", "l2tp", "heartbeat"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2410         { "ntp_server", "NTP Server", NULL, NULL, TRUE, 0 },  // not use
2411         { "ntp_mode", "NTP Mode", validate_choice, ARGV("manual","auto"), TRUE, 0 },
2412         { "daylight_time", "Daylight", validate_choice, ARGV("0", "1"), TRUE, 0 },
2413         { "time_zone", "Time Zone", validate_choice, ARGV("-12 1 0","-11 1 0","-10 1 0","-09 1 1","-08 1 1","-07 1 0","-07 2 1","-06 1 0","-06 2 1","-05 1 0","-05 2 1","-04 1 0","-04 2 1","-03.5 1 1","-03 1 0","-03 2 1","-02 1 0","-01 1 2","+00 1 0","+00 2 2","+01 1 0","+01 2 2","+02 1 0","+02 2 2","+03 1 0","+04 1 0","+05 1 0","+06 1 0","+07 1 0","+08 1 0","+08 2 0","+09 1 0","+10 1 0","+10 2 4","+11 1 0","+12 1 0","+12 2 4"), FALSE, 0 },
2414         //{ "pptp_server_ip", "WAN Gateway", validate_merge_ipaddrs, ARGV("wan_ipaddr","wan_netmask"), FALSE },
2415         { "ppp_username", "Username", validate_name, ARGV("63"), FALSE, 0 },
2416         { "ppp_passwd", "Password", validate_password, ARGV("63"), TRUE, 0 },
2417         { "ppp_keepalive", "Keep Alive", validate_choice, ARGV("0", "1"), FALSE, 0 },
2418         { "ppp_demand", "Connect on Demand", validate_choice, ARGV("0", "1"), FALSE, 0 },
2419         { "ppp_idletime", "Max Idle Time", validate_range, ARGV("1", "9999"), FALSE, 0 },
2420         { "ppp_redialperiod", "Redial Period", validate_range, ARGV("1", "9999"), FALSE, 0 },
2421         { "ppp_service", "Service Name", validate_name, ARGV("63"), TRUE, 0 },  // 2003-03-19 by honor
2422         { "ppp_static", "Enable /Disable Static IP", validate_choice, ARGV("0", "1"), TRUE, 0 },
2423         { "ppp_static_ip", "Static IP", validate_merge_ipaddrs, NULL, FALSE, 0 },
2424         { "wan_dns", "WAN DNS Server", validate_dns, NULL, FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2425         { "lan_proto", "LAN Protocol", validate_choice, ARGV("dhcp", "static"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2426         { "dhcp_check", "DHCP check", dhcp_check, NULL, FALSE, 0 },
2427         { "dhcp_start", "DHCP Server LAN IP Address Range", validate_range, ARGV("0","255"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2428         //{ "dhcp_start", "DHCP Server LAN IP Address Range", validate_merge_ip_4, NULL, FALSE },
2429         { "dhcp_num", "DHCP Users", validate_range, ARGV("1","253"), FALSE, 0 },
2430         { "dhcp_lease", "DHCP Client Lease Time", validate_range, ARGV("0","99999"), FALSE, 0 },
2431         { "wan_wins", "WAN WINS Server", validate_merge_ipaddrs, NULL, FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2432         { "http_username", "Router Username", validate_name, ARGV("63"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2433         { "http_passwd", "Router Password", validate_password, ARGV("63"), TRUE, EZC_FLAGS_WRITE },
2434         { "upnp_enable", "UPnP", validate_choice, ARGV("0", "1"), FALSE, 0 },
2435         { "web_wl_filter", "Wireless Access Web", validate_choice, ARGV("0", "1"), FALSE, 0 },
2436         { "http_enable", "HTTP Server", validate_choice, ARGV("0", "1"), FALSE, 0 },
2437         { "https_enable", "HTTPS Server", validate_choice, ARGV("0", "1"), FALSE, 0 },
2438
2439         { "samba_mount", "SambaFS Mount", validate_choice, ARGV("0", "1"), FALSE,0 },
2440         { "samba_share", "SambaFS Share", NULL, NULL, FALSE,0 },
2441         { "samba_user" , "SambaFS User" , NULL, NULL, FALSE,0 },
2442         { "samba_password", "SambaFS Password", NULL,NULL, FALSE ,0},
2443         { "samba_script", "SambaFS StartScript", NULL,NULL, FALSE,0 },
2444         { "rflow_enable" , "RFLOW Enable" , validate_choice,ARGV("0","1"), FALSE,0 },
2445         { "rflow_ip", "RFLOW IP", NULL,NULL, FALSE,0 },
2446         { "rflow_port", "RFLOW PORT", NULL,NULL, FALSE,0 },
2447         { "macupd_enable" , "MAC Update Enable" , validate_choice,ARGV("0","1"), FALSE,0 },
2448         { "macupd_ip", "MAC Update IP", NULL,NULL, FALSE,0 },
2449         { "macupd_port", "MAC update PORT", NULL,NULL, FALSE,0 },
2450         { "macupd_interval", "MAC Update Interval", NULL,NULL, FALSE,0 },
2451         { "status_auth","Status Site Authentication",NULL,NULL,FALSE,0},
2452
2453
2454         { "rc_startup", "Startup Script", NULL, NULL, FALSE, 0 },
2455         { "rc_firewall", "Firewall Script", NULL, NULL, FALSE, 0 },
2456         { "lan_gateway", "LAN Gateway", validate_merge_ipaddrs, NULL, FALSE, 0 },
2457         { "sv_localdns", "Local DNS", validate_merge_ipaddrs, NULL, FALSE, 0 },
2458         { "lan_domain", "LAN Domain Name", validate_name, ARGV("255"), TRUE, 0 },
2459         { "wl_mode", "Wireless Mode", validate_choice, ARGV("ap", "wet", "infra"), FALSE, 0 },
2460         { "txpwr", "TX Power", validate_range, ARGV("0","251"),  FALSE, 0 },
2461         { "txant", "TX Ant", validate_choice, ARGV("0","1","3"),  FALSE, 0 },
2462         { "wl_antdiv", "RX Ant", validate_choice, ARGV("0","1","3"),  FALSE, 0 },
2463         { "apwatchdog_enable", "AP Watchdog", validate_choice, ARGV("0", "1"), FALSE, 0 },
2464         { "apwatchdog_interval", "AP Watchdog", validate_range, ARGV("0", "86400"), FALSE, 0 },
2465         { "boot_wait", "Boot Wait", validate_choice, ARGV("on", "off"), FALSE, 0 },
2466         { "cron_enable", "Cron", validate_choice, ARGV("0", "1"), FALSE, 0 },
2467         { "dhcp_domain", "DHCP Domain", validate_choice, ARGV("wan", "lan"), FALSE, 0 },
2468         { "dhcpd_statics", "DHCP", validate_statics, NULL, TRUE, 0 },
2469         { "dhcpd_options", "DHCP", NULL, NULL, TRUE, 0 },
2470         { "dnsmasq_enable", "DNS Masq", validate_choice, ARGV("0", "1"), FALSE, 0 },
2471         { "dnsmasq_options", "DNS Masq", NULL, NULL, TRUE, 0 },
2472         { "httpd_enable", "Httpd", validate_choice, ARGV("0", "1"), FALSE, 0 },
2473         { "httpsd_enable", "Httpsd", validate_choice, ARGV("0", "1"), FALSE, 0 },
2474         { "loopback_enable", "Loopback", validate_choice, ARGV("0", "1"), FALSE, 0 },
2475         { "local_dns", "Local DNS", validate_choice, ARGV("0", "1"), FALSE, 0 },
2476         { "nas_enable", "NAS", validate_choice, ARGV("0", "1"), FALSE, 0 },
2477         { "ntp_enable", "NTP Client", validate_choice, ARGV("0", "1"), FALSE, 0 },
2478         { "pptpd_enable", "PPTPD", validate_choice, ARGV("0", "1"), FALSE, 0 },
2479         { "pptpd_lip", "PPTPD", NULL, NULL, FALSE, 0 },
2480         { "pptpd_rip", "PPTPD", NULL, NULL, FALSE, 0 },
2481         { "pptpd_auth", "PPTPD", NULL, NULL, FALSE, 0 },
2482         { "pptp_encrypt", "PPTP", validate_choice, ARGV("0", "1"), FALSE, 0 },
2483         { "resetbutton_enable", "Resetbuttond", validate_choice, ARGV("0", "1"), FALSE, 0 },
2484         { "telnetd_enable", "Telnetd", validate_choice, ARGV("0", "1"), FALSE, 0 },
2485         { "sshd_enable", "SSHD", validate_choice, ARGV("0", "1"), FALSE, 0 },
2486         { "sshd_port", "SSHD", validate_range, ARGV("1", "65535"), FALSE, 0 },
2487         { "sshd_passwd_auth", "SSHD", validate_choice, ARGV("0", "1"), FALSE, 0 },
2488         { "sshd_rsa_host_key", "SSHD", NULL, NULL, TRUE, 0 },
2489         { "sshd_authorized_keys", "SSHD", NULL, NULL, TRUE , 0 },
2490         { "syslogd_enable", "Syslog", validate_choice, ARGV("0", "1"), FALSE, 0 },
2491         { "syslogd_rem_ip", "Syslog", validate_ipaddr, NULL, TRUE, 0 },
2492
2493         { "wshaper_enable", "Bandwidth Mgmt", validate_choice, ARGV("0", "1"), FALSE, 0 },
2494         { "wshaper_dev", "Bandwidth Mgmt", validate_choice, ARGV("WAN", "LAN", "wLAN"), FALSE, 0 },
2495         { "wshaper_downlink", "Bandwidth Mgmt", NULL, NULL, TRUE, 0 },
2496         { "wshaper_uplink", "Bandwidth Mgmt", NULL, NULL, TRUE, 0 },
2497         { "wshaper_nopriohostsrc", "Bandwidth Mgmt", NULL, NULL, TRUE, 0 },
2498         { "wshaper_nopriohostdst", "Bandwidth Mgmt", NULL, NULL, TRUE, 0 },
2499         { "wshaper_noprioportsrc", "Bandwidth Mgmt", NULL, NULL, TRUE, 0 },
2500         { "wshaper_noprioportdst", "Bandwidth Mgmt", NULL, NULL, TRUE, 0 },
2501         { "zebra_enable", "Zebra", validate_choice, ARGV("0", "1"), FALSE, 0 },
2502
2503
2504         // WDS vars
2505         { "wl_wds1_enable","WDS separate bridge Enabled", save_wds, NULL, FALSE, 0 },
2506         { "wl_wds1_hwaddr","WDS MAC", validate_wds, NULL, FALSE, 0 },
2507         { "bird_ospf","Routing", NULL, NULL, TRUE, 0 },
2508
2509         { "snmpd_enable", "Snmpd", validate_choice, ARGV("0", "1"), FALSE, 0 },
2510         { "snmpd_syslocation", "Snmpd", NULL, NULL, TRUE, 0 },
2511         { "snmpd_syscontact", "Snmpd", NULL, NULL, TRUE, 0 },
2512         { "snmpd_sysname", "Snmpd", NULL, NULL, TRUE, 0 },
2513         { "snmpd_rocommunity", "Snmpd", NULL, NULL, TRUE, 0 },
2514         { "snmpd_rwcommunity", "Snmpd", NULL, NULL, TRUE, 0 },
2515
2516         { "wol_enable", "Wol", validate_choice, ARGV("0", "1"), FALSE, 0 },
2517         { "wol_interval", "Wol", validate_range, ARGV("1", "86400"), TRUE, 0 },
2518         { "wol_hostname", "Wol", NULL, NULL, TRUE, 0 },
2519         { "wol_macs", "Wol", NULL, NULL, TRUE, 0 },
2520         { "wol_passwd", "Wol", NULL, NULL, TRUE, 0 },
2521
2522         { "chilli_enable", "Enable Chillispot", validate_choice, ARGV("0","1"), TRUE, 0 },
2523         { "chilli_url", "Redirect URL", validate_name, ARGV("128"), TRUE, 0 },
2524         { "chilli_radius1", "Primary Radius Server", validate_merge_ipaddrs, NULL, FALSE, 0 },
2525         { "chilli_radius2", "Backup Radius Server", validate_merge_ipaddrs, NULL, FALSE, 0 },
2526         { "chilli_pass", "Radius Password", validate_name, ARGV("128"), TRUE, 0 },
2527         { "chilli_dns1", "Chillispot DNS1", validate_merge_ipaddrs, NULL, FALSE, 0 },
2528
2529         { "def_whwaddr", "User define wireless MAC Address", validate_merge_mac, NULL, TRUE, 0 },
2530
2531         { "log_dropped", "Access log D", validate_choice, ARGV("0", "1"), FALSE, 0 },
2532         { "log_rejected", "Access log R", validate_choice, ARGV("0", "1"), FALSE, 0 },
2533         { "log_accepted", "Access log A", validate_choice, ARGV("0", "1"), FALSE, 0 },
2534
2535         { "log_level", "Connection Logging", validate_range, ARGV("0", "3"), FALSE, 0 },
2536         { "log_enable", "Access log", validate_choice, ARGV("0", "1"), FALSE, 0 },
2537         { "filter", "Firewall Protection", validate_choice, ARGV("on", "off"), FALSE, 0 },
2538         { "filter_policy", "Filter", validate_filter_policy, NULL, FALSE, 0 },
2539         { "filter_ip_value", "TCP/UDP IP Filter", validate_filter_ip_grp, NULL, FALSE, 0 },
2540         { "filter_port", "TCP/UDP Port Filter", validate_filter_port, NULL, FALSE, 0 },
2541         { "filter_dport_value", "TCP/UDP Port Filter", validate_filter_dport_grp, NULL, FALSE, 0 },
2542         { "blocked_service", "TCP/UDP Port Filter", validate_blocked_service, NULL, FALSE, 0 },
2543         { "filter_mac_value", "TCP/UDP MAC Filter", validate_filter_mac_grp, NULL, FALSE, 0 },
2544         { "filter_web", "Website Filter", validate_filter_web, NULL, FALSE, 0 },
2545         { "block_wan", "Block WAN Request", validate_choice, ARGV("0", "1"), FALSE, 0 },
2546         { "ident_pass", "IDENT passthrough", validate_choice, ARGV("0", "1"), TRUE, 0 },
2547         { "block_loopback", "Filter Internet NAT redirection", validate_choice, ARGV("0", "1"), FALSE, 0 },
2548         { "block_proxy", "Block Proxy", validate_choice, ARGV("0", "1"), FALSE, 0 },
2549         { "block_java", "Block Java", validate_choice, ARGV("0", "1"), FALSE, 0 },
2550         { "block_activex", "Block ActiveX", validate_choice, ARGV("0", "1"), FALSE, 0 },
2551         { "block_cookie", "Block Cookie", validate_choice, ARGV("0", "1"), FALSE, 0 },
2552         { "multicast_pass", "Multicast Pass Through", validate_choice, ARGV("0", "1"), FALSE, 0 },
2553         { "ipsec_pass", "IPSec Pass Through", validate_choice, ARGV("0", "1"), FALSE, 0 },
2554         { "pptp_pass", "PPTP Pass Through", validate_choice, ARGV("0", "1"), FALSE, 0 },
2555         { "l2tp_pass", "L2TP Pass Through", validate_choice, ARGV("0", "1"), FALSE, 0 },
2556         { "remote_management", "Remote Management", validate_choice, ARGV("0", "1"), FALSE, 0 },
2557         { "remote_mgt_https", "Remote Management use https", validate_choice, ARGV("0", "1"), FALSE, 0 },
2558         { "http_wanport", "Router WAN Port", validate_range, ARGV("0", "65535"), TRUE, 0 },
2559         { "remote_upgrade", "Remote Upgrade", validate_choice, ARGV("0", "1"), FALSE, 0 },
2560         { "mtu_enable", "MTU enable", validate_choice, ARGV("0", "1"), FALSE, 0 },
2561         { "wan_mtu", "WAN MTU", validate_range, ARGV("576","1500"), FALSE, 0 },
2562         { "forward_port", "TCP/UDP Port Forward", validate_forward_proto, NULL, FALSE, 0 },
2563         { "port_trigger", "TCP/UDP Port Trigger", validate_port_trigger, NULL, FALSE, 0 },
2564         { "static_route", "Static Route", validate_static_route, NULL, FALSE, 0 },
2565         { "wk_mode", "Working Mode", validate_dynamic_route, ARGV("gateway", "router", "ospf"), FALSE, 0 },
2566         //{ "dr_setting", "Dynamic Routing", validate_choice, ARGV("0", "1", "2", "3"), FALSE },
2567         //{ "dr_lan_tx", "Dynamic Routing LAN TX", validate_choice, ARGV("0","1 2"), FALSE },
2568         //{ "dr_lan_rx", "Dynamic Routing LAN RX", validate_choice, ARGV("0","1 2"), FALSE },
2569         //{ "dr_wan_tx", "Dynamic Routing WAN TX", validate_choice, ARGV("0","1 2"), FALSE },
2570         //{ "dr_wan_rx", "Dynamic Routing WAN RX", validate_choice, ARGV("0","1 2"), FALSE },
2571         { "dmz_enable", "DMZ enable", validate_choice, ARGV("0", "1"), FALSE, 0 },
2572         { "dmz_ipaddr", "DMZ LAN IP Address", validate_range, ARGV("0","255"), FALSE, 0 },
2573         { "mac_clone_enable", "User define WAN MAC Address", validate_choice, ARGV("0","1"), TRUE, 0 },
2574         { "def_hwaddr", "User define WAN MAC Address", validate_merge_mac, NULL, TRUE, 0 },
2575         { "upgrade_enable", "Tftp upgrade", validate_choice, ARGV("0", "1"), FALSE, 0 },
2576         { "wl_enable", "Enable Wireless", validate_choice, ARGV("0","1"), TRUE, 0 },
2577         { "wl_ssid", "Network Name (SSID)", validate_name, ARGV("32"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2578         { "wl_closed", "Network Type", validate_choice, ARGV("0", "1"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2579         { "wl_country", "Country", validate_choice, ARGV("Worldwide", "Thailand", "Israel", "Jordan", "China", "Japan", "USA", "Europe", "USA Low", "Japan High", "All"), FALSE, 0 },
2580         { "wl_ap_isolate", "AP Isolate", validate_choice, ARGV("0", "1"), TRUE, 0 },
2581 //        { "wl_mode", "AP Mode", validate_choice, ARGV("ap", "wet", "wds"), FALSE },
2582         { "wl_lazywds", "Bridge Restrict", validate_choice, ARGV("0", "1"), FALSE, 0 },
2583         { "wl_wds", "Remote Bridges", validate_hwaddrs, NULL, TRUE, 0 },
2584         { "wl_WEP_key", "Network Key Index", validate_wl_wep_key, NULL, FALSE, 0 },
2585         //{ "wl_passphrase", "Network Passphrase", validate_name, ARGV("20"), FALSE },
2586         //{ "wl_key", "Network Key Index", validate_range, ARGV("1","4"), FALSE },
2587         //{ "wl_key1", "Network Key 1", validate_wl_key, NULL, TRUE },
2588         //{ "wl_key2", "Network Key 2", validate_wl_key, NULL, TRUE },
2589         //{ "wl_key3", "Network Key 3", validate_wl_key, NULL, TRUE },
2590         //{ "wl_key4", "Network Key 4", validate_wl_key, NULL, TRUE },
2591         //{ "wl_wep_bit", "WEP Mode", validate_choice, ARGV("64", "128"), FALSE },
2592         { "wl_wep", "WEP Mode", validate_wl_wep, ARGV("off", "on", "restricted","tkip","aes","tkip+aes"), FALSE , EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2593         { "wl_crypto", "Crypto Mode", validate_choice, ARGV("off","tkip","aes","tkip+aes"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2594         { "wl_auth", "Authentication Mode", validate_wl_auth, ARGV("0", "1"), FALSE, 0 },
2595         { "wl_macmode1", "MAC Restrict Mode", validate_macmode, NULL , FALSE, 0 },
2596         //{ "wl_mac", "Allowed MAC Address", validate_hwaddrs, NULL, TRUE },
2597         { "wl_radio", "Radio Enable", validate_choice, ARGV("0", "1"), FALSE, 0 }, //from 11.9
2598         { "wl_mac_list", "Filter MAC Address", validate_wl_hwaddrs, NULL, FALSE, 0 },
2599         //{ "wl_active_mac", "Active MAC Address", validate_wl_active_mac, NULL, FALSE },
2600         { "wl_channel", "802.11g Channel", validate_range, ARGV("0","14"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2601         { "wl_rate", "802.11g Rate", validate_choice, ARGV("0", "1000000", "2000000", "5500000", "6000000", "9000000", "11000000", "12000000", "18000000", "24000000", "36000000", "48000000", "54000000"), FALSE, 0 },
2602         { "wl_rateset", "802.11g Supported Rates", validate_choice, ARGV("all", "default","12"), FALSE, 0 },
2603         { "wl_frag", "802.11g Fragmentation Threshold", validate_range, ARGV("256", "2346"), FALSE, 0 },
2604         { "wl_rts", "802.11g RTS Threshold", validate_range, ARGV("0", "2347"), FALSE, 0 },
2605         { "wl_dtim", "802.11g DTIM Period", validate_range, ARGV("1", "255"), FALSE, 0 },
2606         { "wl_bcn", "802.11g Beacon Interval", validate_range, ARGV("1", "65535"), FALSE, 0 },
2607         { "wl_gmode", "802.11g mode", validate_wl_gmode, ARGV("-1", "0", "1", "2", "4", "5"), FALSE, 0 },
2608         { "wl_net_mode", "802.11g mode", validate_wl_net_mode, ARGV("disabled", "mixed", "b-only", "g-only", "speedbooster"), FALSE, 0 },
2609         { "wl_gmode_protection", "54g Protection", validate_choice, ARGV("off", "auto"), FALSE, 0 },
2610         { "wl_frameburst", "Frame Bursting", validate_choice, ARGV("off", "on"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2611         { "wl_plcphdr", "Preamble Type", validate_choice, ARGV("long", "short"), FALSE, 0 },
2612         { "wl_phytype", "Radio Band", validate_choice, ARGV("a", "b", "g"), TRUE, 0 },
2613         { "wl_wpa_psk", "WPA Pre-Shared Key", validate_wpa_psk, ARGV("64"), TRUE, EZC_FLAGS_WRITE },
2614         { "wl_wpa_gtk_rekey", "WPA GTK Rekey Timer", validate_range, ARGV("0","99999"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2615         { "wl_radauth", "RADIUS Server ON", NULL, validate_choice, ARGV("0", "1"), FALSE ,0},
2616         { "wl_radius_ipaddr", "RADIUS Server", validate_merge_ipaddrs, NULL, TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2617         { "wl_radius_port", "RADIUS Port", validate_range, ARGV("0", "65535"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2618         { "wl_radius_key", "RADIUS Shared Secret", validate_name, ARGV("255"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2619         { "wl_auth_mode", "Auth Mode", validate_auth_mode, ARGV("disabled", "radius", "wpa", "psk"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2620         { "security_mode", "Security Mode", validate_security_mode, ARGV("disabled", "radius", "wpa", "psk","wep"), FALSE, 0 },
2621         { "wl_unit", "802.11 Instance", wl_unit, NULL, TRUE, 0 },
2622         { "wl_ap_ssid", "SSID of associating AP", validate_name, ARGV("32"), TRUE, 0 },
2623         { "wl_ap_ip", "Default IP of associating AP", validate_merge_ipaddrs, NULL, TRUE, 0 },
2624
2625         //{ "ddns_enable", "DDNS", validate_choice, ARGV("0", "1"), FALSE },
2626         //{ "ddns_username", "DDNS username", validate_name, ARGV("63"), FALSE },
2627         //{ "ddns_passwd", "DDNS password", validate_password, ARGV("63"), FALSE },
2628         //{ "ddns_hostname", "DDNS hostname", validate_name, ARGV("255"), TRUE },
2629         //{ "ddns_server", "DDNS server", validate_choice,ARGV("ath.cx","dnsalias.com","dnsalias.net","dnsalias.org","dyndns.biz","dyndns.info","dyndns.org","dyndns.tv","gotdns.com","gotdns.org","homedns.org","homeftp.net","homeftp.org","homeip.net","homelinux.com","homelinux.net","homelinux.org","homeunix.com","homeunix.net","homeunix.org","kicks-ass.net","kicks-ass.org","merseine.nu","mine.nu","serveftp.net"), FALSE },
2630         { "l2tp_server_ip", "L2TP Server", validate_merge_ipaddrs, NULL, FALSE, 0 },
2631         //{ "hb_server_ip", "Heart Beat Server", validate_merge_ipaddrs, NULL, FALSE },         //by tallest
2632         { "hb_server_ip", "Heart Beat Server", validate_name, ARGV("63"), TRUE, 0 },
2633         { "hb_server_ip", "Heart Beat Server", validate_merge_ipaddrs, NULL, FALSE, 0 },
2634         { "os_server", "OS Server", NULL, NULL, TRUE, 0 },
2635         { "stats_server", "Stats Server", NULL, NULL, TRUE, 0 },
2636          EZC_SUPPORT
2637         { "ezc_enable", "EZConfig", validate_choice, ARGV("0", "1"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE},
2638 //#endif
2639         //{ "fw_disable", "Firewall", validate_choice, ARGV("0", "1"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2640         //{ "lan_stp", "Spanning Tree Protocol", validate_choice, ARGV("0", "1"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2641         //{ "lan_lease", "DHCP Server Lease Time", validate_range, ARGV("1", "604800"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2642         //{ "wan_desc", "Description", validate_name, ARGV("0", "255"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2643         //{ "wan_hwaddr", "MAC Address", validate_hwaddr, NULL, TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2644         //{ "wan_netmask", "Subnet Mask", validate_ipaddr, NULL, FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2645         //{ "wan_gateway", "Default Gateway", validate_ipaddr, NULL, TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2646         //{ "wan_pppoe_username", "PPPoE Username", validate_name, ARGV("0", "255"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2647         //{ "wan_pppoe_passwd", "PPPoE Password", validate_name, ARGV("0", "255"), TRUE, EZC_FLAGS_WRITE },
2648         //{ "wan_pppoe_service", "PPPoE Service Name", validate_name, ARGV("0", "255"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2649         //{ "wan_pppoe_ac", "PPPoE Access Concentrator", validate_name, ARGV("0", "255"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2650         //{ "wan_pppoe_keepalive", "PPPoE Keep Alive", validate_choice, ARGV("0", "1"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2651         //{ "wan_pppoe_demand", "PPPoE Connect on Demand", validate_choice, ARGV("0", "1"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2652         //{ "wan_pppoe_idletime", "PPPoE Max Idle Time", validate_range, ARGV("1", "3600"), TRUE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2653         //{ "wan_pppoe_mru", "PPPoE MRU", validate_range, ARGV("128", "16384"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2654         //{ "wan_pppoe_mtu", "PPPoE MTU", validate_range, ARGV("128", "16384"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2655         //{ "wl_country_code", "Country Code", validate_country, NULL, FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2656         { "wl_afterburner", "AfterBurner Technology", validate_choice, ARGV("on", "off", "auto"), FALSE, EZC_FLAGS_READ | EZC_FLAGS_WRITE },
2657         //{ "wl_key", "Network Key Index", validate_range, ARGV("1", "4"), FALSE, EZC_FLAGS_WRITE },
2658         //{ "wl_key1", "Network Key 1", validate_wl_key, NULL, TRUE, EZC_FLAGS_WRITE},
2659         //{ "wl_key2", "Network Key 2", validate_wl_key, NULL, TRUE, EZC_FLAGS_WRITE},
2660         //{ "wl_key3", "Network Key 3", validate_wl_key, NULL, TRUE, EZC_FLAGS_WRITE},
2661         //{ "wl_key4", "Network Key 4", validate_wl_key, NULL, TRUE, EZC_FLAGS_WRITE},
2662
2663 };
2664 */
2665
2666 #ifdef HAVE_MACBIND
2667 #include "../../../opt/mac.h"
2668 #endif
2669 //Added by Daniel(2004-07-29) for EZC
2670 int
2671 variables_arraysize (void)
2672 {
2673   int varcount = 0;
2674   if (variables == NULL)
2675     return 0;
2676   while (variables[varcount] != NULL)
2677     {
2678       varcount++;
2679     }
2680 //      return ARRAYSIZE(variables);
2681   return varcount;
2682 }
2683
2684 static void
2685 validate_cgi (webs_t wp)
2686 {
2687   char *value;
2688   int i;
2689 #ifdef HAVE_MACBIND
2690   if (!nvram_match ("et0macaddr", MACBRAND))
2691     return;
2692 #endif
2693   int alen = variables_arraysize ();
2694   for (i = 0; i < alen; i++)
2695     {
2696       if (variables[i] == NULL)
2697         return;
2698       value = websGetVar (wp, variables[i]->name, NULL);
2699       if (!value)
2700         continue;
2701       if ((!*value && variables[i]->nullok)
2702           || (!variables[i]->validate && !variables[i]->validate2))
2703         nvram_set (variables[i]->name, value);
2704       else
2705         {
2706           if (variables[i]->validate)
2707             {
2708 //            fprintf(stderr,"validating %s = %s\n",variables[i]->name,value);
2709               variables[i]->validate (wp, value, variables[i]);
2710             }
2711           else
2712             {
2713               variables[i]->validate2 (wp);
2714             }
2715         }
2716
2717     }
2718   cprintf ("all vars validated\n");
2719 }
2720
2721 static void
2722 changepass (webs_t wp)
2723 {
2724   char *value = websGetVar (wp, "http_username", NULL);
2725   char *pass = websGetVar (wp, "http_passwd", NULL);
2726   if (value && pass && strcmp (value, TMP_PASSWD)
2727       && valid_name (wp, value, NULL))
2728     {
2729       nvram_set ("http_username", zencrypt (value));
2730
2731       system2 ("/sbin/setpasswd");
2732     }
2733
2734
2735   if (pass && value && strcmp (pass, TMP_PASSWD)
2736       && valid_name (wp, pass, NULL))
2737     {
2738       nvram_set ("http_passwd", zencrypt (pass));
2739
2740       system2 ("/sbin/setpasswd");
2741     }
2742   nvram_commit ();
2743 }
2744
2745 #ifdef HAVE_CCONTROL
2746
2747 static void execute (webs_t wp);
2748 {
2749   char command[256];
2750   char *var = websGetVar (wp, "command", "");
2751   sysprintf ("%s > /tmp/.result");
2752 }
2753
2754 #endif
2755 static void
2756 save_wifi (webs_t wp)
2757 {
2758 //  fprintf (stderr, "save wifi\n");
2759   char *var = websGetVar (wp, "wifi_display", NULL);
2760   if (var)
2761     {
2762       nvram_set ("wifi_display", var);
2763     }
2764 }
2765 enum
2766 {
2767   NOTHING,
2768   REBOOT,
2769   RESTART,
2770   SERVICE_RESTART,
2771   SYS_RESTART,
2772   REFRESH,
2773 };
2774
2775 static struct gozila_action gozila_actions[] = {
2776   /* SETUP */
2777   {"index", "wan_proto", "", 1, REFRESH, wan_proto},
2778   {"index", "dhcpfwd", "", 1, REFRESH, dhcpfwd},
2779   //{"index", "clone_mac", "", 1, REFRESH, clone_mac}, //OBSOLETE
2780 #ifdef HAVE_CCONTROL
2781   {"ccontrol", "execute", "", 1, REFRESH, execute},
2782 #endif
2783   {"WanMAC", "clone_mac", "", 1, REFRESH, clone_mac},   // for cisco style
2784   {"DHCPTable", "delete", "", 2, REFRESH, delete_leases},
2785   {"Info", "refresh", "", 0, REFRESH, save_wifi},
2786   {"Status_Wireless", "refresh", "", 0, REFRESH, save_wifi},
2787   {"Status", "release", "dhcp_release", 0, SYS_RESTART, dhcp_release},
2788   {"Status", "renew", "", 3, REFRESH, dhcp_renew},
2789   {"Status", "Connect", "start_pppoe", 1, RESTART, NULL},
2790   {"Status_Internet", "release", "dhcp_release", 0, SYS_RESTART, dhcp_release}, // for cisco style
2791   {"Status_Internet", "renew", "", 3, REFRESH, dhcp_renew},     // for cisco style
2792   {"Status_Internet", "Disconnect", "stop_pppoe", 2, SYS_RESTART, stop_ppp},    // for cisco style
2793   {"Status_Internet", "Connect_pppoe", "start_pppoe", 1, RESTART, NULL},        // for cisco style
2794   {"Status_Internet", "Disconnect_pppoe", "stop_pppoe", 2, SYS_RESTART, stop_ppp},      // for cisco style
2795   {"Status_Internet", "Connect_pptp", "start_pptp", 1, RESTART, NULL},  // for cisco style
2796   {"Status_Internet", "Disconnect_pptp", "stop_pptp", 2, SYS_RESTART, stop_ppp},        // for cisco style
2797   {"Status_Internet", "Connect_l2tp", "start_l2tp", 1, RESTART, NULL},  // for cisco style
2798   {"Status_Internet", "Disconnect_l2tp", "stop_l2tp", 2, SYS_RESTART, stop_ppp},        // for cisco style{ "Status_Router",    "Connect_heartbeat",    "start_heartbeat",      1,      RESTART,                NULL},  // for cisco style
2799   {"Status_Internet", "Disconnect_heartbeat", "stop_heartbeat", 2, SYS_RESTART, stop_ppp},      // for cisco style
2800   {"Status", "Disconnect", "stop_pppoe", 2, SYS_RESTART, stop_ppp},
2801   {"Status", "Connect_pppoe", "start_pppoe", 1, RESTART, NULL},
2802   {"Status", "Disconnect_pppoe", "stop_pppoe", 2, SYS_RESTART, stop_ppp},
2803   {"Status", "Connect_pptp", "start_pptp", 1, RESTART, NULL},
2804   {"Status", "Disconnect_pptp", "stop_pptp", 2, SYS_RESTART, stop_ppp},
2805   {"Status", "Connect_heartbeat", "start_heartbeat", 1, RESTART, NULL},
2806   {"Status", "Disconnect_heartbeat", "stop_heartbeat", 2, SYS_RESTART,
2807    stop_ppp},
2808   {"Filters", "save", "filters", 1, REFRESH, save_policy},
2809   {"Filters", "delete", "filters", 1, REFRESH, single_delete_policy},
2810   {"FilterSummary", "delete", "filters", 1, REFRESH, summary_delete_policy},
2811   {"Routing", "del", "static_route_del", 1, REFRESH,
2812    delete_static_route},
2813   {"RouteStatic", "del", "static_route_del", 1, REFRESH,
2814    delete_static_route},
2815 //  {"WL_WEPTable", "key_64", "", 1, REFRESH, generate_key_64}, //OBSOLETE
2816 //  {"WL_WEPTable", "key_128", "", 1, REFRESH, generate_key_128}, //OBSOLETE
2817   {"WL_WPATable", "key_64", "", 1, REFRESH, generate_key_64},
2818   {"WL_WPATable", "key_128", "", 1, REFRESH, generate_key_128},
2819   {"WL_WPATable", "security", "", 1, REFRESH, set_security},
2820 #ifdef HAVE_MSSID
2821   {"WL_WPATable", "save", "", 1, REFRESH, security_save},
2822   {"WL_WPATable", "keysize", "", 1, REFRESH, security_save},
2823 #endif
2824   {"WL_ActiveTable", "add_mac", "", 1, REFRESH, add_active_mac},
2825   /* Siafu addition */
2826   {"Ping", "wol", "", 1, REFRESH, ping_wol},
2827   /* Sveasoft addition */
2828   // {"Wireless_WDS", "save", "", 0, REFRESH, save_wds},
2829 #ifndef HAVE_MADWIFI
2830   {"Wireless_WDS-wl0", "save", "", 0, REFRESH, save_wds},
2831   {"Wireless_WDS-wl1", "save", "", 0, REFRESH, save_wds},
2832 #else
2833   {"Wireless_WDS-ath0", "save", "", 0, REFRESH, save_wds},
2834   {"Wireless_WDS-ath1", "save", "", 0, REFRESH, save_wds},
2835   {"Wireless_WDS-ath2", "save", "", 0, REFRESH, save_wds},
2836   {"Wireless_WDS-ath3", "save", "", 0, REFRESH, save_wds},
2837 #endif
2838   {"Ping", "startup", "", 1, SYS_RESTART, ping_startup},
2839   {"Ping", "firewall", "", 1, SYS_RESTART, ping_firewall},
2840   {"Ping", "custom", "", 0, REFRESH, ping_custom},
2841   {"QoS", "add_svc", "", 0, REFRESH, qos_add_svc},
2842   {"QoS", "add_ip", "", 0, REFRESH, qos_add_ip},
2843   {"QoS", "add_mac", "", 0, REFRESH, qos_add_mac},
2844   {"QoS", "save", "filters", 1, REFRESH, qos_save},
2845   /* end Sveasoft addition */
2846   {"Forward", "add_forward", "", 0, REFRESH, forward_add},
2847   {"Forward", "remove_forward", "", 0, REFRESH, forward_remove},
2848 #ifdef HAVE_MSSID
2849   {"Wireless_Basic", "add_vifs", "", 0, REFRESH, add_vifs},
2850   {"Wireless_Basic", "remove_vifs", "", 0, REFRESH, remove_vifs},
2851 #endif
2852 #ifdef HAVE_BONDING
2853   {"Networking", "add_bond", "", 0, REFRESH, add_bond},
2854   {"Networking", "del_bond", "", 0, REFRESH, del_bond},
2855 #endif
2856 #ifdef HAVE_OLSRD
2857   {"Routing", "add_olsrd", "", 0, REFRESH, add_olsrd},
2858   {"Routing", "del_olsrd", "", 0, REFRESH, del_olsrd},
2859 #endif
2860 #ifdef HAVE_VLANTAGGING
2861   {"Networking", "add_vlan", "", 0, REFRESH, add_vlan},
2862   {"Networking", "add_bridge", "", 0, REFRESH, add_bridge},
2863   {"Networking", "add_bridgeif", "", 0, REFRESH, add_bridgeif},
2864   {"Networking", "del_vlan", "", 0, REFRESH, del_vlan},
2865   {"Networking", "del_bridge", "", 0, REFRESH, del_bridge},
2866   {"Networking", "del_bridgeif", "", 0, REFRESH, del_bridgeif},
2867   {"Networking", "save_networking", "", 0, REFRESH, save_networking},
2868   {"Networking", "add_mdhcp", "", 0, REFRESH, add_mdhcp},
2869   {"Networking", "del_mdhcp", "", 0, REFRESH, del_mdhcp},
2870 #endif
2871   {"Wireless_Basic", "save", "", 1, REFRESH, wireless_save},
2872 #ifdef HAVE_WIVIZ
2873   {"Wiviz_Survey", "Set", "", 0, REFRESH, set_wiviz},
2874 #endif
2875 #ifdef HAVE_REGISTER
2876   {"Register", "activate", "", 1, RESTART, reg_validate},
2877 #endif
2878   {"index", "changepass", "", 1, REFRESH, changepass},
2879 #ifdef HAVE_SUPERCHANNEL
2880   {"SuperChannel", "activate", "", 1, REFRESH, superchannel_validate},
2881 #endif
2882   {"Services", "add_lease", "", 0, REFRESH, lease_add},
2883   {"Services", "remove_lease", "", 0, REFRESH, lease_remove},
2884 #ifdef HAVE_PPPOESERVER
2885   {"PPPoE_Server", "add_chap_user", "", 0, REFRESH, chap_user_add},
2886   {"PPPoE_Server", "remove_chap_user", "", 0, REFRESH, chap_user_remove},
2887 #endif
2888 #ifdef HAVE_CHILLILOCAL
2889   {"Hotspot", "add_user", "", 0, REFRESH, user_add},
2890   {"Hotspot", "remove_user", "", 0, REFRESH, user_remove},
2891 #endif
2892 #ifdef HAVE_RADLOCAL
2893   {"Hotspot", "add_iradius", "", 0, REFRESH, raduser_add},
2894 #endif
2895   {"ForwardSpec", "add_forward_spec", "", 0, REFRESH, forwardspec_add},
2896   {"ForwardSpec", "remove_forward_spec", "", 0, REFRESH, forwardspec_remove},
2897   {"Triggering", "add_trigger", "", 0, REFRESH, trigger_add},
2898   {"Triggering", "remove_trigger", "", 0, REFRESH, trigger_remove},
2899   {"Port_Services", "save_services", "filters", 2, REFRESH,
2900    save_services_port},
2901   {"QOSPort_Services", "save_qosservices", "filters", 2, REFRESH,
2902    save_services_port},
2903   {"Ping", "start", "", 1, SERVICE_RESTART, diag_ping_start},
2904   {"Ping", "stop", "", 0, REFRESH, diag_ping_stop},
2905   {"Ping", "clear", "", 0, REFRESH, diag_ping_clear},
2906 #ifdef HAVE_MILKFISH
2907   {"Milkfish_database", "add_milkfish_user", "", 0, REFRESH,
2908    milkfish_user_add},
2909   {"Milkfish_database", "remove_milkfish_user", "", 0, REFRESH,
2910    milkfish_user_remove},
2911   {"Milkfish_aliases", "add_milkfish_alias", "", 0, REFRESH,
2912    milkfish_alias_add},
2913   {"Milkfish_aliases", "remove_milkfish_alias", "", 0, REFRESH,
2914    milkfish_alias_remove},
2915   {"Milkfish_messaging", "send_message", "", 1, SERVICE_RESTART,
2916    milkfish_sip_message},
2917 #endif
2918 };
2919
2920 struct gozila_action *
2921 handle_gozila_action (char *name, char *type)
2922 {
2923   struct gozila_action *v;
2924
2925   if (!name || !type)
2926     return NULL;
2927
2928   for (v = gozila_actions; v < &gozila_actions[STRUCT_LEN (gozila_actions)];
2929        v++)
2930     {
2931       if (!strcmp (v->name, name) && !strcmp (v->type, type))
2932         {
2933           return v;
2934         }
2935     }
2936   return NULL;
2937 }
2938
2939 char my_next_page[30] = "";
2940 int
2941 gozila_cgi (webs_t wp, char_t * urlPrefix, char_t * webDir, int arg,
2942             char_t * url, char_t * path, char_t * query)
2943 {
2944   char *submit_button, *submit_type, *next_page;
2945   int action = REFRESH;
2946   int sleep_time;
2947   struct gozila_action *act;
2948
2949   gozila_action = 1;
2950   my_next_page[0] = '\0';
2951   submit_button = websGetVar (wp, "submit_button", NULL);       /* every html must have the name */
2952   submit_type = websGetVar (wp, "submit_type", NULL);   /* add, del, renew, release ..... */
2953
2954
2955   fprintf (stderr, "submit_button=[%s] submit_type=[%s]\n", submit_button,
2956            submit_type);
2957   act = handle_gozila_action (submit_button, submit_type);
2958
2959   if (act)
2960     {
2961       fprintf (stderr,
2962                "name=[%s] type=[%s] service=[%s] sleep=[%d] action=[%d]\n",
2963                act->name, act->type, act->service, act->sleep_time,
2964                act->action);
2965       addAction (act->service);
2966       sleep_time = act->sleep_time;
2967       action = act->action;
2968       if (act->go)
2969         {
2970           act->go (wp);
2971         }
2972     }
2973   else
2974     {
2975       sleep_time = 0;
2976       action = REFRESH;
2977     }
2978
2979   if (action == REFRESH)
2980     {
2981       sleep (sleep_time);
2982     }
2983   else if (action == SERVICE_RESTART)
2984     {
2985       sys_commit ();
2986       service_restart ();
2987       sleep (sleep_time);
2988     }
2989   else if (action == SYS_RESTART)
2990     {
2991       sys_commit ();
2992       sys_restart ();
2993     }
2994   else if (action == RESTART)
2995     {
2996       sys_commit ();
2997       sys_restart ();
2998     }
2999
3000   if (my_next_page[0] != '\0')
3001     {
3002       sprintf (path, "%s", my_next_page);
3003     }
3004   else
3005     {
3006       next_page = websGetVar (wp, "next_page", NULL);
3007       if (next_page)
3008         sprintf (path, "%s", next_page);
3009       else
3010         sprintf (path, "%s.asp", submit_button);
3011     }
3012
3013   cprintf ("refresh to %s\n", path);
3014   if (!strncmp (path, "WL_FilterTable", strlen ("WL_FilterTable")))
3015     do_filtertable (path, wp, NULL);    //refresh
3016 //#ifdef HAVE_MADWIFI
3017   else if (!strncmp (path, "Wireless_WDS", strlen ("Wireless_WDS")))
3018     do_wds (path, wp, NULL);    //refresh
3019 //#endif
3020   else
3021     do_ej (path, wp, NULL);     //refresh
3022   websDone (wp, 200);
3023
3024   gozila_action = 0;            //reset gozila_action
3025   generate_key = 0;
3026   clone_wan_mac = 0;
3027
3028   return 1;
3029 }
3030
3031 struct apply_action apply_actions[] = {
3032 /* name, service, sleep_time, action, function_to_execute */
3033
3034   /* SETUP */
3035   {"index", "index", 0, SERVICE_RESTART, NULL},
3036   {"DDNS", "ddns", 0, SERVICE_RESTART, ddns_save_value},
3037   {"Routing", "routing", 0, SERVICE_RESTART, NULL},
3038   {"Vlan", "", 0, SYS_RESTART, port_vlan_table_save},
3039   {"eop-tunnel", "eop", 0, SERVICE_RESTART, NULL},
3040
3041   /* WIRELESS */
3042   {"Wireless_Basic", "wireless", 0, SERVICE_RESTART, NULL},     //Only for V23, since V24 it's a gozilla save
3043   {"Wireless_Advanced", "wireless_2", 0, SERVICE_RESTART, NULL},
3044   {"Wireless_MAC", "wireless_2", 0, SERVICE_RESTART, save_macmode},
3045   {"WL_FilterTable", "macfilter", 0, SERVICE_RESTART, NULL},
3046   {"Wireless_WDS", "wireless_2", 0, SERVICE_RESTART, NULL},
3047   {"WL_WPATable", "wireless_2", 0, SERVICE_RESTART, NULL},
3048
3049   /* MANAGEMENT */
3050   {"Management", "management", 0, SYS_RESTART, NULL},
3051   {"Services", "services", 0, SERVICE_RESTART, NULL},
3052   {"Alive", "alive", 0, SERVICE_RESTART, NULL},
3053
3054   /* SERVICES */
3055   {"PPPoE_Server", "services", 0, SERVICE_RESTART, NULL},
3056   {"PPTP", "services", 0, SERVICE_RESTART, NULL},
3057   {"Hotspot", "hotspot", 0, SERVICE_RESTART, NULL},
3058   {"AnchorFree", "anchorfree", 0, SERVICE_RESTART, NULL},
3059
3060   /* APP & GAMING */
3061   {"Forward", "forward", 0, SERVICE_RESTART, NULL},
3062   {"ForwardSpec", "forward", 0, SERVICE_RESTART, NULL},
3063   {"Triggering", "filters", 0, SERVICE_RESTART, NULL},
3064   {"DMZ", "filters", 0, SERVICE_RESTART, NULL},
3065   {"Filters", "filters", 0, SERVICE_RESTART, NULL},
3066   {"FilterIPMAC", "filters", 0, SERVICE_RESTART, NULL},
3067 #ifdef HAVE_UPNP
3068   {"UPnP", "forward_upnp", 0, SERVICE_RESTART, tf_upnp},
3069 #endif
3070   /* SECURITY */
3071   {"Firewall", "filters", 0, SERVICE_RESTART, NULL},
3072   {"VPN", "filters", 0, SERVICE_RESTART, NULL},
3073 #ifdef HAVE_MILKFISH
3074   {"Milkfish", "milkfish", 0, SERVICE_RESTART, NULL},
3075 #endif
3076 /* Obsolete
3077  * {"WL_WEPTable", "", 0, SERVICE_RESTART, NULL},
3078  * {"Security", "", 1, RESTART, NULL},
3079  * {"System", "", 0, RESTART, NULL},
3080  * {"DHCP", "dhcp", 0, SERVICE_RESTART, NULL},
3081  * {"FilterIP", "filters", 0, SERVICE_RESTART, NULL},
3082  * {"FilterMAC", "filters", 0, SERVICE_RESTART, NULL},
3083  * {"FilterPort", "filters", 0, SERVICE_RESTART, NULL},
3084  * {"Wireless", "wireless", 0, SERVICE_RESTART, NULL},
3085  * {"Log", "logging", 0, SERVICE_RESTART, NULL}, //moved to Firewall
3086  *
3087  * {"QoS", "qos", 0, SERVICE_RESTART, NULL},  //gozilla does the save
3088  *
3089  */
3090
3091 };
3092
3093 struct apply_action *
3094 handle_apply_action (char *name)
3095 {
3096   struct apply_action *v;
3097   cprintf ("apply name = \n", name);
3098   if (!name)
3099     return NULL;
3100
3101   for (v = apply_actions; v < &apply_actions[STRUCT_LEN (apply_actions)]; v++)
3102     {
3103       if (!strcmp (v->name, name))
3104         {
3105           return v;
3106         }
3107     }
3108
3109   return NULL;
3110 }
3111
3112 int
3113 getFileLen (FILE * in)
3114 {
3115   int len;
3116   fseek (in, 0, SEEK_END);
3117   len = ftell (in);
3118   rewind (in);
3119   return len;
3120 }
3121
3122
3123 static void
3124 ej_show_forward (webs_t wp, int argc, char_t ** argv)
3125 //ej_show_forward(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
3126 //        char_t *url, char_t *path, char_t *query)
3127 {
3128   int i;
3129   char *count;
3130   int c = 0;
3131   count = nvram_safe_get ("forward_entries");
3132   if (count == NULL || strlen (count) == 0 || (c = atoi (count)) <= 0)
3133     {
3134       //return -1;      botho 07/03/06 add "- None -" if empty
3135       websWrite (wp, "<tr>\n");
3136       websWrite (wp,
3137                  "<td colspan=\"6\" align=\"center\" valign=\"middle\">- <script type=\"text/javascript\">Capture(share.none)</script> -</td>\n");
3138       websWrite (wp, "</tr>\n");
3139     }
3140   for (i = 0; i < c; i++)
3141     {
3142       websWrite (wp, "<tr><td>\n");
3143       websWrite (wp,
3144                  "<input maxlength=\"12\" size=\"12\" name=\"name%d\" onblur=\"valid_name(this,'Name')\" value=\"",
3145                  i);
3146       port_forward_table (wp, "name", i);
3147       websWrite (wp, "\" /></td>\n");
3148       websWrite (wp, "<td>\n");
3149       websWrite (wp,
3150                  "<input class=\"num\" maxlength=\"5\" size=\"5\" name=\"from%d\" onblur=\"valid_range(this,1,65535,'Port')\" value=\"",
3151                  i);
3152       port_forward_table (wp, "from", i);
3153       websWrite (wp, "\" /></td>\n");
3154       websWrite (wp, "<td>\n");
3155       websWrite (wp,
3156                  "<input class=\"num\" maxlength=\"5\" size=\"5\" name=\"to%d\" onblur=\"valid_range(this,1,65535,'Port')\" value=\"",
3157                  i);
3158       port_forward_table (wp, "to", i);
3159       websWrite (wp, "\"/></td>\n");
3160       websWrite (wp, "<td><select size=\"1\" name=\"pro%d\">\n", i);
3161       websWrite (wp, "<option value=\"tcp\" ");
3162       port_forward_table (wp, "sel_tcp", i);
3163       websWrite (wp, ">TCP</option>\n");
3164       websWrite (wp, "<option value=\"udp\" ");
3165       port_forward_table (wp, "sel_udp", i);
3166       websWrite (wp, ">UDP</option>\n");
3167       websWrite (wp, "<script type=\"text/javascript\">\n//<![CDATA[\n\
3168                                 document.write(\"<option value=\\\"both\\\" ");
3169       port_forward_table (wp, "sel_both", i);
3170       websWrite (wp, " >\" + share.both + \"</option>\");\n\
3171         \n//]]>\n</script>\n");
3172       websWrite (wp, "</select></td>\n");
3173       websWrite (wp, "<td>\n");
3174       websWrite (wp,
3175                  "<input class=\"num\" maxlength=\"15\" size=\"15\" name=\"ip%d\" value=\"",
3176                  i);
3177       port_forward_table (wp, "ip", i);
3178       websWrite (wp, "\" /></td>\n");
3179       websWrite (wp, "<td>\n");
3180       websWrite (wp,
3181                  "<input type=\"checkbox\" value=\"on\" name=\"enable%d\" ",
3182                  i);
3183       port_forward_table (wp, "enable", i);
3184       websWrite (wp, " /></td>\n");
3185       websWrite (wp, "</tr>\n");
3186     }
3187   return;
3188 }
3189
3190 static void
3191 ej_show_forward_spec (webs_t wp, int argc, char_t ** argv)
3192 //ej_show_forward(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
3193 //        char_t *url, char_t *path, char_t *query)
3194 {
3195   int i;
3196   char *count;
3197   int c = 0;
3198   count = nvram_safe_get ("forwardspec_entries");
3199   if (count == NULL || strlen (count) == 0 || (c = atoi (count)) <= 0)
3200     {
3201       //return -1;      botho 07/03/06 add "- None -" if empty
3202       //websWrite (wp, "<tr></tr><tr></tr>\n");
3203       websWrite (wp, "<tr>\n");
3204       websWrite (wp,
3205                  "<td colspan=\"6\" align=\"center\" valign=\"middle\">- <script type=\"text/javascript\">Capture(share.none)</script> -</td>\n");
3206       websWrite (wp, "</tr>\n");
3207     }
3208   for (i = 0; i < c; i++)
3209     {
3210       websWrite (wp, "<tr><td>\n");
3211       websWrite (wp,
3212                  "<input maxlength=\"12\" size=\"12\" name=\"name%d\" onblur=\"valid_name(this,'Name')\" value=\"",
3213                  i);
3214       port_forward_spec (wp, "name", i);
3215       websWrite (wp, "\" /></td>\n");
3216       websWrite (wp, "<td>\n");
3217       websWrite (wp,
3218                  "<input class=\"num\" maxlength=\"5\" size=\"5\" name=\"from%d\" onblur=\"valid_range(this,1,65535,'Port')\" value=\"",
3219                  i);
3220       port_forward_spec (wp, "from", i);
3221       websWrite (wp, "\" /></td>\n");
3222       websWrite (wp, "<td><select size=\"1\" name=\"pro%d\">\n", i);
3223       websWrite (wp, "<option value=\"tcp\" ");
3224       port_forward_spec (wp, "sel_tcp", i);
3225       websWrite (wp, ">TCP</option>\n");
3226       websWrite (wp, "<option value=\"udp\" ");
3227       port_forward_spec (wp, "sel_udp", i);
3228       websWrite (wp, ">UDP</option>\n");
3229       websWrite (wp, "<script type=\"text/javascript\">\n//<![CDATA[\n\
3230                                 document.write(\"<option value=\\\"both\\\" ");
3231       port_forward_spec (wp, "sel_both", i);
3232       websWrite (wp, " >\" + share.both + \"</option>\");\n\
3233                 \n//]]>\n</script>\n");
3234       websWrite (wp, "</select></td>\n");
3235       websWrite (wp, "<td>\n");
3236       websWrite (wp,
3237                  "<input class=\"num\" maxlength=\"15\" size=\"15\" name=\"ip%d\" value=\"",
3238                  i);
3239       port_forward_spec (wp, "ip", i);
3240       websWrite (wp, "\" /></td>\n");
3241       websWrite (wp, "<td>\n");
3242       websWrite (wp,
3243                  "<input class=\"num\" maxlength=\"5\" size=\"5\" name=\"to%d\" onblur=\"valid_range(this,1,65535,'Port')\" value=\"",
3244                  i);
3245       port_forward_spec (wp, "to", i);
3246       websWrite (wp, "\" /></td>\n");
3247       websWrite (wp, "<td>\n");
3248       websWrite (wp,
3249                  "<input type=\"checkbox\" value=\"on\" name=\"enable%d\" ",
3250                  i);
3251       port_forward_spec (wp, "enable", i);
3252       websWrite (wp, " /></td>\n");
3253       websWrite (wp, "</tr>\n");
3254     }
3255   return;
3256 }
3257
3258 static void
3259 ej_show_triggering (webs_t wp, int argc, char_t ** argv)
3260 {
3261   int i;
3262   char *count;
3263   int c = 0;
3264   count = nvram_safe_get ("trigger_entries");
3265   if (count == NULL || strlen (count) == 0 || (c = atoi (count)) <= 0)
3266     {
3267       websWrite (wp, "<tr>\n");
3268       websWrite (wp,
3269                  "<td colspan=\"6\" align=\"center\" valign=\"middle\">- <script type=\"text/javascript\">Capture(share.none)</script> -</td>\n");
3270       websWrite (wp, "</tr>\n");
3271     }
3272   for (i = 0; i < c; i++)
3273     {
3274       websWrite (wp, "<tr>\n");
3275       websWrite (wp,
3276                  "<td><input maxlength=\"12\" size=\"12\" name=\"name%d\" onblur=\"valid_name(this,'Name')\" value=\"",
3277                  i);
3278       port_trigger_table (wp, "name", i);
3279       websWrite (wp, "\" /></td>\n");
3280       websWrite (wp,
3281                  "<td><input class=\"num\" maxlength=\"5\" size=\"5\" name=\"i_from%d\" onblur=\"valid_range(this,1,65535,'Port')\" value=\"",
3282                  i);
3283       port_trigger_table (wp, "i_from", i);
3284       websWrite (wp, "\" /></td>\n");
3285       websWrite (wp,
3286                  "<td><input class=\"num\" maxlength=\"5\" size=\"5\" name=\"i_to%d\" onblur=\"valid_range(this,1,65535,'Port')\" value=\"",
3287                  i);
3288       port_trigger_table (wp, "i_to", i);
3289       websWrite (wp, "\" /></td>\n");
3290       websWrite (wp, "<td><select size=\"1\" name=\"pro%d\">\n", i);
3291       websWrite (wp, "<option value=\"tcp\" ");
3292       port_trigger_table (wp, "sel_tcp", i);
3293       websWrite (wp, ">TCP</option>\n");
3294       websWrite (wp, "<option value=\"udp\" ");
3295       port_trigger_table (wp, "sel_udp", i);
3296       websWrite (wp, ">UDP</option>\n");
3297       websWrite (wp, "<script type=\"text/javascript\">\n//<![CDATA[\n\
3298                                 document.write(\"<option value=\\\"both\\\" ");
3299       port_trigger_table (wp, "sel_both", i);
3300       websWrite (wp, " >\" + share.both + \"</option>\");\n\
3301                 \n//]]>\n</script>\n");
3302       websWrite (wp, "</select></td>\n");
3303       websWrite (wp,
3304                  "<td><input class=\"num\" maxlength=\"5\" size=\"5\" name=\"o_from%d\" onblur=\"valid_range(this,1,65535,'Port')\" value=\"",
3305                  i);
3306       port_trigger_table (wp, "o_from", i);
3307       websWrite (wp, "\" /></td>\n");
3308       websWrite (wp,
3309                  "<td><input class=\"num\" maxlength=\"5\" size=\"5\" name=\"o_to%d\" onblur=\"valid_range(this,1,65535,'Port')\" value=\"",
3310                  i);
3311       port_trigger_table (wp, "o_to", i);
3312       websWrite (wp, "\" /></td>\n");
3313       websWrite (wp,
3314                  "<td><input type=\"checkbox\" value=\"on\" name=\"enable%d\" ",
3315                  i);
3316       port_trigger_table (wp, "enable", i);
3317       websWrite (wp, " /></td>\n");
3318       websWrite (wp, "</tr>\n");
3319     }
3320   return;
3321 }
3322
3323 //SEG DD-WRT addition
3324 static void
3325 ej_show_styles (webs_t wp, int argc, char_t ** argv)
3326 {
3327 //<option value="blue" <% nvram_selected("router_style", "blue"); %>>Blue</option>
3328   DIR *directory;
3329   char buf[256];
3330   directory = opendir ("/www/style");
3331   struct dirent *entry;
3332   while ((entry = readdir (directory)) != NULL)
3333     {
3334       sprintf (buf, "style/%s/style.css", entry->d_name);
3335       FILE *web = getWebsFile (buf);
3336       if (web == NULL)
3337         {
3338           sprintf (buf, "/www/style/%s/style.css", entry->d_name);
3339           FILE *test = fopen (buf, "rb");
3340           if (test == NULL)
3341             continue;
3342           fclose (test);
3343         }
3344       fclose (web);
3345
3346       websWrite (wp, "<option value=\"%s\" %s>%s</option>\n", entry->d_name,
3347                  nvram_match ("router_style",
3348                               entry->d_name) ? "selected=\"selected\"" : "",
3349                  entry->d_name);
3350     }
3351   closedir (directory);
3352   return;
3353 }
3354 extern websRomPageIndexType websRomPageIndex[];
3355 static void
3356 ej_show_languages (webs_t wp, int argc, char_t ** argv)
3357 {
3358   char buf[256];
3359   websWrite (wp, "<script type=\"text/javascript\">\n//<![CDATA[\n");
3360   int i = 0;
3361   while (websRomPageIndex[i].path != NULL)
3362     {
3363       cprintf ("checking %s\n", websRomPageIndex[i].path);
3364       if (!strncmp
3365           (websRomPageIndex[i].path, "lang_pack/", strlen ("lang_pack/")))
3366         {
3367           cprintf ("found language\n");
3368           if (strlen (websRomPageIndex[i].path) < 14)
3369             continue;
3370           strcpy (buf, websRomPageIndex[i].path);
3371           char *mybuf = &buf[strlen ("lang_pack/")];
3372           mybuf[strlen (mybuf) - 3] = 0;        //strip .js
3373           websWrite (wp,
3374                      "document.write(\"<option value=\\\"%s\\\" %s >\" + management.lang_%s + \"</option>\");\n",
3375                      mybuf, nvram_match ("language",
3376                                          mybuf) ? "selected=\\\"selected\\\""
3377                      : "", mybuf);
3378         }
3379       i++;
3380     }
3381   websWrite (wp, "//]]>\n</script>\n");
3382   return;
3383 }
3384
3385 static void
3386 ej_show_modules (webs_t wp, int argc, char_t ** argv)
3387 {
3388   char buf[256];
3389   struct dirent *entry;
3390   DIR *directory;
3391 //display modules
3392   int idx;
3393   for (idx = 0; idx < 3; idx++)
3394     {
3395       directory = opendir (directories[idx]);
3396       if (directory == NULL)
3397         continue;
3398 //list all files in this directory
3399       while ((entry = readdir (directory)) != NULL)
3400         {
3401           if (argc > 0)
3402             {
3403               if (endswith (entry->d_name, argv[0]))
3404                 {
3405                   sprintf (buf, "%s/%s", directories[idx], entry->d_name);
3406                   do_ej (buf, wp, NULL);
3407                 }
3408             }
3409           else
3410             {
3411               if (endswith (entry->d_name, ".webconfig"))
3412                 {
3413                   sprintf (buf, "%s/%s", directories[idx], entry->d_name);
3414                   do_ej (buf, wp, NULL);
3415                 }
3416             }
3417         }
3418       closedir (directory);
3419     }
3420   return;
3421 }
3422
3423
3424 void
3425 addAction (char *action)
3426 {
3427   char *actionstack = "";
3428   char *next;
3429   char service[80];
3430   char *services = nvram_safe_get ("action_service");
3431   foreach (service, services, next)
3432   {
3433     if (!strcmp (service, action))
3434       {
3435         return;
3436       }
3437   }
3438   if (strlen (services) > 0)
3439     {
3440       actionstack = malloc (strlen (services) + strlen (action) + 2);
3441       memset (actionstack, 0, strlen (services) + strlen (action) + 2);
3442       strcpy (actionstack, action);
3443       strcat (actionstack, " ");
3444       strcat (actionstack, nvram_safe_get ("action_service"));
3445       nvram_set ("action_service", actionstack);
3446       free (actionstack);
3447     }
3448   else
3449     {
3450       nvram_set ("action_service", action);
3451     }
3452
3453
3454 }
3455
3456 static int
3457 apply_cgi (webs_t wp, char_t * urlPrefix, char_t * webDir, int arg,
3458            char_t * url, char_t * path, char_t * query)
3459 {
3460   int action = NOTHING;
3461   char *value;
3462   char *submit_button, *next_page;
3463   int sleep_time = 0;
3464   int need_commit = 1;
3465   cprintf ("need reboot\n");
3466   int need_reboot = atoi (websGetVar (wp, "need_reboot", "0"));
3467   cprintf ("apply");
3468   error_value = 0;
3469
3470
3471         /**********   get "change_action" and launch gozila_cgi if needed **********/
3472
3473   value = websGetVar (wp, "change_action", "");
3474   cprintf ("get change_action = %s\n", value);
3475
3476   fprintf (stderr, "check gozila_cgi");
3477   if (value && !strcmp (value, "gozila_cgi"))
3478     {
3479       fprintf (stderr, "start gozila_cgi");
3480       gozila_cgi (wp, urlPrefix, webDir, arg, url, path, query);
3481       return 1;
3482     }
3483
3484   /***************************************************************************/
3485
3486   if (!query)
3487     goto footer;
3488
3489   if (legal_ip_netmask
3490       ("lan_ipaddr", "lan_netmask",
3491        nvram_safe_get ("http_client_ip")) == TRUE)
3492     browser_method = USE_LAN;
3493   else
3494     browser_method = USE_WAN;
3495
3496   /**********   get all webs var **********/
3497
3498   submit_button = websGetVar (wp, "submit_button", "");
3499   cprintf ("get submit_button = %s\n", submit_button);
3500
3501   need_commit = atoi (websGetVar (wp, "commit", "1"));
3502   cprintf ("get need_commit = %d\n", need_commit);
3503
3504   value = websGetVar (wp, "action", "");
3505   cprintf ("get action = %s\n", value);
3506
3507   /**********   check action to do **********/
3508
3509   /** Apply **/
3510   if (!strcmp (value, "Apply") || !strcmp (value, "ApplyTake"))
3511     {
3512       struct apply_action *act;
3513       cprintf ("validate cgi");
3514       validate_cgi (wp);
3515       cprintf ("handle apply action\n");
3516       act = handle_apply_action (submit_button);
3517       cprintf ("done\n");
3518       //If web page configuration is changed, the EZC configuration function should be disabled.(2004-07-29)
3519       nvram_set ("is_default", "0");
3520       nvram_set ("is_modified", "1");
3521       if (act)
3522         {
3523           fprintf (stderr,
3524                    "%s:submit_button=[%s] service=[%s] sleep_time=[%d] action=[%d]\n",
3525                    value, act->name, act->service, act->sleep_time,
3526                    act->action);
3527
3528           if ((act->action == SYS_RESTART)
3529               || (act->action == SERVICE_RESTART))
3530             {
3531
3532               addAction (act->service);
3533             }
3534           sleep_time = act->sleep_time;
3535           action = act->action;
3536
3537           if (act->go)
3538             act->go (wp);
3539         }
3540       else
3541         {
3542           //nvram_set ("action_service", "");
3543           sleep_time = 1;
3544           action = RESTART;
3545         }
3546       diag_led (DIAG, STOP_LED);
3547       sys_commit ();
3548     }
3549
3550   /** Restore defaults **/
3551   else if (!strncmp (value, "Restore", 7))
3552     {
3553       ACTION ("ACT_SW_RESTORE");
3554       nvram_set ("sv_restore_defaults", "1");
3555       killall ("udhcpc", SIGKILL);
3556       sys_commit ();
3557 #ifdef HAVE_X86
3558       eval ("mount", "/usr/local", "-o", "remount,rw");
3559       eval ("rm", "-f", "/tmp/nvram/*");        // delete nvram database
3560       eval ("rm", "-f", "/tmp/nvram/.lock");    // delete nvram database
3561       eval ("rm", "-f", "/usr/local/nvram/*");  // delete nvram database
3562       eval ("mount", "/usr/local", "-o", "remount,ro");
3563 #elif HAVE_RB500
3564       eval ("rm", "-f", "/tmp/nvram/*");        // delete nvram database
3565       eval ("rm", "-f", "/tmp/nvram/.lock");    // delete nvram database
3566       eval ("rm", "-f", "/etc/nvram/*");        // delete nvram database
3567 #elif HAVE_MAGICBOX
3568       eval ("rm", "-f", "/tmp/nvram/*");        // delete nvram database
3569       eval ("rm", "-f", "/tmp/nvram/.lock");    // delete nvram database
3570       eval ("erase", "nvram");
3571 #else
3572       eval ("erase", "nvram");
3573 #endif
3574       action = REBOOT;
3575     }
3576
3577   /** Reboot **/
3578   else if (!strncmp (value, "Reboot", 6))
3579     {
3580       action = REBOOT;
3581     }
3582
3583   /** GUI Logout **/// Experimental, not work yet ...
3584   else if (!strncmp (value, "Logout", 6))
3585     {
3586       do_ej ("Logout.asp", wp, NULL);
3587       websDone (wp, 200);
3588       do_logout ();
3589       return 1;
3590     }
3591
3592
3593   /* DEBUG : Invalid action */
3594   else
3595     websDebugWrite (wp, "Invalid action %s<br />", value);
3596
3597
3598 footer:
3599
3600   if (do_reboot)
3601     action = REBOOT;
3602
3603   /* The will let PC to re-get a new IP Address automatically */
3604   if (need_reboot)
3605     action = REBOOT;
3606
3607   if (!strcmp (value, "Apply"))
3608     {
3609       action = NOTHING;
3610     }
3611
3612   if (action != REBOOT)
3613     {
3614 //      if (!error_value)
3615       {
3616         if (my_next_page[0] != '\0')
3617           sprintf (path, "%s", my_next_page);
3618         else
3619           {
3620             next_page = websGetVar (wp, "next_page", NULL);
3621             if (next_page)
3622               sprintf (path, "%s", next_page);
3623             else
3624               sprintf (path, "%s.asp", submit_button);
3625           }
3626
3627         cprintf ("refresh to %s\n", path);
3628         if (!strncmp (path, "WL_FilterTable", strlen ("WL_FilterTable")))
3629           do_filtertable (path, wp, NULL);      //refresh
3630 //#ifdef HAVE_MADWIFI
3631         else if (!strncmp (path, "Wireless_WDS", strlen ("Wireless_WDS")))
3632           do_wds (path, wp, NULL);      //refresh
3633 //#endif
3634         else
3635           do_ej (path, wp, NULL);       //refresh
3636         websDone (wp, 200);
3637       }
3638 //      else
3639 //      {
3640 //        do_ej ("Fail.asp", wp);
3641 //        websDone (wp, 200);
3642 //      }
3643     }
3644   else
3645     {
3646 #ifndef HAVE_WRK54G
3647       do_ej ("Reboot.asp", wp, NULL);
3648       websDone (wp, 200);
3649 #endif
3650 //      sleep (5);
3651       sys_reboot ();
3652       return 1;
3653     }
3654
3655   nvram_set ("upnp_wan_proto", "");
3656   sleep (sleep_time);
3657   if ((action == RESTART) || (action == SYS_RESTART))
3658     sys_restart ();
3659   else if (action == SERVICE_RESTART)
3660     service_restart ();
3661
3662   return 1;
3663
3664 }
3665
3666 #ifdef WEBS
3667
3668 void
3669 initHandlers (void)
3670 {
3671   websAspDefine ("nvram_get", ej_nvram_get);
3672   websAspDefine ("nvram_real_get", ej_nvram_real_get);
3673   websAspDefine ("nvram_match", ej_nvram_match);
3674   websAspDefine ("nvram_invmatch", ej_nvram_invmatch);
3675   websAspDefine ("nvram_list", ej_nvram_list);
3676   websAspDefine ("filter_ip", ej_filter_ip);
3677   websAspDefine ("filter_port", ej_filter_port);
3678   websAspDefine ("forward_port", ej_forward_port);
3679   websAspDefine ("forward_spec", ej_forward_spec);
3680 // changed by steve
3681 //websAspDefine ("forward_upnp", ej_forward_upnp);      // upnp added
3682 // end changed by steve
3683
3684   websAspDefine ("static_route", ej_static_route);
3685   websAspDefine ("localtime", ej_localtime);
3686   websAspDefine ("dumplog", ej_dumplog);
3687 #ifdef HAVE_SPUTNIK_APD
3688   websAspDefine ("sputnik_apd_status", ej_sputnik_apd_status);
3689 #endif
3690   websAspDefine ("dumpleases", ej_dumpleases);
3691   websAspDefine ("ppplink", ej_ppplink);
3692   websUrlHandlerDefine ("/Management.asp", NULL, 0, apply_cgi, 0);
3693   websUrlHandlerDefine ("/internal.cgi", NULL, 0, internal_cgi, 0);
3694   //DD-WRT addition start
3695   websUrlHandlerDefine ("/modules.cgi", NULL, 0, show_modules, 0);
3696   //DD-WRT addition end
3697   websSetPassword (nvram_safe_get ("http_passwd"));
3698   websSetRealm ("DD-WRT Router OS Core");
3699 }
3700
3701 #else /* !WEBS */
3702 #ifdef HAVE_SKYTRON
3703 int
3704 do_auth (char *userid, char *passwd, char *realm)
3705 {
3706   strncpy (userid, nvram_safe_get ("skyhttp_username"), AUTH_MAX);
3707   strncpy (passwd, nvram_safe_get ("skyhttp_passwd"), AUTH_MAX);
3708   //strncpy(realm, MODEL_NAME, AUTH_MAX);
3709   strncpy (realm, nvram_safe_get ("router_name"), AUTH_MAX);
3710   return 0;
3711 }
3712
3713
3714 int
3715 do_auth2 (char *userid, char *passwd, char *realm)
3716 {
3717   strncpy (userid, nvram_safe_get ("http_username"), AUTH_MAX);
3718   strncpy (passwd, nvram_safe_get ("http_passwd"), AUTH_MAX);
3719   //strncpy(realm, MODEL_NAME, AUTH_MAX);
3720   strncpy (realm, nvram_safe_get ("router_name"), AUTH_MAX);
3721   return 0;
3722 }
3723 #else
3724
3725
3726
3727 int
3728 do_auth (char *userid, char *passwd, char *realm)
3729 {
3730   strncpy (userid, nvram_safe_get ("http_username"), AUTH_MAX);
3731   strncpy (passwd, nvram_safe_get ("http_passwd"), AUTH_MAX);
3732   //strncpy(realm, MODEL_NAME, AUTH_MAX);
3733   strncpy (realm, nvram_safe_get ("router_name"), AUTH_MAX);
3734   return 0;
3735 }
3736
3737 int
3738 do_cauth (char *userid, char *passwd, char *realm)
3739 {
3740   if (nvram_match ("info_passwd", "0"))
3741     return -1;
3742   return do_auth (userid, passwd, realm);
3743 }
3744 #endif
3745 #undef HAVE_DDLAN
3746
3747 #ifdef HAVE_DDLAN
3748 int
3749 do_auth2 (char *userid, char *passwd, char *realm)
3750 {
3751   strncpy (userid, nvram_safe_get ("http2_username"), AUTH_MAX);
3752   strncpy (passwd, nvram_safe_get ("http2_passwd"), AUTH_MAX);
3753   //strncpy(realm, MODEL_NAME, AUTH_MAX);
3754   strncpy (realm, nvram_safe_get ("router_name"), AUTH_MAX);
3755   return 0;
3756 }
3757 #endif
3758
3759 //#ifdef EZC_SUPPORT
3760 char ezc_version[128];
3761 //#endif
3762
3763 char post_buf[10000] = { 0 };
3764 extern int post;
3765
3766 static void                     // support GET and POST 2003-08-22
3767 do_apply_post (char *url, webs_t stream, int len, char *boundary)
3768 {
3769   unsigned char buf[1024];
3770   int count;
3771
3772   if (post == 1)
3773     {
3774       if (len > sizeof (post_buf) - 1)
3775         {
3776           cprintf ("The POST data exceed length limit!\n");
3777           return;
3778         }
3779       /* Get query */
3780       if (!(count = wfread (post_buf, 1, len, stream)))
3781         return;
3782       post_buf[count] = '\0';;
3783       len -= strlen (post_buf);
3784
3785       /* Slurp anything remaining in the request */
3786       while (--len > 0)
3787 #ifdef HAVE_HTTPS
3788         if (do_ssl)
3789           wfgets (buf, 1, stream);
3790         else
3791 #endif
3792           (void) fgetc (stream);
3793       init_cgi (post_buf);
3794     }
3795 }
3796
3797 #if !defined(HAVE_X86) && !defined(HAVE_MAGICBOX)
3798 static void
3799 do_cfebackup (char *url, webs_t stream, char *query)
3800 {
3801   system2 ("cat /dev/mtd/0 > /tmp/cfe.bin");
3802   do_file ("/tmp/cfe.bin", stream, NULL);
3803   unlink ("/tmp/cfe.bin");
3804 }
3805 #endif
3806
3807 static void
3808 do_stylecss (char *url, webs_t stream, char *query)
3809 {
3810   char *style = nvram_get ("router_style");
3811
3812   if (query != NULL)
3813     style = query;
3814
3815   long sdata[30];
3816
3817   long blue[30] =
3818     { 0x36f, 0xfff, 0x68f, 0x24d, 0x24d, 0x68f, 0x57f, 0xccf, 0x78f, 0x35d,
3819 0x35c, 0x78f,
3820     0x78f, 0xfff, 0x9af, 0x46e, 0x46e, 0x9af, 0x36f, 0xccf, 0xfff, 0x69f,
3821       0xfff, 0xfff,
3822     0x999, 0x69f, 0x69f, 0xccf, 0x78f, 0xfff
3823   };
3824
3825   long cyan[30] =
3826     { 0x099, 0xfff, 0x3bb, 0x066, 0x066, 0x3bb, 0x3bb, 0xcff, 0x4cc, 0x1aa,
3827 0x1aa, 0x4cc,
3828     0x6cc, 0xfff, 0x8dd, 0x5bb, 0x5bb, 0x8dd, 0x099, 0xcff, 0xfff, 0x3bb,
3829       0xfff, 0xfff,
3830     0x999, 0x3bb, 0x3bb, 0xcff, 0x6cc, 0xfff
3831   };
3832
3833   long elegant[30] =
3834     { 0x30519c, 0xfff, 0x496fc7, 0x496fc7, 0x496fc7, 0x496fc7, 0x496fc7,
3835 0xfff, 0x6384cf, 0x6384cf, 0x6384cf, 0x6384cf,
3836     0x6384cf, 0xfff, 0x849dd9, 0x849dd9, 0x849dd9, 0x849dd9, 0x30519c, 0xfff,
3837       0xfff, 0x496fc7, 0xfff, 0xfff,
3838     0x999, 0x496fc7, 0x496fc7, 0xfff, 0x6384cf, 0xfff
3839   };
3840
3841   long green[30] =
3842     { 0x090, 0xfff, 0x3b3, 0x060, 0x060, 0x3b3, 0x3b3, 0xcfc, 0x4c4, 0x1a1,
3843 0x1a1, 0x4c4,
3844     0x6c6, 0xfff, 0x8d8, 0x5b5, 0x5b5, 0x8d8, 0x090, 0xcfc, 0xfff, 0x3b3,
3845       0xfff, 0xfff,
3846     0x999, 0x3b3, 0x3b3, 0xcfc, 0x6c6, 0xfff
3847   };
3848
3849   long orange[30] =
3850     { 0xf26522, 0xfff, 0xff8400, 0xff8400, 0xff8400, 0xff8400, 0xff8400,
3851 0xfff, 0xfeb311, 0xfeb311, 0xfeb311, 0xfeb311,
3852     0xff9000, 0xfff, 0xffa200, 0xffa200, 0xffa200, 0xffa200, 0xf26522, 0xfff,
3853       0xfff, 0xff8400, 0xfff, 0xfff,
3854     0x999, 0xff8400, 0xff8400, 0xfff, 0xff9000, 0xfff
3855   };
3856
3857   long red[30] =
3858     { 0xc00, 0xfff, 0xe33, 0x800, 0x800, 0xe33, 0xd55, 0xfcc, 0xe77, 0xc44,
3859 0xc44, 0xe77,
3860     0xe77, 0xfff, 0xf99, 0xd55, 0xd55, 0xf99, 0xc00, 0xfcc, 0xfff, 0xd55,
3861       0xfff, 0xfff,
3862     0x999, 0xd55, 0xd55, 0xfcc, 0xe77, 0xfff
3863   };
3864
3865   long yellow[30] =
3866     { 0xcc0, 0x000, 0xee3, 0x880, 0x880, 0xee3, 0xdd5, 0x660, 0xee7, 0xbb4,
3867 0xbb4, 0xee7,
3868     0xee7, 0x000, 0xff9, 0xcc5, 0xcc5, 0xff9, 0x990, 0x660, 0x000, 0xdd5,
3869       0x000, 0xfff,
3870     0x999, 0xdd5, 0xdd5, 0x660, 0xee7, 0x000
3871   };
3872
3873   if (!strcmp (style, "blue"))
3874     memcpy (sdata, blue, 30 * sizeof (long));
3875   else if (!strcmp (style, "cyan"))
3876     memcpy (sdata, cyan, 30 * sizeof (long));
3877   else if (!strcmp (style, "elegant"))
3878     memcpy (sdata, elegant, 30 * sizeof (long));
3879   else if (!strcmp (style, "green"))
3880     memcpy (sdata, green, 30 * sizeof (long));
3881   else if (!strcmp (style, "orange"))
3882     memcpy (sdata, orange, 30 * sizeof (long));
3883   else if (!strcmp (style, "red"))
3884     memcpy (sdata, red, 30 * sizeof (long));
3885   else                          //yellow
3886     memcpy (sdata, yellow, 30 * sizeof (long));
3887
3888
3889   websWrite (stream, "@import url(../common.css);\n");
3890   websWrite (stream, "#menuSub,\n");
3891   websWrite (stream, "#menuMainList li span,\n");
3892   websWrite (stream, "#help h2 {\n");
3893   websWrite (stream, "background:#%03x;\n", sdata[0]);
3894   websWrite (stream, "color:#%03x;\n", sdata[1]);
3895   websWrite (stream, "border-color:#%03x #%03x #%03x #%03x;\n", sdata[2],
3896              sdata[3], sdata[4], sdata[5]);
3897   websWrite (stream, "}\n");
3898   websWrite (stream, "#menuSubList li a {\n");
3899   websWrite (stream, "background:#%03x;\n", sdata[6]);
3900   websWrite (stream, "color:#%03x;\n", sdata[7]);
3901   websWrite (stream, "border-color:#%03x #%03x #%03x #%03x;\n", sdata[8],
3902              sdata[9], sdata[10], sdata[11]);
3903   websWrite (stream, "}\n");
3904   websWrite (stream, "#menuSubList li a:hover {\n");
3905   websWrite (stream, "background:#%03x;\n", sdata[12]);
3906   websWrite (stream, "color:#%03x;\n", sdata[13]);
3907   websWrite (stream, "border-color:#%03x #%03x #%03x #%03x;\n", sdata[14],
3908              sdata[15], sdata[16], sdata[17]);
3909   websWrite (stream, "}\n");
3910   websWrite (stream, "fieldset legend {\n");
3911   websWrite (stream, "color:#%03x;\n", sdata[18]);
3912   websWrite (stream, "}\n");
3913   websWrite (stream, "#help a {\n");
3914   websWrite (stream, "color:#%03x;\n", sdata[19]);
3915   websWrite (stream, "}\n");
3916   websWrite (stream, "#help a:hover {\n");
3917   websWrite (stream, "color:#%03x;\n", sdata[20]);
3918   websWrite (stream, "}\n");
3919   websWrite (stream, ".meter .bar {\n");
3920   websWrite (stream, "background-color: #%03x;\n", sdata[21]);
3921   websWrite (stream, "}\n");
3922   websWrite (stream, ".meter .text {\n");
3923   websWrite (stream, "color:#%03x;\n", sdata[22]);
3924   websWrite (stream, "}\n");
3925   websWrite (stream, ".progressbar {\n");
3926   websWrite (stream, "background-color: #%03x;\n", sdata[23]);
3927   websWrite (stream, "border-color: #%03x;\n", sdata[24]);
3928   websWrite (stream, "font-size:.09em;\n");
3929   websWrite (stream, "border-width:.09em;\n");
3930   websWrite (stream, "}\n");
3931   websWrite (stream, ".progressbarblock {\n");
3932   websWrite (stream, "background-color: #%03x;\n", sdata[25]);
3933   websWrite (stream, "font-size:.09em;\n");
3934   websWrite (stream, "}\n");
3935   websWrite (stream, "input.button {\n");
3936   websWrite (stream, "background: #%03x;\n", sdata[26]);
3937   websWrite (stream, "color: #%03x;\n", sdata[27]);
3938   websWrite (stream, "}\n");
3939   websWrite (stream, "input.button:hover {\n");
3940   websWrite (stream, "background: #%03x;\n", sdata[28]);
3941   websWrite (stream, "color: #%03x;\n", sdata[29]);
3942   websWrite (stream, "}\n");
3943
3944 }
3945
3946 static void
3947 do_stylecss_ie (char *url, webs_t stream, char *query)
3948 {
3949   websWrite (stream, ".submitFooter input {\n");
3950   websWrite (stream, "padding:.362em .453em;\n");
3951   websWrite (stream, "}\n");
3952   websWrite (stream, "fieldset {\n");
3953   websWrite (stream, "padding-top:0;\n");
3954   websWrite (stream, "}\n");
3955   websWrite (stream, "fieldset legend {\n");
3956   websWrite (stream, "margin-left:-9px;\n");
3957   websWrite (stream, "margin-bottom:8px;\n");
3958   websWrite (stream, "padding:0 .09em;\n");
3959   websWrite (stream, "}\n");
3960 }
3961
3962 /*
3963 static void
3964 do_style (char *url, webs_t stream, char *query)
3965 {
3966   char *style = nvram_get ("router_style");
3967   if (style == NULL || strlen (style) == 0)
3968     do_file ("kromo.css", stream, NULL);
3969   else
3970     do_file (style, stream, NULL);
3971 }
3972 */
3973
3974
3975 static void
3976 do_fetchif (char *url, webs_t stream, char *query)
3977 {
3978   char line[256];
3979   int i, llen;
3980   char buffer[256];
3981   if (query == NULL || strlen (query) == 0)
3982     return;
3983   int strbuffer = 0;
3984   time_t tm;
3985   struct tm tm_time;
3986   time (&tm);
3987   memcpy (&tm_time, localtime (&tm), sizeof (tm_time));
3988   char *date_fmt = "%a %b %e %H:%M:%S %Z %Y";
3989   strftime (buffer, 200, date_fmt, &tm_time);
3990   strbuffer = strlen (buffer);
3991   buffer[strbuffer++] = '\n';
3992   FILE *in = fopen ("/proc/net/dev", "rb");
3993   if (in == NULL)
3994     return;
3995
3996   while (fgets (line, sizeof (line), in) != NULL)
3997     {
3998       if (!strchr (line, ':'))
3999         continue;
4000       if (strstr (line, query))
4001         {
4002           llen = strlen (line);
4003           for (i = 0; i < llen; i++)
4004             {
4005               buffer[strbuffer++] = line[i];
4006             }
4007           break;
4008         }
4009     }
4010   buffer[strbuffer] = 0;
4011   fclose (in);
4012   websWrite (stream, "%s", buffer);
4013 }
4014
4015 static void
4016 ej_get_totaltraff (webs_t wp, int argc, char_t ** argv)
4017 {
4018   char *type;
4019   static char wanface[32];
4020   char line[256];
4021   unsigned long rcvd, sent, megcounti, megcounto;
4022   FILE *in;
4023
4024 #ifdef FASTWEB
4025   ejArgs (argc, argv, "%s", &type);
4026 #else
4027   if (ejArgs (argc, argv, "%s", &type) < 1)
4028     {
4029       websError (wp, 400, "Insufficient args\n");
4030       return;
4031     }
4032 #endif
4033
4034   if (!nvram_match ("ttraff_enable", "1"))
4035     return;
4036
4037   strncpy (wanface, get_wan_face (), sizeof (wanface));
4038
4039   in = fopen ("/proc/net/dev", "rb");
4040   if (in == NULL)
4041     return;
4042
4043   while (fgets (line, sizeof (line), in) != NULL)
4044     {
4045       int ifl = 0;
4046       if (!strchr (line, ':'))
4047         continue;
4048       while (line[ifl] != ':')
4049         ifl++;
4050       line[ifl] = 0;            /* interface */
4051       if (strstr (line, wanface))
4052         {
4053           sscanf (line + ifl + 1,
4054                   "%lu %*ld %*ld %*ld %*ld %*ld %*ld %*ld %lu %*ld %*ld %*ld %*ld %*ld %*ld %*ld",
4055                   &rcvd, &sent);
4056
4057         }
4058     }
4059
4060   fclose (in);
4061
4062   rcvd >>= 20;                  //output in MBytes
4063   sent >>= 20;
4064
4065
4066   if ((in = fopen ("/tmp/.megc", "r")) != NULL)
4067     {
4068       fgets (line, sizeof (line), in);
4069       sscanf (line, "%lu:%lu", &megcounti, &megcounto);
4070       rcvd += megcounti;
4071       sent += megcounto;
4072       fclose (in);
4073     }
4074
4075   if (!strcmp (type, "in"))
4076     {
4077       websWrite (wp, "%lu", rcvd);      //output in MBytes
4078     }
4079   else if (!strcmp (type, "out"))
4080     {
4081       websWrite (wp, "%lu", sent);
4082     }
4083   return;
4084 }
4085
4086 static void
4087 do_ttgraph (char *url, webs_t stream, char *query)
4088 {
4089 #define COL_WIDTH 16            /* single column width */
4090
4091   char *next;
4092   char var[80];
4093
4094   unsigned int days;
4095   unsigned int month;
4096   unsigned int year;
4097   int wd;
4098   int i = 0;
4099   char months[12][12] =
4100     { "share.jan", "share.feb", "share.mar", "share.apr", "share.may",
4101 "share.jun",
4102     "share.jul", "share.aug", "share.sep", "share.oct", "share.nov",
4103       "share.dec"
4104   };
4105   unsigned long rcvd[31] =
4106     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4107 0, 0, 0, 0, 0, 0, 0 };
4108   unsigned long sent[31] =
4109     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4110 0, 0, 0, 0, 0, 0, 0 };
4111   unsigned long max = 5, smax = 5, f = 1;
4112   unsigned long totin = 0;
4113   unsigned long totout = 0;
4114
4115   if (sscanf (query, "%u-%u", &month, &year) != 2)
4116     return;
4117
4118   days = daysformonth (month, year);
4119   wd = weekday (month, 1, year);        //first day in month (mon=0, tue=1, ..., sun=6)
4120
4121   char tq[32];
4122   sprintf (tq, "traff-%02u-%u", month, year);
4123   char *tdata = nvram_safe_get (tq);
4124   if (tdata != NULL || strlen (tdata))
4125     {
4126       foreach (var, tdata, next)
4127       {
4128         sscanf (var, "%lu:%lu", &rcvd[i], &sent[i]);
4129         totin += rcvd[i];
4130         totout += sent[i];
4131         if (rcvd[i] > max)
4132           max = rcvd[i];
4133         if (sent[i] > max)
4134           max = sent[i];
4135         i++;
4136       }
4137     }
4138
4139
4140   while (max > smax)
4141     {
4142       if (max > (f * 5))
4143         smax = f * 10;
4144       if (max > (f * 10))
4145         smax = f * 25;
4146       if (max > (f * 25))
4147         smax = f * 50;
4148       f = f * 10;
4149     }
4150
4151   char incom[32];
4152   sprintf (incom, "%s", live_translate ("status_inet.traffin"));
4153   char outcom[32];
4154   sprintf (outcom, "%s", live_translate ("status_inet.traffout"));
4155   char monthname[32];
4156   sprintf (monthname, "%s", live_translate (months[month - 1]));
4157
4158   websWrite (stream,
4159              "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
4160   websWrite (stream, "<html>\n");
4161   websWrite (stream, "<head>\n");
4162   websWrite (stream, "<title>dd-wrt traffic graph</title>\n");
4163
4164   websWrite (stream, "<script type=\"text/javascript\">\n");
4165   websWrite (stream, "//<![CDATA[\n");
4166   websWrite (stream, "function Show(label) {\n");
4167   websWrite (stream,
4168              "document.getElementById(\"label\").innerHTML = label;\n");
4169   websWrite (stream, "}\n");
4170   websWrite (stream, "//]]>\n");
4171   websWrite (stream, "</script>\n");
4172
4173   websWrite (stream, "<style type=\"text/css\">\n\n");
4174   websWrite (stream,
4175              "#t-graph {position: relative; width: %upx; height: 300px;\n",
4176              days * COL_WIDTH);
4177   websWrite (stream, "  margin: 1.1em 0 3.5em; padding: 0;\n");
4178   websWrite (stream, "  border: 1px solid gray; list-style: none;\n");
4179   websWrite (stream, "  font: 9px Tahoma, Arial, sans-serif;}\n");
4180   websWrite (stream,
4181              "#t-graph ul {margin: 0; padding: 0; list-style: none;}\n");
4182   websWrite (stream,
4183              "#t-graph li {position: absolute; bottom: 0; width: %dpx; z-index: 2;\n",
4184              COL_WIDTH);
4185   websWrite (stream, "  margin: 0; padding: 0;\n");
4186   websWrite (stream, "  text-align: center; list-style: none;}\n");
4187   websWrite (stream,
4188              "#t-graph li.day {height: 298px; padding-top: 2px; border-right: 1px dotted #C4C4C4; color: #AAA;}\n");
4189   websWrite (stream,
4190              "#t-graph li.day_sun {height: 298px; padding-top: 2px; border-right: 1px dotted #C4C4C4; color: #E00;}\n");
4191   websWrite (stream,
4192              "#t-graph li.bar {width: 4px; border: 1px solid; border-bottom: none; color: #000;}\n");
4193   websWrite (stream, "#t-graph li.bar p {margin: 5px 0 0; padding: 0;}\n");
4194   websWrite (stream, "#t-graph li.rcvd {left: 3px; background: #228B22;}\n");   //set rcvd bar colour here (green)
4195   websWrite (stream, "#t-graph li.sent {left: 8px; background: #CD0000;}\n");   //set sent bar colour here (red)
4196
4197   for (i = 0; i < days - 1; i++)
4198     {
4199       websWrite (stream, "#t-graph #d%d {left: %dpx;}\n", i + 1,
4200                  i * COL_WIDTH);
4201     }
4202   websWrite (stream, "#t-graph #d%u {left: %upx; border-right: none;}\n",
4203              days, (days - 1) * COL_WIDTH);
4204
4205   websWrite (stream,
4206              "#t-graph #ticks {width: %upx; height: 300px; z-index: 1;}\n",
4207              days * COL_WIDTH);
4208   websWrite (stream,
4209              "#t-graph #ticks .tick {position: relative; border-bottom: 1px solid #BBB; width: %upx;}\n",
4210              days * COL_WIDTH);
4211   websWrite (stream,
4212              "#t-graph #ticks .tick p {position: absolute; left: 100%%; top: -0.67em; margin: 0 0 0 0.5em;}\n");
4213   websWrite (stream,
4214              "#t-graph #label {width: 500px; bottom: -20px;  z-index: 1; font: 12px Tahoma, Arial, sans-serif; font-weight: bold;}\n");
4215   websWrite (stream, "</style>\n");
4216   websWrite (stream, "</head>\n\n");
4217   websWrite (stream, "<body>\n");
4218   websWrite (stream, "<ul id=\"t-graph\">\n");
4219
4220   for (i = 0; i < days; i++)
4221     {
4222       websWrite (stream, "<li class=\"day%s\" id=\"d%d\" ",
4223                  (wd % 7) == 6 ? "_sun" : "", i + 1);
4224       wd++;
4225       websWrite (stream,
4226                  "onmouseover=\"Show(\'%s %d, %d (%s: %lu MB / %s: %lu MB)\')\" ",
4227                  monthname, i + 1, year, incom, rcvd[i], outcom, sent[i]);
4228       websWrite (stream,
4229                  "onmouseout=\"Show(\'%s %d (%s: %lu MB / %s: %lu MB)\')\"",
4230                  monthname, year, incom, totin, outcom, totout);
4231       websWrite (stream, ">%d\n", i + 1);
4232       websWrite (stream, "<ul>\n");
4233       websWrite (stream,
4234                  "<li class=\"rcvd bar\" style=\"height: %lupx;\"><p></p></li>\n",
4235                  rcvd[i] * 300 / smax);
4236       websWrite (stream,
4237                  "<li class=\"sent bar\" style=\"height: %lupx;\"><p></p></li>\n",
4238                  sent[i] * 300 / smax);
4239       websWrite (stream, "</ul>\n");
4240       websWrite (stream, "</li>\n");
4241     }
4242
4243   websWrite (stream, "<li id=\"ticks\">\n");
4244   for (i = 5; i; i--)           //scale
4245     {
4246       websWrite (stream,
4247                  "<div class=\"tick\" style=\"height: 59px;\"><p>%d%sMB</p></div>\n",
4248                  smax * i / 5, (smax > 10000) ? " " : "&nbsp;");
4249     }
4250   websWrite (stream, "</li>\n\n");
4251
4252   websWrite (stream, "<li id=\"label\">\n");
4253   websWrite (stream, "%s %d (%s: %lu MB / %s: %lu MB)\n", monthname, year,
4254              incom, totin, outcom, totout);
4255   websWrite (stream, "</li>\n");
4256
4257   websWrite (stream, "</ul>\n\n");
4258   websWrite (stream, "</body>\n");
4259   websWrite (stream, "</html>\n");
4260
4261
4262 }
4263
4264 static void
4265 do_apply_cgi (char *url, webs_t stream, char *q)
4266 {
4267   char *path, *query;
4268
4269   if (post == 1)
4270     {
4271       query = post_buf;
4272       path = url;
4273     }
4274   else
4275     {
4276       query = url;
4277       path = strsep (&query, "?") ? : url;
4278       init_cgi (query);
4279     }
4280
4281   if (!query)
4282     return;
4283
4284   apply_cgi (stream, NULL, NULL, 0, url, path, query);
4285   init_cgi (NULL);
4286 }
4287
4288 static void
4289 show_bwif (webs_t wp, char *ifname, char *name)
4290 {
4291   websWrite (wp, "<h2>%s - %s</h2>\n", live_translate ("status_band.h2"),
4292              name);
4293   websWrite (wp, "<fieldset>\n");
4294   websWrite (wp,
4295              "<iframe src=\"/graph_if.svg?%s\" width=\"555\" height=\"275\" frameborder=\"0\" type=\"image/svg+xml\">\n",
4296              ifname);
4297   websWrite (wp, "</iframe>\n");
4298   websWrite (wp, "</fieldset>\n");
4299   websWrite (wp, "<br />\n");
4300 }
4301
4302 #ifdef HAVE_MADWIFI
4303 extern int getdevicecount (void);
4304 #endif
4305
4306 static void
4307 ej_show_bandwidth (webs_t wp, int argc, char_t ** argv)
4308 {
4309   show_bwif (wp, nvram_safe_get ("lan_ifname"), "LAN");
4310   if (!nvram_match ("wan_proto", "disabled"))
4311     {
4312       if (strlen (nvram_safe_get ("wan_iface")) > 0)
4313         {
4314           show_bwif (wp, nvram_safe_get ("wan_iface"), "WAN");
4315         }
4316       else
4317         {
4318           if (strlen (nvram_safe_get ("wan_ifname")) > 0)
4319             {
4320               show_bwif (wp, nvram_safe_get ("wan_ifname"), "WAN");
4321             }
4322         }
4323     }
4324 #ifdef HAVE_MADWIFI
4325   char var[80];
4326   char *next;
4327   int c = getdevicecount ();
4328   int i;
4329   for (i = 0; i < c; i++)
4330     {
4331       char dev[32];
4332       sprintf (dev, "ath%d", i);
4333       char name[32];
4334       sprintf (name, "%s (%s)", live_translate ("share.wireless"), dev);
4335       show_bwif (wp, dev, name);
4336       char *vifs = nvram_nget ("%s_vifs", dev);
4337       if (vifs == NULL)
4338         continue;
4339       foreach (var, vifs, next)
4340       {
4341         sprintf (name, "%s (%s)", live_translate ("share.wireless"), var);
4342         show_bwif (wp, var, name);
4343       }
4344       int s;
4345       for (s = 1; s <= 10; s++)
4346         {
4347           char *wdsdev;
4348           wdsdev = nvram_nget ("%s_wds%d_if", dev, s);
4349           if (strlen (wdsdev) == 0)
4350             continue;
4351           if (nvram_nmatch ("0", "%s_wds%d_enable", dev, s))
4352             continue;
4353           sprintf (name, "%s (%s)", live_translate ("share.wireless"),
4354                    wdsdev);
4355           show_bwif (wp, wdsdev, name);
4356         }
4357
4358     }
4359
4360 #else
4361   char name[32];
4362   sprintf (name, "%s", live_translate ("share.wireless"));
4363   show_bwif (wp, get_wdev (), name);
4364 #endif
4365 #ifdef HAVE_WAVESAT
4366   char name[32];
4367   sprintf (name, "%s", live_translate ("wl_wimax.titl"));
4368   show_bwif (wp, "ofdm", name);
4369 #endif
4370 }
4371
4372 void
4373 ej_get_http_method (webs_t wp, int argc, char_t ** argv)
4374 {
4375   websWrite (wp, "%s", "post");
4376 }
4377
4378 static char *
4379 getLanguageName ()
4380 {
4381   char *lang = nvram_get ("language");
4382   cprintf ("get language %s\n", lang);
4383   char *l = malloc (60);
4384   if (lang == NULL)
4385     {
4386       cprintf ("return default\n");
4387       sprintf (l, "lang_pack/english.js");
4388       return l;
4389     }
4390   sprintf (l, "lang_pack/%s.js", lang);
4391   cprintf ("return %s\n", l);
4392   return l;
4393 }
4394
4395 static void
4396 do_language (char *path, webs_t stream, char *query)    //jimmy, https, 8/4/2003
4397 {
4398   char *lang = getLanguageName ();
4399   do_file (lang, stream, NULL);
4400   free (lang);
4401   return;
4402 }
4403
4404 char *
4405 live_translate (char *tran)
4406 {
4407
4408   FILE *fp;
4409   static char temp[256], temp1[256];
4410   char *temp2;
4411   char *lang = getLanguageName ();
4412   char buf[64];
4413   sprintf (buf, "%s", lang);
4414   free (lang);
4415
4416   strcpy (temp1, tran);
4417   strcat (temp1, "=\"");
4418
4419   int len = strlen (temp1);
4420
4421   fp = getWebsFile (buf);
4422   if (fp == NULL)
4423     return "Error";
4424   int start = ftell (fp);
4425   int filelen = getWebsFileLen (buf);
4426   while (fgets (temp, 256, fp) != NULL)
4427     {
4428       int pos = ftell (fp);
4429       if ((pos - start) > filelen)
4430         break;
4431       if ((memcmp (temp, temp1, len)) == 0)
4432         {
4433           temp2 = strtok (temp, "\"");
4434           temp2 = strtok (NULL, "\"");
4435
4436           fclose (fp);
4437           return temp2;
4438         }
4439     }
4440   fclose (fp);
4441
4442   fp = getWebsFile ("lang_pack/english.js");    //if not found, try english
4443   if (fp == NULL)
4444     return "Error";
4445
4446   while (fgets (temp, 256, fp) != NULL)
4447     {
4448       if ((memcmp (temp, temp1, len)) == 0)
4449         {
4450           temp2 = strtok (temp, "\"");
4451           temp2 = strtok (NULL, "\"");
4452
4453           fclose (fp);
4454           return temp2;
4455         }
4456     }
4457   fclose (fp);
4458
4459   return "Error";               //not found
4460
4461 }
4462 extern int issuperchannel (void);
4463
4464
4465 void
4466 ej_do_menu (webs_t wp, int argc, char_t ** argv)
4467 {
4468   char *mainmenu, *submenu;
4469
4470 #ifdef FASTWEB
4471   ejArgs (argc, argv, "%s %s", &mainmenu, &submenu);
4472 #else
4473   if (ejArgs (argc, argv, "%s %s", &mainmenu, &submenu) < 2)
4474     {
4475       websError (wp, 400, "Insufficient args\n");
4476       return;
4477     }
4478 #endif
4479
4480   int vlan_supp = check_vlan_support ();
4481 #ifdef HAVE_SPUTNIK_APD
4482   int sputnik = nvram_match ("apd_enable", "1");
4483 #else
4484   int sputnik = 0;
4485 #endif
4486   int openvpn =
4487     nvram_match ("openvpn_enable", "1") | nvram_match ("openvpncl_enable",
4488                                                        "1");
4489   int auth = nvram_match ("status_auth", "1");
4490 #ifdef HAVE_MADWIFI
4491 #ifdef HAVE_NOWIFI
4492   int wifi = 0;
4493 #else
4494   int wifi = haswifi ();
4495 #endif
4496 #endif
4497   int wimaxwifi = 0;
4498   char menu[8][11][32] =
4499     { {"index.asp", "DDNS.asp", "WanMAC.asp", "Routing.asp", "Vlan.asp",
4500        "Networking.asp", "", "", "", "", ""},
4501   {"Wireless_Basic.asp", "SuperChannel.asp", "WiMAX.asp",
4502    "Wireless_radauth.asp", "WL_WPATable.asp",
4503    "Wireless_MAC.asp", "Wireless_Advanced.asp", "Wireless_WDS.asp", "", "",
4504    ""},
4505   {"Services.asp", "PPPoE_Server.asp", "PPTP.asp", "Hotspot.asp",
4506    "Milkfish.asp", "eop-tunnel.asp", "AnchorFree.asp", "", "", "", ""},
4507   {"Firewall.asp", "VPN.asp", "", "", "", "", "", "", "", "", ""},
4508   {"Filters.asp", "", "", "", "", "", "", "", "", "", ""},
4509   {"ForwardSpec.asp", "Forward.asp", "Triggering.asp", "UPnP.asp", "DMZ.asp",
4510    "QoS.asp", "P2P.asp", "", "", "", ""},
4511   {"Management.asp", "Alive.asp", "Diagnostics.asp", "Wol.asp",
4512    "Factory_Defaults.asp", "Upgrade.asp", "config.asp", "", "", "", ""},
4513   {"Status_Router.asp", "Status_Internet.asp", "Status_Lan.asp",
4514    "Status_Wireless.asp",
4515    "Status_SputnikAPD.asp", "Status_OpenVPN.asp", "Status_Bandwidth.asp",
4516    "Info.htm", "", "", ""}
4517   };
4518
4519 /* real name is bmenu.menuname[i][j] */
4520   char menuname[8][12][32] =
4521     { {"setup", "setupbasic", "setupddns", "setupmacclone", "setuprouting",
4522        "setupvlan", "networking", "", "", "", "", ""},
4523   {"wireless", "wirelessBasic", "wirelessSuperchannel", "wimax",
4524    "wirelessRadius", "wirelessSecurity",
4525    "wirelessMac", "wirelessAdvanced", "wirelessWds", "", "", ""},
4526   {"services", "servicesServices", "servicesPppoesrv", "servicesPptp",
4527    "servicesHotspot", "servicesMilkfish", "setupeop", "servicesAnchorFree",
4528    "", "", "", ""},
4529   {"security", "firwall", "vpn", "", "", "", "", "", "", "", "", ""},
4530   {"accrestriction", "webaccess", "", "", "", "", "", "", "", "", "", ""},
4531   {"applications", "applicationspforwarding", "applicationsprforwarding",
4532    "applicationsptriggering", "applicationsUpnp", "applicationsDMZ",
4533    "applicationsQoS", "applicationsP2P", "", "", "", ""},
4534   {"admin", "adminManagement", "adminAlive",
4535    "adminDiag", "adminWol", "adminFactory", "adminUpgrade", "adminBackup",
4536    "", "", "", ""},
4537   {"statu", "statuRouter", "statuInet", "statuLAN", "statuWLAN",
4538    "statuSputnik",
4539    "statuVPN", "statuBand", "statuSysInfo", "", "", ""}
4540   };
4541
4542 #ifdef HAVE_MADWIFI
4543   //fill up WDS
4544   int ifcount = getifcount ("wifi");
4545   int a;
4546   for (a = 0; a < ifcount; a++)
4547     {
4548       sprintf (&menu[1][a + 7][0], "Wireless_WDS-ath%d.asp", a);
4549       if (ifcount == 1)
4550         sprintf (&menuname[1][a + 8][0], "wirelessWds");
4551       else
4552         sprintf (&menuname[1][a + 8][0], "wirelessWds%d", a);
4553     }
4554 #else
4555   int ifcount = get_wl_instances ();
4556   int a;
4557   for (a = 0; a < ifcount; a++)
4558     {
4559       sprintf (&menu[1][a + 7][0], "Wireless_WDS-wl%d.asp", a);
4560       if (ifcount == 1)
4561         sprintf (&menuname[1][a + 8][0], "wirelessWds");
4562       else
4563         sprintf (&menuname[1][a + 8][0], "wirelessWdswl%d", a);
4564     }
4565 #endif
4566
4567   int i, j;
4568
4569   websWrite (wp, "<div id=\"menu\">\n");
4570   websWrite (wp, " <div id=\"menuMain\">\n");
4571   websWrite (wp, "  <ul id=\"menuMainList\">\n");
4572 #ifdef HAVE_WAVESAT
4573   wimaxwifi = 1;
4574 #endif
4575   for (i = 0; i < 8; i++)
4576     {
4577 #ifdef HAVE_MADWIFI
4578       if (!wifi && !wimaxwifi && !strcmp (menu[i][0], "Wireless_Basic.asp"))
4579         i++;
4580 #endif
4581       if (!strcmp (menu[i][0], mainmenu))
4582         {
4583 #ifdef HAVE_MADWIFI
4584           if (!wifi && wimaxwifi
4585               && !strcmp (menu[i][0], "Wireless_Basic.asp"))
4586             websWrite (wp,
4587                        "   <li class=\"current\"><span><script type=\"text/javascript\">Capture(bmenu.wimax)</script></span>\n");
4588           else
4589 #endif
4590             websWrite (wp,
4591                        "   <li class=\"current\"><span><script type=\"text/javascript\">Capture(bmenu.%s)</script></span>\n",
4592                        menuname[i][0]);
4593           websWrite (wp, "    <div id=\"menuSub\">\n");
4594           websWrite (wp, "     <ul id=\"menuSubList\">\n");
4595
4596           for (j = 0; j < 11; j++)
4597             {
4598
4599 #ifdef HAVE_MADWIFI
4600               if (!wifi && !strncmp (menu[i][j], "Wireless_Basic.asp", 8))
4601                 j++;
4602 #ifndef HAVE_SUPERCHANNEL
4603               if (!strcmp (menu[i][j], "SuperChannel.asp"))     //jump over PPTP in micro build
4604                 j++;
4605 #else
4606               if (!strcmp (menu[i][j], "SuperChannel.asp") && (issuperchannel () || !wifi))     //jump over PPTP in micro build
4607                 j++;
4608 #endif
4609 #else
4610               if (!strcmp (menu[i][j], "SuperChannel.asp"))     //jump over PPTP in micro build
4611                 j++;
4612 #endif
4613 #ifndef HAVE_WAVESAT
4614               if (!strcmp (menu[i][j], "WiMAX.asp"))    //jump over WiMAX
4615                 j++;
4616 #else
4617               if (!wimaxwifi && !strcmp (menu[i][j], "WiMAX.asp"))      //jump over WiMAX
4618                 j++;
4619