4 Copyright (C) 2006-2008 Jonathan Zarate
10 #include <sys/sysinfo.h>
12 #include <arpa/inet.h>
16 // #define DEBUG_NOEXECSERVICE
17 // #define DEBUG_NVRAMSET(k, v) cprintf("nvram set %s=%s\n", k, v);
18 #define DEBUG_NVRAMSET(k, v) do { } while(0);
21 char *post_buf
= NULL
;
25 void asp_resmsg(int argc
, char **argv
);
28 static void wo_tomato(char *url
);
29 static void wo_update(char *url
);
30 static void wo_service(char *url
);
31 static void wo_logout(char *url
);
32 static void wo_shutdown(char *url
);
33 static void wo_nvcommit(char *url
);
36 // ----------------------------------------------------------------------------
39 void exec_service(const char *action
)
43 _dprintf("exec_service: %s\n", action
);
46 while ((!nvram_match("action_service", "")) && (i
-- > 0)) {
47 _dprintf("%s: waiting before %d\n", __FUNCTION__
, i
);
51 nvram_set("action_service", action
);
55 while ((nvram_match("action_service", (char *)action
)) && (i
-- > 0)) {
56 _dprintf("%s: waiting after %d\n", __FUNCTION__
, i
);
61 if (atoi(webcgi_safeget("_service_wait", ""))) {
63 while ((nvram_match("action_service", (char *)action)) && (i-- > 0)) {
64 _dprintf("%s: waiting after %d\n", __FUNCTION__, i);
71 void wi_generic_noid(char *url
, int len
, char *boundary
)
74 if (len
>= (32 * 1024)) {
75 syslog(LOG_WARNING
, "POST length exceeded maximum allowed");
79 if (!post_buf
) free(post_buf
);
80 if ((post_buf
= malloc(len
+ 1)) == NULL
) {
81 // syslog(LOG_CRIT, "Unable to allocate post buffer");
85 if (web_read_x(post_buf
, len
) != len
) {
89 _dprintf("post_buf=%s\n", post_buf
);
90 webcgi_init(post_buf
);
94 void wi_generic(char *url
, int len
, char *boundary
)
96 wi_generic_noid(url
, len
, boundary
);
100 static void wo_blank(char *url
)
102 web_puts("\n\n\n\n");
105 static void wo_favicon(char *url
)
107 if (nvram_match("web_favicon", "1")) {
108 send_header(200, NULL
, "image/vnd.microsoft.icon", 0);
112 send_error(404, NULL
, NULL
);
116 static void wo_cfe(char *url
)
118 do_file("/dev/mtd/0ro");
121 static void wo_nvram(char *url
)
123 web_pipecmd("nvram show", WOF_NONE
);
126 static void wo_iptables(char *url
)
128 web_pipecmd("iptables -nvL; iptables -t nat -nvL; iptables -t mangle -nvL", WOF_NONE
);
132 static void wo_spin(char *url)
136 strlcpy(s, nvram_safe_get("web_css"), sizeof(s));
137 strlcat(s, "_spin.gif", sizeof(s));
138 if (f_exists(s)) do_file(s);
139 else do_file("_spin.gif");
143 void common_redirect(void)
145 if (atoi(webcgi_safeget("_ajax", ""))) {
146 send_header(200, NULL
, mime_html
, 0);
150 redirect(webcgi_safeget("_redirect", "/"));
154 // ----------------------------------------------------------------------------
156 const struct mime_handler mime_handlers
[] = {
157 { "update.cgi", mime_javascript
, 0, wi_generic
, wo_update
, 1 },
158 { "tomato.cgi", NULL
, 0, wi_generic
, wo_tomato
, 1 },
160 { "debug.js", mime_javascript
, 5, wi_generic_noid
, wo_blank
, 1 }, // while debugging
161 { "cfe/*.bin", mime_binary
, 0, wi_generic
, wo_cfe
, 1 },
162 { "nvram/*.txt", mime_binary
, 0, wi_generic
, wo_nvram
, 1 },
163 { "ipt/*.txt", mime_binary
, 0, wi_generic
, wo_iptables
, 1 },
165 { "cfg/*.cfg", NULL
, 0, wi_generic
, wo_backup
, 1 },
166 { "cfg/restore.cgi", mime_html
, 0, wi_restore
, wo_restore
, 1 },
167 { "cfg/defaults.cgi", NULL
, 0, wi_generic
, wo_defaults
, 1 },
169 { "bwm/*.gz", NULL
, 0, wi_generic
, wo_bwmbackup
, 1 },
170 { "bwm/restore.cgi", NULL
, 0, wi_bwmrestore
, wo_bwmrestore
, 1 },
172 { "logs/view.cgi", NULL
, 0, wi_generic
, wo_viewlog
, 1 },
173 { "logs/*.txt", NULL
, 0, wi_generic
, wo_syslog
, 1 },
175 { "logout.asp", NULL
, 0, wi_generic
, wo_asp
, 1 },
176 { "clearcookies.asp", NULL
, 0, wi_generic
, wo_asp
, 1 },
178 // { "spin.gif", NULL, 0, wi_generic_noid, wo_spin, 1 },
180 { "**.asp", NULL
, 0, wi_generic_noid
, wo_asp
, 1 },
181 { "**.css", "text/css", 2, wi_generic_noid
, do_file
, 1 },
182 { "**.htm", mime_html
, 2, wi_generic_noid
, do_file
, 1 },
183 { "**.gif", "image/gif", 5, wi_generic_noid
, do_file
, 1 },
184 { "**.jpg", "image/jpeg", 5, wi_generic_noid
, do_file
, 1 },
185 { "**.png", "image/png", 5, wi_generic_noid
, do_file
, 1 },
186 { "**.js", mime_javascript
, 2, wi_generic_noid
, do_file
, 1 },
187 { "**.jsx", mime_javascript
, 0, wi_generic
, wo_asp
, 1 },
188 { "**.svg", "image/svg+xml", 2, wi_generic_noid
, do_file
, 1 },
189 { "**.txt", mime_plain
, 2, wi_generic_noid
, do_file
, 1 },
190 { "**.bin", mime_binary
, 0, wi_generic_noid
, do_file
, 1 },
191 { "**.bino", mime_octetstream
, 0, wi_generic_noid
, do_file
, 1 },
192 { "favicon.ico", NULL
, 5, wi_generic_noid
, wo_favicon
, 1 },
195 { "dhcpc.cgi", NULL
, 0, wi_generic
, wo_dhcpc
, 1 },
196 { "dhcpd.cgi", mime_javascript
, 0, wi_generic
, wo_dhcpd
, 1 },
197 { "nvcommit.cgi", NULL
, 0, wi_generic
, wo_nvcommit
, 1 },
198 { "ping.cgi", mime_javascript
, 0, wi_generic
, wo_ping
, 1 },
199 { "trace.cgi", mime_javascript
, 0, wi_generic
, wo_trace
, 1 },
200 { "upgrade.cgi", mime_html
, 0, wi_upgrade
, wo_flash
, 1 },
201 { "upnp.cgi", NULL
, 0, wi_generic
, wo_upnp
, 1 },
202 { "wakeup.cgi", NULL
, 0, wi_generic
, wo_wakeup
, 1 },
203 { "wlmnoise.cgi", mime_html
, 0, wi_generic
, wo_wlmnoise
, 1 },
204 { "wlradio.cgi", NULL
, 0, wi_generic
, wo_wlradio
, 1 },
205 { "resolve.cgi", mime_javascript
, 0, wi_generic
, wo_resolve
, 1 },
206 { "expct.cgi", mime_html
, 0, wi_generic
, wo_expct
, 1 },
207 { "service.cgi", NULL
, 0, wi_generic
, wo_service
, 1 },
208 { "logout.cgi", NULL
, 0, wi_generic
, wo_logout
, 0 },
209 { "shutdown.cgi", mime_html
, 0, wi_generic
, wo_shutdown
, 1 },
211 { "usbcmd.cgi", mime_javascript
, 0, wi_generic
, wo_usbcommand
, 1 }, //!!TB - USB
213 { "usb.cgi", NULL
, 0, wi_generic
, wo_usb
, 1 },
214 { "umount.cgi", NULL
, 0, wi_generic
, wo_umount
, 1 },
217 { "blackhole.cgi", NULL
, 0, wi_blackhole
, NULL
, 1 },
219 // { "test", mime_html, 0, wi_generic, wo_test, 1 },
220 { NULL
, NULL
, 0, NULL
, NULL
, 1 }
223 const aspapi_t aspapi
[] = {
224 { "activeroutes", asp_activeroutes
},
225 { "arplist", asp_arplist
},
226 { "bandwidth", asp_bandwidth
},
227 { "build_time", asp_build_time
},
228 { "cgi_get", asp_cgi_get
},
229 { "compmac", asp_compmac
},
230 { "ctcount", asp_ctcount
},
231 { "ctdump", asp_ctdump
},
232 { "ddnsx", asp_ddnsx
},
233 { "devlist", asp_devlist
},
234 { "dhcpc_time", asp_dhcpc_time
},
236 { "ident", asp_ident
},
237 { "lanip", asp_lanip
},
238 { "layer7", asp_layer7
},
239 { "link_uptime", asp_link_uptime
},
240 { "lipp", asp_lipp
},
241 { "netdev", asp_netdev
},
242 { "notice", asp_notice
},
244 { "nvram", asp_nvram
},
245 { "nvramseq", asp_nvramseq
},
246 { "psup", asp_psup
},
247 { "qrate", asp_qrate
},
248 { "resmsg", asp_resmsg
},
249 { "rrule", asp_rrule
},
250 { "statfs", asp_statfs
},
251 { "sysinfo", asp_sysinfo
},
252 { "time", asp_time
},
253 { "upnpinfo", asp_upnpinfo
},
254 { "version", asp_version
},
255 { "wanstatus", asp_wanstatus
},
256 { "wanup", asp_wanup
},
257 { "wlchannel", asp_wlchannel
},
258 { "wlclient", asp_wlclient
},
259 { "wlcrssi", asp_wlcrssi
},
260 { "wlnoise", asp_wlnoise
},
261 { "wlradio", asp_wlradio
},
262 { "wlscan", asp_wlscan
},
264 { "sharelist", asp_sharelist
},
266 { "usbdevices", asp_usbdevices
}, //!!TB - USB Support
270 // -----------------------------------------------------------------------------
272 const char *resmsg_get(void)
274 return webcgi_safeget("resmsg", "");
277 void resmsg_set(const char *msg
)
279 webcgi_set("resmsg", strdup(msg
)); // m ok
282 int resmsg_fread(const char *fname
)
287 f_read_string(fname
, s
, sizeof(s
));
288 if ((p
= strchr(s
, '\n')) != NULL
) *p
= 0;
296 void asp_resmsg(int argc
, char **argv
)
300 if ((p
= js_string(webcgi_safeget("resmsg", (argc
> 0) ? argv
[0] : ""))) == NULL
) return;
301 web_printf("\nresmsg='%s';\n", p
);
305 // ----------------------------------------------------------------------------
307 // verification... simple sanity checks. UI should verify all fields.
309 // todo: move and re-use for filtering - zzz
320 VT_NONE
, // no checking
321 VT_LENGTH
, // check length of string
322 VT_TEXT
, // strip \r, check length of string
323 VT_RANGE
, // expect an integer, check range
324 VT_IP
, // expect an ip address
325 VT_MAC
, // expect a mac address
326 VT_TEMP
// no checks, no commit
333 #define V_NONE VT_NONE, { }, { }
334 #define V_01 VT_RANGE, { .l = 0 }, { .l = 1 }
335 #define V_PORT VT_RANGE, { .l = 2 }, { .l = 65535 }
336 #define V_ONOFF VT_LENGTH, { .i = 2 }, { .i = 3 }
337 #define V_WORD VT_LENGTH, { .i = 1 }, { .i = 16 }
338 #define V_LENGTH(min, max) VT_LENGTH, { .i = min }, { .i = max }
339 #define V_TEXT(min, max) VT_TEXT, { .i = min }, { .i = max }
340 #define V_RANGE(min, max) VT_RANGE, { .l = min }, { .l = max }
341 #define V_IP VT_IP, { }, { }
342 #define V_OCTET VT_RANGE, { .l = 0 }, { .l = 255 }
343 #define V_NUM VT_RANGE, { .l = 0 }, { .l = 0x7FFFFFFF }
344 #define V_TEMP VT_TEMP, { }, { }
346 static const nvset_t nvset_list
[] = {
349 { "router_name", V_LENGTH(0, 32) },
350 { "wan_hostname", V_LENGTH(0, 32) },
351 { "wan_domain", V_LENGTH(0, 32) },
354 { "tm_tz", V_LENGTH(1, 64) }, // PST8PDT
355 { "tm_sel", V_LENGTH(1, 64) }, // PST8PDT
357 { "ntp_updates", V_RANGE(-1, 24) },
358 { "ntp_tdod", V_01
},
359 { "ntp_server", V_LENGTH(1, 150) }, // x y z
360 { "ntp_kiss", V_LENGTH(0, 255) },
363 { "dhcpd_static", V_LENGTH(0, 53*101) }, // 53 (max chars per entry) x 100 entries
366 { "ddnsx0", V_LENGTH(0, 2048) },
367 { "ddnsx1", V_LENGTH(0, 2048) },
368 { "ddnsx0_cache", V_LENGTH(0, 1) }, // only to clear
369 { "ddnsx1_cache", V_LENGTH(0, 1) },
370 { "ddnsx_ip", V_LENGTH(0, 32) },
374 { "wan_proto", V_LENGTH(1, 16) }, // disabled, dhcp, static, pppoe, pptp, l2tp
375 { "wan_ipaddr", V_IP
},
376 { "wan_netmask", V_IP
},
377 { "wan_gateway", V_IP
},
378 { "hb_server_ip", V_LENGTH(0, 32) },
379 { "l2tp_server_ip", V_IP
},
380 { "pptp_server_ip", V_IP
},
381 { "ppp_username", V_LENGTH(0, 50) },
382 { "ppp_passwd", V_LENGTH(0, 50) },
383 { "ppp_service", V_LENGTH(0, 50) },
384 { "ppp_demand", V_01
},
385 { "ppp_idletime", V_RANGE(0, 1440) },
386 { "ppp_redialperiod", V_RANGE(1, 86400) },
387 { "mtu_enable", V_01
},
388 { "wan_mtu", V_RANGE(576, 1500) },
391 { "lan_ipaddr", V_IP
},
392 { "lan_netmask", V_IP
},
393 { "lan_gateway", V_IP
},
394 { "wan_dns", V_LENGTH(0, 50) }, // ip ip ip
395 { "lan_proto", V_WORD
}, // static, dhcp
396 { "dhcp_start", V_RANGE(1, 254) }, // remove !
397 { "dhcp_num", V_RANGE(1, 255) }, // remove !
398 { "dhcpd_startip", V_IP
},
399 { "dhcpd_endip", V_IP
},
400 { "dhcp_lease", V_RANGE(1, 10080) },
401 { "wan_wins", V_IP
},
404 { "wl_radio", V_01
},
405 { "wl_mode", V_LENGTH(2, 3) }, // ap, sta, wet, wds
406 { "wl_net_mode", V_LENGTH(5, 8) }, // disabled, mixed, b-only, g-only, bg-mixed, n-only [speedbooster]
407 { "wl_ssid", V_LENGTH(1, 32) },
408 { "wl_closed", V_01
},
409 { "wl_channel", V_RANGE(1, 14) },
414 { "security_mode2", V_LENGTH(1, 32) }, // disabled, radius, wep, wpa_personal, wpa_enterprise, wpa2_personal, wpa2_enterprise
415 { "wl_radius_ipaddr", V_IP
},
416 { "wl_radius_port", V_PORT
},
417 { "wl_radius_key", V_LENGTH(1, 64) },
418 { "wl_wep_bit", V_RANGE(64, 128) }, // 64 or 128
419 { "wl_passphrase", V_LENGTH(0, 20) },
420 { "wl_key", V_RANGE(1, 4) },
421 { "wl_key1", V_LENGTH(0, 26) },
422 { "wl_key2", V_LENGTH(0, 26) },
423 { "wl_key3", V_LENGTH(0, 26) },
424 { "wl_key4", V_LENGTH(0, 26) },
425 { "wl_crypto", V_LENGTH(3, 8) }, // tkip, aes, tkip+aes
426 { "wl_wpa_psk", V_LENGTH(8, 64) },
427 { "wl_wpa_gtk_rekey", V_RANGE(60, 7200) },
429 { "wl_lazywds", V_01
},
430 { "wl_wds", V_LENGTH(0, 180) }, // mac mac mac (x 10)
432 { "security_mode", V_LENGTH(1, 32) }, // disabled, radius, wpa, psk,wep, wpa2, psk2, wpa wpa2, psk psk2
433 { "wds_enable", V_01
},
434 { "wl_gmode", V_RANGE(-1, 6) },
435 { "wl_wep", V_LENGTH(1, 32) }, // off, on, restricted,tkip,aes,tkip+aes
436 { "wl_akm", V_LENGTH(0, 32) }, // wpa, wpa2, psk, psk2, wpa wpa2, psk psk2, ""
437 { "wl_auth_mode", V_LENGTH(4, 6) }, // none, radius
440 { "wl_nmode", V_NONE
},
441 { "wl_nreqd", V_NONE
},
445 { "wl_macmode", V_NONE
}, // allow, deny, disabled
446 { "wl_maclist", V_LENGTH(0, 18*101) }, // 18 x 100 (11:22:33:44:55:66 ...)
447 { "macnames", V_LENGTH(0, 62*101) }, // 62 (12+1+48+1) x 50 (112233445566<..>) todo: re-use -- zzz
450 { "ct_max", V_RANGE(128, 10240) },
451 { "ct_tcp_timeout", V_LENGTH(20, 70) },
452 { "ct_udp_timeout", V_LENGTH(5, 15) },
453 { "nf_ttl", V_RANGE(-10, 10) },
461 { "dhcpd_slt", V_RANGE(-1, 43200) }, // -1=infinite, 0=follow normal lease time, >=1 custom
462 { "dhcpd_dmdns", V_01
},
463 { "dhcpd_lmax", V_NUM
},
464 { "dns_addget", V_01
},
465 { "dns_intcpt", V_01
},
466 { "dhcpc_minpkt", V_01
},
467 { "dnsmasq_custom", V_TEXT(0, 2048) },
468 // { "dnsmasq_norw", V_01 },
470 // advanced-firewall // todo: moveme
471 { "block_wan", V_01
},
472 { "multicast_pass", V_01
},
473 { "block_loopback", V_01
},
474 { "nf_loopback", V_NUM
},
475 { "ne_syncookies", V_01
},
479 { "wait_time", V_RANGE(3, 20) },
480 { "wan_speed", V_RANGE(0, 4) },
483 { "mac_wan", V_LENGTH(0, 17) },
484 { "mac_wl", V_LENGTH(0, 17) },
487 { "routes_static", V_LENGTH(0, 2048) },
488 { "lan_stp", V_RANGE(0, 1) },
489 { "wk_mode", V_LENGTH(1, 32) }, // gateway, router
490 { "dr_setting", V_RANGE(0, 3) },
491 { "dr_lan_tx", V_LENGTH(0, 32) },
492 { "dr_lan_rx", V_LENGTH(0, 32) },
493 { "dr_wan_tx", V_LENGTH(0, 32) },
494 { "dr_wan_rx", V_LENGTH(0, 32) },
497 { "wl_afterburner", V_LENGTH(2, 4) }, // off, on, auto
499 { "wl_rateset", V_LENGTH(2, 7) }, // all, default, 12
500 { "wl_rate", V_RANGE(0, 54 * 1000 * 1000) },
501 { "wl_mrate", V_RANGE(0, 54 * 1000 * 1000) },
502 { "wl_gmode_protection",V_LENGTH(3, 4) }, // off, auto
503 { "wl_frameburst", V_ONOFF
}, // off, on
504 { "wl_bcn", V_RANGE(1, 65535) },
505 { "wl_dtim", V_RANGE(1, 255) },
506 { "wl_frag", V_RANGE(256, 2346) },
507 { "wl_rts", V_RANGE(0, 2347) },
508 { "wl_ap_isolate", V_01
},
509 { "wl_plcphdr", V_LENGTH(4, 5) }, // long, short
510 { "wl_antdiv", V_RANGE(0, 3) },
511 { "wl_txant", V_RANGE(0, 3) },
512 { "wl_txpwr", V_RANGE(0, 255) },
513 { "wl_wme", V_ONOFF
}, // off, on
514 { "wl_wme_no_ack", V_ONOFF
}, // off, on
515 { "wl_maxassoc", V_RANGE(0, 255) },
516 { "wl_distance", V_LENGTH(0, 5) }, // "", 1-99999
517 { "wlx_hpamp", V_01
},
518 { "wlx_hperx", V_01
},
519 { "wl_reg_mode", V_LENGTH(1, 3) }, // !!TB - Regulatory: off, h, d
522 { "wl_nmode_protection",V_WORD
, }, // off, auto
523 { "wl_nmcsidx", V_RANGE(-2, 15), }, // -2 - 15
529 { "wd_atp0", V_LENGTH(1, 48) },
530 { "wd_atp1", V_LENGTH(0, 48) },
531 { "wd_atp2", V_LENGTH(0, 48) },
532 { "wd_atp3", V_LENGTH(0, 48) },
533 { "wd_atp4", V_LENGTH(0, 48) },
542 { "dmz_enable", V_01
},
543 { "dmz_ipaddr", V_LENGTH(0, 15) },
544 { "dmz_sip", V_LENGTH(0, 32) },
547 { "upnp_enable", V_01
},
548 { "upnp_mnp", V_01
},
549 // { "upnp_config", V_01 },
550 { "upnp_ssdp_interval", V_RANGE(10, 9999) },
551 { "upnp_max_age", V_RANGE(5, 9999) },
554 { "portforward", V_LENGTH(0, 4096) },
557 { "trigforward", V_LENGTH(0, 4096) },
560 // access restriction
561 { "rruleN", V_RANGE(0, 49) },
562 // { "rrule##", V_LENGTH(0, 2048) }, // in save_variables()
565 { "http_enable", V_01
},
566 { "https_enable", V_01
},
567 { "https_crt_save", V_01
},
568 { "https_crt_cn", V_LENGTH(0, 64) },
569 { "https_crt_gen", V_TEMP
},
570 { "remote_management", V_01
},
571 { "remote_mgt_https", V_01
},
572 { "http_lanport", V_PORT
},
573 { "https_lanport", V_PORT
},
574 { "web_wl_filter", V_01
},
575 { "web_favicon", V_01
},
576 { "web_css", V_LENGTH(1, 32) },
577 { "http_wanport", V_PORT
},
578 { "telnetd_eas", V_01
},
579 { "telnetd_port", V_PORT
},
580 { "sshd_eas", V_01
},
581 { "sshd_pass", V_01
},
582 { "sshd_port", V_PORT
},
583 { "sshd_remote", V_01
},
584 { "sshd_rport", V_PORT
},
585 { "sshd_authkeys", V_TEXT(0, 4096) },
586 { "rmgt_sip", V_LENGTH(0, 32) },
589 { "rstats_enable", V_01
},
590 { "rstats_path", V_LENGTH(0, 48) },
591 { "rstats_stime", V_RANGE(1, 168) },
592 { "rstats_offset", V_RANGE(1, 31) },
593 { "rstats_exclude", V_LENGTH(0, 64) },
594 { "rstats_sshut", V_01
},
595 { "rstats_bak", V_01
},
598 { "sesx_led", V_RANGE(0, 255) }, // amber, white, aoss
599 { "sesx_b0", V_RANGE(0, 4) }, // 0-4: toggle wireless, reboot, shutdown, script
600 { "sesx_b1", V_RANGE(0, 4) }, // "
601 { "sesx_b2", V_RANGE(0, 4) }, // "
602 { "sesx_b3", V_RANGE(0, 4) }, // "
603 { "sesx_script", V_TEXT(0, 1024) }, //
606 { "debug_nocommit", V_01
},
607 { "debug_cprintf", V_01
},
608 { "debug_cprintf_file", V_01
},
609 // { "debug_keepfiles", V_01 },
610 { "debug_ddns", V_01
},
611 { "debug_norestart", V_TEXT(0, 128) },
612 { "console_loglevel", V_RANGE(1, 8) },
613 { "t_cafree", V_01
},
614 { "t_hidelr", V_01
},
617 { "sch_rboot", V_TEXT(0, 64) },
618 { "sch_rcon", V_TEXT(0, 64) },
619 { "sch_c1", V_TEXT(0, 64) },
620 { "sch_c1_cmd", V_TEXT(0, 2048) },
621 { "sch_c2", V_TEXT(0, 64) },
622 { "sch_c2_cmd", V_TEXT(0, 2048) },
623 { "sch_c3", V_TEXT(0, 64) },
624 { "sch_c3_cmd", V_TEXT(0, 2048) },
627 { "script_init", V_TEXT(0, 4096) },
628 { "script_shut", V_TEXT(0, 4096) },
629 { "script_fire", V_TEXT(0, 8192) },
630 { "script_wanup", V_TEXT(0, 4096) },
633 { "log_remote", V_01
},
634 { "log_remoteip", V_IP
},
635 { "log_remoteport", V_PORT
},
636 { "log_file", V_01
},
637 { "log_limit", V_RANGE(0, 2400) },
638 { "log_in", V_RANGE(0, 3) },
639 { "log_out", V_RANGE(0, 3) },
640 { "log_mark", V_RANGE(0, 1440) },
641 { "log_events", V_TEXT(0, 32) }, // "acre,crond,ntp"
644 { "cifs1", V_LENGTH(5, 384) },
645 { "cifs2", V_LENGTH(5, 384) },
648 { "jffs2_on", V_01
},
649 { "jffs2_exec", V_LENGTH(0, 64) },
650 { "jffs2_format", V_01
},
653 { "usb_enable", V_01
},
654 { "usb_uhci", V_01
},
655 { "usb_ohci", V_01
},
656 { "usb_usb2", V_01
},
657 { "usb_storage", V_01
},
658 { "usb_printer", V_01
},
659 { "usb_printer_bidirect", V_01
},
660 { "usb_fs_ext3", V_01
},
661 { "usb_fs_fat", V_01
},
662 { "usb_automount", V_01
},
663 { "script_usbhotplug", V_TEXT(0, 2048) },
664 { "script_usbmount", V_TEXT(0, 2048) },
665 { "script_usbumount", V_TEXT(0, 2048) },
669 { "ftp_enable", V_RANGE(0, 2) },
670 { "ftp_super", V_01
},
671 { "ftp_anonymous", V_RANGE(0, 3) },
672 { "ftp_dirlist", V_RANGE(0, 2) },
673 { "ftp_port", V_PORT
},
674 { "ftp_max", V_RANGE(0, 12) },
675 { "ftp_ipmax", V_RANGE(0, 12) },
676 { "ftp_staytimeout", V_RANGE(0, 65535) },
677 { "ftp_rate", V_RANGE(0, 99999) },
678 { "ftp_anonrate", V_RANGE(0, 99999) },
679 { "ftp_anonroot", V_LENGTH(0, 256) },
680 { "ftp_pubroot", V_LENGTH(0, 256) },
681 { "ftp_pvtroot", V_LENGTH(0, 256) },
682 { "ftp_users", V_LENGTH(0, 4096) },
683 { "ftp_custom", V_TEXT(0, 2048) },
687 #ifdef TCONFIG_SAMBASRV
689 { "smbd_enable", V_RANGE(0, 2) },
690 { "smbd_wgroup", V_LENGTH(0, 20) },
691 { "smbd_cpage", V_LENGTH(0, 4) },
692 { "smbd_cset", V_LENGTH(0, 20) },
693 { "smbd_loglevel", V_RANGE(0, 100) },
694 { "smbd_custom", V_TEXT(0, 2048) },
695 { "smbd_autoshare", V_RANGE(0, 3) },
696 { "smbd_shares", V_LENGTH(0, 4096) },
697 { "smbd_user", V_LENGTH(0, 50) },
698 { "smbd_passwd", V_LENGTH(0, 50) },
702 { "qos_enable", V_01
},
707 { "qos_icmp", V_01
},
708 { "qos_reset", V_01
},
709 { "qos_obw", V_RANGE(10, 999999) },
710 { "qos_ibw", V_RANGE(10, 999999) },
711 { "qos_orules", V_LENGTH(0, 4096) },
712 { "qos_default", V_RANGE(0, 9) },
713 { "qos_pfifo", V_01
}, // !!TB
714 { "qos_irates", V_LENGTH(0, 128) },
715 { "qos_orates", V_LENGTH(0, 128) },
717 { "ne_vegas", V_01
},
718 { "ne_valpha", V_NUM
},
719 { "ne_vbeta", V_NUM
},
720 { "ne_vgamma", V_NUM
},
742 port_flow_control_1 0,1
743 port_rate_limit_1 0-8
745 port_flow_control_2 0,1
746 port_rate_limit_2 0-8
748 port_flow_control_3 0,1
749 port_rate_limit_3 0-8
751 port_flow_control_4 0,1
752 port_rate_limit_4 0-8
760 static int save_variables(int write
)
770 static const char *msgf
= "The field \"%s\" is invalid. Please report this problem.";
773 for (v
= nvset_list
; v
->name
; ++v
) {
774 // _dprintf("[%s] %p\n", v->name, webcgi_get((char*)v->name));
775 if ((p
= webcgi_get((char*)v
->name
)) == NULL
) continue;
779 p
= unix_string(p
); // NOTE: p = malloc'd
783 if ((n
< v
->va
.i
) || (n
> v
->vb
.i
)) ok
= 0;
786 l
= strtol(p
, &e
, 10);
787 if ((p
== e
) || (*e
) || (l
< v
->va
.l
) || (l
> v
->vb
.l
)) ok
= 0;
790 if ((sscanf(p
, "%3u.%3u.%3u.%3u", &u
[0], &u
[1], &u
[2], &u
[3]) != 4) ||
791 (u
[0] > 255) || (u
[1] > 255) || (u
[2] > 255) || (u
[3] > 255)) ok
= 0;
794 if ((sscanf(p
, "%2x:%2x:%2x:%2x:%2x:%2x", &u
[0], &u
[1], &u
[2], &u
[3], &u
[4], &u
[5]) != 6) ||
795 (u
[0] > 255) || (u
[1] > 255) || (u
[2] > 255) || (u
[3] > 255) || (u
[4] > 255) || (u
[5] > 255)) ok
= 0;
802 if (v
->vtype
== VT_TEXT
) free(p
);
804 sprintf(s
, msgf
, v
->name
);
809 if (!nvram_match((char *)v
->name
, p
)) {
810 if (v
->vtype
!= VT_TEMP
) dirty
= 1;
811 nvram_set(v
->name
, p
);
814 if (v
->vtype
== VT_TEXT
) free(p
);
821 if (((p1
= webcgi_get("set_password_1")) != NULL
) && (strcmp(p1
, "**********") != 0)) {
822 if (((p2
= webcgi_get("set_password_2")) != NULL
) && (strcmp(p1
, p2
) == 0)) {
823 if ((write
) && (!nvram_match("http_passwd", p1
))) {
825 nvram_set("http_passwd", p1
);
829 sprintf(s
, msgf
, "password");
835 for (n
= 0; n
< 50; ++n
) {
836 sprintf(s
, "rrule%d", n
);
837 if ((p
= webcgi_get(s
)) != NULL
) {
838 if (strlen(p
) > 2048) {
843 if ((write
) && (!nvram_match(s
, p
))) {
850 return (write
) ? dirty
: 1;
853 static void wo_tomato(char *url
)
862 // _dprintf("tomato.cgi\n");
864 red
= webcgi_safeget("_redirect", "");
865 if (!*red
) send_header(200, NULL
, mime_html
, 0);
867 commit
= atoi(webcgi_safeget("_commit", "1"));
868 ajax
= atoi(webcgi_safeget("_ajax", "0"));
870 nvset
= atoi(webcgi_safeget("_nvset", "1"));
872 if (!save_variables(0)) {
874 web_printf("@msg:%s", resmsg_get());
877 parse_asp("error.asp");
881 commit
= save_variables(1) && commit
;
883 resmsg_set("Settings saved.");
886 rboot
= atoi(webcgi_safeget("_reboot", "0"));
888 parse_asp("reboot.asp");
892 web_printf("@msg:%s", resmsg_get());
894 else if (atoi(webcgi_safeget("_moveip", "0"))) {
895 parse_asp("saved-moved.asp");
898 parse_asp("saved.asp");
903 _dprintf("commit from tomato.cgi\n");
904 if (!nvram_match("debug_nocommit", "1")) {
909 if ((v
= webcgi_get("_service")) != NULL
) {
911 if (ajax
) web_printf(" Some services are being restarted...");
924 for (i
= atoi(webcgi_safeget("_sleep", "0")); i
> 0; --i
) sleep(1);
926 if (*red
) redirect(red
);
936 // ----------------------------------------------------------------------------
939 static void wo_update(char *url
)
947 if ((name
= webcgi_get("exec")) != NULL
) {
948 for (api
= aspapi
; api
->name
; ++api
) {
949 if (strcmp(api
->name
, name
) == 0) {
950 for (argc
= 0; argc
< 16; ++argc
) {
951 sprintf(s
, "arg%d", argc
);
952 if ((argv
[argc
] = (char *)webcgi_get(s
)) == NULL
) break;
954 api
->exec(argc
, argv
);
961 static void wo_service(char *url
)
965 exec_service(webcgi_safeget("_service", ""));
967 if ((n
= atoi(webcgi_safeget("_sleep", "2"))) <= 0) n
= 2;
976 static void wo_login(char *url)
981 u = webcgi_safeget("user", "");
982 p = webcgi_safeget("pass", "");
985 if ((strcmp(u, "root") == 0) || (strcmp(u, "admin") == 0)) {
986 if (strcmp(p, nvram_safe_get("http_password")) == 0) {
987 nvram_set("web_logout", "0");
994 web_printf("<form action='login'><input type='text' name='user'><input type='text' name='pass'></form>");
999 void gen_sessnum(void)
1003 sprintf(s
, "%llx", (unsigned long long)time(NULL
) * rand());
1004 nvram_set("web_sess", s
);
1008 static void wo_logout(char *url
)
1012 // doesn't work with all browsers...
1014 if (((user_agent
) && (strstr(user_agent
, "Opera") != NULL
))) {
1015 sprintf(s
, "%llx", (unsigned long long)time(NULL
) * rand());
1016 send_authenticate(s
);
1019 send_authenticate(NULL
);
1031 p
= nvram_safe_get("web_out");
1032 c
= inet_ntoa(clientsai
.sin_addr
);
1033 if ((c
!= NULL
) && (!find_word(p
, c
))) {
1034 while (strlen(p
) > 128) {
1040 sprintf(s
, "%s,%s", p
, c
);
1041 nvram_set("web_out", s
);
1044 nvram_set("web_out", c
);
1046 nvram_unset("web_outx");
1051 static void wo_shutdown(char *url
)
1053 parse_asp("shutdown.asp");
1060 static void wo_nvcommit(char *url
)
1062 parse_asp("saved.asp");