VPN GUI frontend
[tomato.git] / release / src / router / httpd / misc.c
blobe47118b8a748d594db6121a7c7379936bca608a7
1 /*
3 Tomato Firmware
4 Copyright (C) 2006-2008 Jonathan Zarate
6 */
8 #include "tomato.h"
10 #include <ctype.h>
11 #include <sys/sysinfo.h>
12 #include <sys/stat.h>
13 #include <sys/ioctl.h>
14 #include <net/if.h>
15 #include <fcntl.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <time.h>
22 #include <sys/statfs.h>
23 #include <netdb.h>
24 #include <net/route.h>
26 #include <wlioctl.h>
27 #include <wlutils.h>
30 int wait_file_exists(const char *name, int max, int invert)
32 while (max-- > 0) {
33 if (f_exists(name) ^ invert) return 1;
34 sleep(1);
36 return 0;
39 // to javascript-safe string
40 char *js_string(const char *s)
42 unsigned char c;
43 char *buffer;
44 char *b;
46 if ((buffer = malloc((strlen(s) * 4) + 1)) != NULL) {
47 b = buffer;
48 while ((c = *s++) != 0) {
49 if ((c == '"') || (c == '\'') || (c == '\\') || (!isprint(c))) {
50 b += sprintf(b, "\\x%02x", c);
52 else {
53 *b++ = c;
56 *b = 0;
58 return buffer;
61 // to html-safe string
62 char *html_string(const char *s)
64 unsigned char c;
65 char *buffer;
66 char *b;
68 if ((buffer = malloc((strlen(s) * 6) + 1)) != NULL) {
69 b = buffer;
70 while ((c = *s++) != 0) {
71 if ((c == '&') || (c == '<') || (c == '>') || (c == '"') || (c == '\'') || (!isprint(c))) {
72 b += sprintf(b, "&#%d;", c);
74 else {
75 *b++ = c;
78 *b = 0;
80 return buffer;
83 // removes \r
84 char *unix_string(const char *s)
86 char *buffer;
87 char *b;
88 char c;
90 if ((buffer = malloc(strlen(s) + 1)) != NULL) {
91 b = buffer;
92 while ((c = *s++) != 0)
93 if (c != '\r') *b++ = c;
94 *b = 0;
96 return buffer;
99 // # days, ##:##:##
100 char *reltime(char *buf, time_t t)
102 int days;
103 int m;
105 if (t < 0) t = 0;
106 days = t / 86400;
107 m = t / 60;
108 sprintf(buf, "%d day%s, %02d:%02d:%02d", days, ((days==1) ? "" : "s"), ((m / 60) % 24), (m % 60), (int)(t % 60));
109 return buf;
112 int get_client_info(char *mac, char *ifname)
114 FILE *f;
115 char s[256];
116 char ips[16];
119 # cat /proc/net/arp
120 IP address HW type Flags HW address Mask Device
121 192.168.0.1 0x1 0x2 00:01:02:03:04:05 * vlan1
122 192.168.1.5 0x1 0x2 00:05:06:07:08:09 * br0
125 if ((f = fopen("/proc/net/arp", "r")) != NULL) {
126 while (fgets(s, sizeof(s), f)) {
127 if (sscanf(s, "%15s %*s %*s %17s %*s %16s", ips, mac, ifname) == 3) {
128 if (inet_addr(ips) == clientsai.sin_addr.s_addr) {
129 fclose(f);
130 return 1;
134 fclose(f);
136 return 0;
143 // <% lanip(mode); %>
144 // <mode>
145 // 1 return first 3 octets (192.168.1)
146 // 2 return last octet (1)
147 // else return full (192.168.1.1)
149 void asp_lanip(int argc, char **argv)
151 char *nv, *p;
152 char s[64];
153 char mode;
155 mode = argc ? *argv[0] : 0;
157 if ((nv = nvram_get("lan_ipaddr")) != NULL) {
158 strcpy(s, nv);
159 if ((p = strrchr(s, '.')) != NULL) {
160 *p = 0;
161 web_puts((mode == '1') ? s : (mode == '2') ? (p + 1) : nv);
166 void asp_lipp(int argc, char **argv)
168 char *one = "1";
169 asp_lanip(1, &one);
172 // <% psup(process); %>
173 // returns 1 if process is running
175 void asp_psup(int argc, char **argv)
177 if (argc == 1) web_printf("%d", pidof(argv[0]) > 0);
180 void asp_vpn_ciphers(int argc, char **argv)
182 #ifdef TCONFIG_OPENVPN
183 FILE *fp;
184 char buffer[16];
186 fp=popen("/usr/sbin/openvpn --show-ciphers | grep -v \"^$\" | awk '{print($1)}'", "r");
187 if (fp == NULL)
188 return;
190 while (fgets(&buffer[0], 16, fp) != NULL)
191 web_printf(",['%s','%s']", strtok(&buffer[0],"\n"), &buffer[0]);
193 pclose(fp);
194 #endif
198 # cat /proc/meminfo
199 total: used: free: shared: buffers: cached:
200 Mem: 14872576 12877824 1994752 0 1236992 4837376
201 Swap: 0 0 0
202 MemTotal: 14524 kB
203 MemFree: 1948 kB
204 MemShared: 0 kB
205 Buffers: 1208 kB
206 Cached: 4724 kB
207 SwapCached: 0 kB
208 Active: 4364 kB
209 Inactive: 2952 kB
210 HighTotal: 0 kB
211 HighFree: 0 kB
212 LowTotal: 14524 kB
213 LowFree: 1948 kB
214 SwapTotal: 0 kB
215 SwapFree: 0 kB
219 typedef struct {
220 unsigned long total;
221 unsigned long free;
222 unsigned long shared;
223 unsigned long buffers;
224 unsigned long cached;
225 unsigned long swaptotal;
226 unsigned long swapfree;
227 unsigned long maxfreeram;
228 } meminfo_t;
230 static int get_memory(meminfo_t *m)
232 FILE *f;
233 char s[128];
234 int ok = 0;
236 if ((f = fopen("/proc/meminfo", "r")) != NULL) {
237 while (fgets(s, sizeof(s), f)) {
238 if (strncmp(s, "Mem:", 4) == 0) {
239 if (sscanf(s + 6, "%ld %*d %ld %ld %ld %ld", &m->total, &m->free, &m->shared, &m->buffers, &m->cached) == 5)
240 ++ok;
242 else if (strncmp(s, "SwapTotal:", 10) == 0) {
243 m->swaptotal = strtoul(s + 12, NULL, 10) * 1024;
244 ++ok;
246 else if (strncmp(s, "SwapFree:", 9) == 0) {
247 m->swapfree = strtoul(s + 11, NULL, 10) * 1024;
248 ++ok;
249 break;
252 fclose(f);
254 if (ok != 3) {
255 memset(m, 0, sizeof(*m));
256 return 0;
258 m->maxfreeram = m->free;
259 if (nvram_match("t_cafree", "1")) m->maxfreeram += m->cached;
260 return 1;
263 void asp_sysinfo(int argc, char **argv)
265 struct sysinfo si;
266 char s[64];
267 meminfo_t mem;
269 web_puts("\nsysinfo = {\n");
270 sysinfo(&si);
271 get_memory(&mem);
272 web_printf(
273 "\tuptime: %ld,\n"
274 "\tuptime_s: '%s',\n"
275 "\tloads: [%ld, %ld, %ld],\n"
276 "\ttotalram: %ld,\n"
277 "\tfreeram: %ld,\n"
278 "\tshareram: %ld,\n"
279 "\tbufferram: %ld,\n"
280 "\tcached: %ld,\n"
281 "\ttotalswap: %ld,\n"
282 "\tfreeswap: %ld,\n"
283 "\ttotalfreeram: %ld,\n"
284 "\tprocs: %d\n",
285 si.uptime,
286 reltime(s, si.uptime),
287 si.loads[0], si.loads[1], si.loads[2],
288 mem.total, mem.free,
289 mem.shared, mem.buffers, mem.cached,
290 mem.swaptotal, mem.swapfree,
291 mem.maxfreeram,
292 si.procs);
293 web_puts("};\n");
296 void asp_activeroutes(int argc, char **argv)
298 FILE *f;
299 char s[512];
300 char dev[17];
301 unsigned long dest;
302 unsigned long gateway;
303 unsigned long flags;
304 unsigned long mask;
305 unsigned metric;
306 struct in_addr ia;
307 char s_dest[16];
308 char s_gateway[16];
309 char s_mask[16];
310 int n;
312 web_puts("\nactiveroutes = [");
313 n = 0;
314 if ((f = fopen("/proc/net/route", "r")) != NULL) {
315 while (fgets(s, sizeof(s), f)) {
316 if (sscanf(s, "%16s%lx%lx%lx%*s%*s%u%lx", dev, &dest, &gateway, &flags, &metric, &mask) != 6) continue;
317 if ((flags & RTF_UP) == 0) continue;
318 if (dest != 0) {
319 ia.s_addr = dest;
320 strcpy(s_dest, inet_ntoa(ia));
322 else {
323 strcpy(s_dest, "default");
325 if (gateway != 0) {
326 ia.s_addr = gateway;
327 strcpy(s_gateway, inet_ntoa(ia));
329 else {
330 strcpy(s_gateway, "*");
332 ia.s_addr = mask;
333 strcpy(s_mask, inet_ntoa(ia));
334 web_printf("%s['%s','%s','%s','%s',%u]", n ? "," : "", dev, s_dest, s_gateway, s_mask, metric);
335 ++n;
337 fclose(f);
339 web_puts("];\n");
342 void asp_cgi_get(int argc, char **argv)
344 const char *v;
345 int i;
347 for (i = 0; i < argc; ++i) {
348 v = webcgi_get(argv[i]);
349 if (v) web_puts(v);
353 void asp_time(int argc, char **argv)
355 time_t t;
356 char s[64];
358 t = time(NULL);
359 if (t < Y2K) {
360 web_puts("Not Available");
362 else {
363 strftime(s, sizeof(s), "%a, %d %b %Y %H:%M:%S %z", localtime(&t));
364 web_puts(s);
368 void asp_wanup(int argc, char **argv)
370 web_puts(check_wanup() ? "1" : "0");
373 void asp_wanstatus(int argc, char **argv)
375 const char *p;
377 if ((using_dhcpc()) && (f_exists("/var/lib/misc/dhcpc.renewing"))) {
378 p = "Renewing...";
380 else if (check_wanup()) {
381 p = "Connected";
383 else if (f_exists("/var/lib/misc/wan.connecting")) {
384 p = "Connecting...";
386 else {
387 p = "Disconnected";
389 web_puts(p);
392 void asp_link_uptime(int argc, char **argv)
394 struct sysinfo si;
395 char buf[64];
396 long uptime;
398 buf[0] = '-';
399 buf[1] = 0;
400 if (check_wanup()) {
401 sysinfo(&si);
402 if (f_read("/var/lib/misc/wantime", &uptime, sizeof(uptime)) == sizeof(uptime)) {
403 reltime(buf, si.uptime - uptime);
406 web_puts(buf);
409 void asp_bandwidth(int argc, char **argv)
411 char *name;
412 int sig;
414 if ((nvram_match("rstats_enable", "1")) && (argc == 1)) {
415 if (strcmp(argv[0], "speed") == 0) {
416 sig = SIGUSR1;
417 name = "/var/spool/rstats-speed.js";
419 else {
420 sig = SIGUSR2;
421 name = "/var/spool/rstats-history.js";
423 unlink(name);
424 killall("rstats", sig);
425 wait_file_exists(name, 5, 0);
426 do_file(name);
427 unlink(name);
431 void asp_rrule(int argc, char **argv)
433 char s[32];
434 int i;
436 i = nvram_get_int("rruleN");
437 sprintf(s, "rrule%d", i);
438 web_puts("\nrrule = '");
439 web_putj(nvram_safe_get(s));
440 web_printf("';\nrruleN = %d;\n", i);
443 void asp_compmac(int argc, char **argv)
445 char mac[32];
446 char ifname[32];
448 if (get_client_info(mac, ifname)) {
449 web_puts(mac);
453 void asp_ident(int argc, char **argv)
455 web_puts(nvram_safe_get("router_name"));
458 void asp_statfs(int argc, char **argv)
460 struct statfs sf;
462 if (argc != 2) return;
464 // used for /cifs/, /jffs/... if it returns squashfs type, assume it's not mounted
465 if ((statfs(argv[0], &sf) != 0) || (sf.f_type == 0x73717368))
466 memset(&sf, 0, sizeof(sf));
468 web_printf(
469 "\n%s = {\n"
470 "\tsize: %llu,\n"
471 "\tfree: %llu\n"
472 "};\n",
473 argv[1],
474 ((uint64_t)sf.f_bsize * sf.f_blocks),
475 ((uint64_t)sf.f_bsize * sf.f_bfree));
478 void asp_notice(int argc, char **argv)
480 char s[256];
481 char buf[2048];
483 if (argc != 1) return;
484 snprintf(s, sizeof(s), "/var/notice/%s", argv[0]);
485 if (f_read_string(s, buf, sizeof(buf)) <= 0) return;
486 web_putj(buf);
489 void wo_wakeup(char *url)
491 char *mac;
492 char *p;
493 char *end;
495 if ((mac = webcgi_get("mac")) != NULL) {
496 end = mac + strlen(mac);
497 while (mac < end) {
498 while ((*mac == ' ') || (*mac == '\t') || (*mac == '\r') || (*mac == '\n')) ++mac;
499 if (*mac == 0) break;
501 p = mac;
502 while ((*p != 0) && (*p != ' ') && (*p != '\r') && (*p != '\n')) ++p;
503 *p = 0;
505 eval("ether-wake", "-i", nvram_safe_get("lan_ifname"), mac);
506 mac = p + 1;
509 common_redirect();
512 void asp_dns(int argc, char **argv)
514 char s[128];
515 int i;
516 const dns_list_t *dns;
518 dns = get_dns(); // static buffer
519 strcpy(s, "\ndns = [");
520 for (i = 0 ; i < dns->count; ++i) {
521 sprintf(s + strlen(s), "%s'%s'", i ? "," : "", inet_ntoa(dns->dns[i]));
523 strcat(s, "];\n");
524 web_puts(s);
527 void wo_resolve(char *url)
529 char *p;
530 char *ip;
531 struct hostent *he;
532 struct in_addr ia;
533 char comma;
534 char *js;
536 comma = ' ';
537 web_puts("\nresolve_data = [\n");
538 if ((p = webcgi_get("ip")) != NULL) {
539 while ((ip = strsep(&p, ",")) != NULL) {
540 ia.s_addr = inet_addr(ip);
541 he = gethostbyaddr(&ia, sizeof(ia), AF_INET);
542 js = js_string(he ? he->h_name : "");
543 web_printf("%c['%s','%s']", comma, inet_ntoa(ia), js);
544 free(js);
545 comma = ',';
548 web_puts("];\n");