4 Copyright (C) 2006-2009 Jonathan Zarate
11 #include <sys/sysinfo.h>
13 #include <sys/ioctl.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <sys/types.h>
22 #include <sys/statfs.h>
24 #include <net/route.h>
29 // to javascript-safe string
30 char *js_string(const char *s
)
36 if ((buffer
= malloc((strlen(s
) * 4) + 1)) != NULL
) {
38 while ((c
= *s
++) != 0) {
39 if ((c
== '"') || (c
== '\'') || (c
== '\\') || (!isprint(c
))) {
40 b
+= sprintf(b
, "\\x%02x", c
);
51 // to html-safe string
52 char *html_string(const char *s
)
58 if ((buffer
= malloc((strlen(s
) * 6) + 1)) != NULL
) {
60 while ((c
= *s
++) != 0) {
61 if ((c
== '&') || (c
== '<') || (c
== '>') || (c
== '"') || (c
== '\'') || (!isprint(c
))) {
62 b
+= sprintf(b
, "&#%d;", c
);
74 char *unix_string(const char *s
)
80 if ((buffer
= malloc(strlen(s
) + 1)) != NULL
) {
82 while ((c
= *s
++) != 0)
83 if (c
!= '\r') *b
++ = c
;
90 char *reltime(char *buf
, time_t t
)
98 sprintf(buf
, "%d day%s, %02d:%02d:%02d", days
, ((days
==1) ? "" : "s"), ((m
/ 60) % 24), (m
% 60), (int)(t
% 60));
102 int get_client_info(char *mac
, char *ifname
)
110 IP address HW type Flags HW address Mask Device
111 192.168.0.1 0x1 0x2 00:01:02:03:04:05 * vlan1
112 192.168.1.5 0x1 0x2 00:05:06:07:08:09 * br0
115 if ((f
= fopen("/proc/net/arp", "r")) != NULL
) {
116 while (fgets(s
, sizeof(s
), f
)) {
117 if (sscanf(s
, "%15s %*s %*s %17s %*s %16s", ips
, mac
, ifname
) == 3) {
118 if (inet_addr(ips
) == clientsai
.sin_addr
.s_addr
) {
133 // <% lanip(mode); %>
135 // 1 return first 3 octets (192.168.1)
136 // 2 return last octet (1)
137 // else return full (192.168.1.1)
139 void asp_lanip(int argc
, char **argv
)
145 mode
= argc
? *argv
[0] : 0;
147 if ((nv
= nvram_get("lan_ipaddr")) != NULL
) {
149 if ((p
= strrchr(s
, '.')) != NULL
) {
151 web_puts((mode
== '1') ? s
: (mode
== '2') ? (p
+ 1) : nv
);
156 void asp_lipp(int argc
, char **argv
)
162 // <% psup(process); %>
163 // returns 1 if process is running
165 void asp_psup(int argc
, char **argv
)
167 if (argc
== 1) web_printf("%d", pidof(argv
[0]) > 0);
170 void wo_vpn_status(char *url
)
172 #ifdef TCONFIG_OPENVPN
180 if ( str
= webcgi_get("server") )
182 else if ( str
= webcgi_get("client") )
185 num
= str
? atoi(str
): 0;
186 if ( type
&& num
> 0 )
188 // Trigger OpenVPN to update the status file
189 snprintf(&buf
[0], sizeof(buf
), "vpn%s%d", type
, num
);
190 killall(&buf
[0], SIGUSR2
);
192 // Give it a chance to update the file
195 // Read the status file and repeat it verbatim to the caller
196 snprintf(&buf
[0], sizeof(buf
), "/etc/openvpn/%s%d/status", type
, num
);
197 fp
= fopen(&buf
[0], "r");
200 while (fgets(&buf
[0], sizeof(buf
), fp
) != NULL
)
210 total: used: free: shared: buffers: cached:
211 Mem: 14872576 12877824 1994752 0 1236992 4837376
233 unsigned long shared
;
234 unsigned long buffers
;
235 unsigned long cached
;
236 unsigned long swaptotal
;
237 unsigned long swapfree
;
238 unsigned long maxfreeram
;
241 static int get_memory(meminfo_t
*m
)
247 if ((f
= fopen("/proc/meminfo", "r")) != NULL
) {
248 while (fgets(s
, sizeof(s
), f
)) {
249 if (strncmp(s
, "Mem:", 4) == 0) {
250 if (sscanf(s
+ 6, "%ld %*d %ld %ld %ld %ld", &m
->total
, &m
->free
, &m
->shared
, &m
->buffers
, &m
->cached
) == 5)
253 else if (strncmp(s
, "SwapTotal:", 10) == 0) {
254 m
->swaptotal
= strtoul(s
+ 12, NULL
, 10) * 1024;
257 else if (strncmp(s
, "SwapFree:", 9) == 0) {
258 m
->swapfree
= strtoul(s
+ 11, NULL
, 10) * 1024;
266 memset(m
, 0, sizeof(*m
));
269 m
->maxfreeram
= m
->free
;
270 if (nvram_match("t_cafree", "1")) m
->maxfreeram
+= m
->cached
;
274 void asp_sysinfo(int argc
, char **argv
)
280 web_puts("\nsysinfo = {\n");
285 "\tuptime_s: '%s',\n"
286 "\tloads: [%ld, %ld, %ld],\n"
290 "\tbufferram: %ld,\n"
292 "\ttotalswap: %ld,\n"
294 "\ttotalfreeram: %ld,\n"
297 reltime(s
, si
.uptime
),
298 si
.loads
[0], si
.loads
[1], si
.loads
[2],
300 mem
.shared
, mem
.buffers
, mem
.cached
,
301 mem
.swaptotal
, mem
.swapfree
,
307 void asp_activeroutes(int argc
, char **argv
)
313 unsigned long gateway
;
323 web_puts("\nactiveroutes = [");
325 if ((f
= fopen("/proc/net/route", "r")) != NULL
) {
326 while (fgets(s
, sizeof(s
), f
)) {
327 if (sscanf(s
, "%16s%lx%lx%lx%*s%*s%u%lx", dev
, &dest
, &gateway
, &flags
, &metric
, &mask
) != 6) continue;
328 if ((flags
& RTF_UP
) == 0) continue;
331 strcpy(s_dest
, inet_ntoa(ia
));
334 strcpy(s_dest
, "default");
338 strcpy(s_gateway
, inet_ntoa(ia
));
341 strcpy(s_gateway
, "*");
344 strcpy(s_mask
, inet_ntoa(ia
));
345 web_printf("%s['%s','%s','%s','%s',%u]", n
? "," : "", dev
, s_dest
, s_gateway
, s_mask
, metric
);
353 void asp_cgi_get(int argc
, char **argv
)
358 for (i
= 0; i
< argc
; ++i
) {
359 v
= webcgi_get(argv
[i
]);
364 void asp_time(int argc
, char **argv
)
371 web_puts("Not Available");
374 strftime(s
, sizeof(s
), "%a, %d %b %Y %H:%M:%S %z", localtime(&t
));
379 void asp_wanup(int argc
, char **argv
)
381 web_puts(check_wanup() ? "1" : "0");
384 void asp_wanstatus(int argc
, char **argv
)
388 if ((using_dhcpc()) && (f_exists("/var/lib/misc/dhcpc.renewing"))) {
391 else if (check_wanup()) {
394 else if (f_exists("/var/lib/misc/wan.connecting")) {
403 void asp_link_uptime(int argc
, char **argv
)
413 if (f_read("/var/lib/misc/wantime", &uptime
, sizeof(uptime
)) == sizeof(uptime
)) {
414 reltime(buf
, si
.uptime
- uptime
);
420 void asp_bandwidth(int argc
, char **argv
)
425 if ((nvram_match("rstats_enable", "1")) && (argc
== 1)) {
426 if (strcmp(argv
[0], "speed") == 0) {
428 name
= "/var/spool/rstats-speed.js";
432 name
= "/var/spool/rstats-history.js";
435 killall("rstats", sig
);
436 f_wait_exists(name
, 5);
442 void asp_rrule(int argc
, char **argv
)
447 i
= nvram_get_int("rruleN");
448 sprintf(s
, "rrule%d", i
);
449 web_puts("\nrrule = '");
450 web_putj(nvram_safe_get(s
));
451 web_printf("';\nrruleN = %d;\n", i
);
454 void asp_compmac(int argc
, char **argv
)
459 if (get_client_info(mac
, ifname
)) {
464 void asp_ident(int argc
, char **argv
)
466 web_puth(nvram_safe_get("router_name"));
469 void asp_statfs(int argc
, char **argv
)
473 if (argc
!= 2) return;
475 // used for /cifs/, /jffs/... if it returns squashfs type, assume it's not mounted
476 if ((statfs(argv
[0], &sf
) != 0) || (sf
.f_type
== 0x73717368))
477 memset(&sf
, 0, sizeof(sf
));
485 ((uint64_t)sf
.f_bsize
* sf
.f_blocks
),
486 ((uint64_t)sf
.f_bsize
* sf
.f_bfree
));
489 void asp_notice(int argc
, char **argv
)
494 if (argc
!= 1) return;
495 snprintf(s
, sizeof(s
), "/var/notice/%s", argv
[0]);
496 if (f_read_string(s
, buf
, sizeof(buf
)) <= 0) return;
500 void wo_wakeup(char *url
)
506 if ((mac
= webcgi_get("mac")) != NULL
) {
507 end
= mac
+ strlen(mac
);
509 while ((*mac
== ' ') || (*mac
== '\t') || (*mac
== '\r') || (*mac
== '\n')) ++mac
;
510 if (*mac
== 0) break;
513 while ((*p
!= 0) && (*p
!= ' ') && (*p
!= '\r') && (*p
!= '\n')) ++p
;
516 eval("ether-wake", "-i", nvram_safe_get("lan_ifname"), mac
);
523 void asp_dns(int argc
, char **argv
)
527 const dns_list_t
*dns
;
529 dns
= get_dns(); // static buffer
530 strcpy(s
, "\ndns = [");
531 for (i
= 0 ; i
< dns
->count
; ++i
) {
532 sprintf(s
+ strlen(s
), "%s'%s'", i
? "," : "", inet_ntoa(dns
->dns
[i
]));
538 void wo_resolve(char *url
)
548 web_puts("\nresolve_data = [\n");
549 if ((p
= webcgi_get("ip")) != NULL
) {
550 while ((ip
= strsep(&p
, ",")) != NULL
) {
551 ia
.s_addr
= inet_addr(ip
);
552 he
= gethostbyaddr(&ia
, sizeof(ia
), AF_INET
);
553 js
= js_string(he
? he
->h_name
: "");
554 web_printf("%c['%s','%s']", comma
, inet_ntoa(ia
), js
);